]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #90443 - camelid:rustdoc-subst, r=GuillaumeGomez
authorbors <bors@rust-lang.org>
Mon, 8 Nov 2021 21:37:59 +0000 (21:37 +0000)
committerbors <bors@rust-lang.org>
Mon, 8 Nov 2021 21:37:59 +0000 (21:37 +0000)
Merge `DocContext.{ty,lt,ct}_substs` into one map

It should be impossible to have more than one entry with a particular
key across the three maps, so they should be one map. In addition to
making it impossible for multiple entries to exist, this should improve
memory usage since now only one map is allocated on the stack and heap.

r? `@GuillaumeGomez`

1197 files changed:
Cargo.lock
RELEASES.md
compiler/rustc_ast/README.md
compiler/rustc_ast/src/ast.rs
compiler/rustc_ast/src/lib.rs
compiler/rustc_ast/src/mut_visit.rs
compiler/rustc_ast/src/util/parser.rs
compiler/rustc_ast/src/util/unicode.rs [new file with mode: 0644]
compiler/rustc_ast/src/visit.rs
compiler/rustc_ast_lowering/src/asm.rs
compiler/rustc_ast_lowering/src/item.rs
compiler/rustc_ast_passes/src/ast_validation.rs
compiler/rustc_ast_passes/src/feature_gate.rs
compiler/rustc_ast_pretty/src/pprust/state.rs
compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
compiler/rustc_borrowck/src/region_infer/mod.rs
compiler/rustc_borrowck/src/type_check/mod.rs
compiler/rustc_borrowck/src/universal_regions.rs
compiler/rustc_builtin_macros/src/asm.rs
compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
compiler/rustc_builtin_macros/src/deriving/mod.rs
compiler/rustc_builtin_macros/src/global_allocator.rs
compiler/rustc_builtin_macros/src/test.rs
compiler/rustc_builtin_macros/src/test_harness.rs
compiler/rustc_codegen_llvm/src/abi.rs
compiler/rustc_codegen_llvm/src/builder.rs
compiler/rustc_codegen_llvm/src/context.rs
compiler/rustc_codegen_llvm/src/lib.rs
compiler/rustc_codegen_llvm/src/llvm/ffi.rs
compiler/rustc_codegen_llvm/src/llvm_util.rs
compiler/rustc_codegen_ssa/src/back/link.rs
compiler/rustc_codegen_ssa/src/back/write.rs
compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
compiler/rustc_codegen_ssa/src/mir/block.rs
compiler/rustc_codegen_ssa/src/mir/mod.rs
compiler/rustc_codegen_ssa/src/mir/statement.rs
compiler/rustc_codegen_ssa/src/target_features.rs
compiler/rustc_codegen_ssa/src/traits/backend.rs
compiler/rustc_const_eval/src/const_eval/error.rs
compiler/rustc_const_eval/src/const_eval/fn_queries.rs
compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
compiler/rustc_const_eval/src/interpret/terminator.rs
compiler/rustc_const_eval/src/transform/check_consts/check.rs
compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
compiler/rustc_const_eval/src/transform/promote_consts.rs
compiler/rustc_data_structures/src/steal.rs
compiler/rustc_error_codes/src/error_codes.rs
compiler/rustc_error_codes/src/error_codes/E0786.md [new file with mode: 0644]
compiler/rustc_errors/src/emitter.rs
compiler/rustc_feature/src/accepted.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_hir/src/hir_id.rs
compiler/rustc_hir/src/lang_items.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_interface/src/passes.rs
compiler/rustc_interface/src/util.rs
compiler/rustc_lexer/src/unescape.rs
compiler/rustc_lint/src/builtin.rs
compiler/rustc_lint/src/context.rs
compiler/rustc_lint/src/hidden_unicode_codepoints.rs [new file with mode: 0644]
compiler/rustc_lint/src/internal.rs
compiler/rustc_lint/src/lib.rs
compiler/rustc_lint_defs/src/builtin.rs
compiler/rustc_lint_defs/src/lib.rs
compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
compiler/rustc_macros/src/hash_stable.rs
compiler/rustc_metadata/src/creader.rs
compiler/rustc_metadata/src/locator.rs
compiler/rustc_metadata/src/native_libs.rs
compiler/rustc_middle/src/mir/interpret/error.rs
compiler/rustc_middle/src/mir/mod.rs
compiler/rustc_middle/src/mir/spanview.rs
compiler/rustc_middle/src/ty/layout.rs
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_middle/src/ty/relate.rs
compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
compiler/rustc_mir_dataflow/src/impls/mod.rs
compiler/rustc_mir_dataflow/src/rustc_peek.rs
compiler/rustc_mir_transform/src/coverage/mod.rs
compiler/rustc_mir_transform/src/coverage/spans.rs
compiler/rustc_mir_transform/src/reveal_all.rs
compiler/rustc_mir_transform/src/unreachable_prop.rs
compiler/rustc_monomorphize/src/collector.rs
compiler/rustc_monomorphize/src/util.rs
compiler/rustc_parse/Cargo.toml
compiler/rustc_parse/src/lexer/mod.rs
compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
compiler/rustc_parse/src/parser/item.rs
compiler/rustc_passes/src/check_const.rs
compiler/rustc_query_system/src/query/plumbing.rs
compiler/rustc_resolve/src/build_reduced_graph.rs
compiler/rustc_resolve/src/diagnostics.rs
compiler/rustc_resolve/src/late.rs
compiler/rustc_resolve/src/late/diagnostics.rs
compiler/rustc_resolve/src/late/lifetimes.rs
compiler/rustc_resolve/src/lib.rs
compiler/rustc_save_analysis/src/dump_visitor.rs
compiler/rustc_session/src/config.rs
compiler/rustc_session/src/options.rs
compiler/rustc_span/src/lib.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_target/src/abi/call/mod.rs
compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs
compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs
compiler/rustc_target/src/spec/mod.rs
compiler/rustc_target/src/spec/x86_64_unknown_none.rs [new file with mode: 0644]
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/mod.rs
compiler/rustc_trait_selection/src/traits/project.rs
compiler/rustc_trait_selection/src/traits/select/confirmation.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
compiler/rustc_typeck/src/astconv/generics.rs
compiler/rustc_typeck/src/check/cast.rs
compiler/rustc_typeck/src/check/compare_method.rs
compiler/rustc_typeck/src/check/demand.rs
compiler/rustc_typeck/src/check/expr.rs
compiler/rustc_typeck/src/check/fallback.rs
compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
compiler/rustc_typeck/src/check/method/suggest.rs
compiler/rustc_typeck/src/check/op.rs
compiler/rustc_typeck/src/check/regionck.rs
compiler/rustc_typeck/src/check/upvar.rs
compiler/rustc_typeck/src/check/wfcheck.rs
compiler/rustc_typeck/src/collect/type_of.rs
compiler/rustc_typeck/src/lib.rs
compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
library/alloc/src/lib.rs
library/alloc/src/rc.rs
library/alloc/src/slice.rs
library/alloc/src/str.rs
library/core/src/lib.rs
library/core/src/num/mod.rs
library/core/src/num/uint_macros.rs
library/core/src/str/pattern.rs
library/proc_macro/src/lib.rs
library/std/Cargo.toml
library/std/src/net/ip.rs
library/std/src/os/raw/mod.rs
library/std/src/os/unix/net/addr.rs
library/std/src/sys/itron/thread.rs
library/std/src/sys/unix/thread.rs
library/std/src/sys/windows/thread_local_dtor.rs
library/std/src/sys/windows/thread_local_key.rs
library/std/src/thread/mod.rs
library/std/src/thread/tests.rs
library/test/src/formatters/junit.rs
src/bootstrap/bootstrap.py
src/bootstrap/builder.rs
src/bootstrap/compile.rs
src/bootstrap/doc.rs
src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
src/ci/docker/host-x86_64/dist-x86_64-linux/build-curl.sh
src/ci/docker/host-x86_64/dist-x86_64-linux/build-openssl.sh
src/ci/docker/host-x86_64/dist-x86_64-linux/download-openssl-curl.sh [new file with mode: 0755]
src/ci/docker/host-x86_64/shared/ISRG_Root_X1.crt [deleted file]
src/ci/docker/run.sh
src/ci/docker/scripts/freebsd-toolchain.sh
src/doc/rustc/src/SUMMARY.md
src/doc/rustc/src/platform-support.md
src/doc/rustc/src/platform-support/x86_64-unknown-none.md [new file with mode: 0644]
src/doc/rustdoc/src/SUMMARY.md
src/doc/rustdoc/src/how-to-read-rustdoc.md [new file with mode: 0644]
src/doc/rustdoc/src/unstable-features.md
src/doc/unstable-book/src/library-features/asm.md
src/doc/unstable-book/src/library-features/global-asm.md
src/librustdoc/clean/auto_trait.rs
src/librustdoc/clean/blanket_impl.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/types.rs
src/librustdoc/fold.rs
src/librustdoc/formats/cache.rs
src/librustdoc/html/format.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/render/context.rs
src/librustdoc/html/render/mod.rs
src/librustdoc/html/render/print_item.rs
src/librustdoc/html/render/span_map.rs
src/librustdoc/html/render/write_shared.rs
src/librustdoc/html/sources.rs
src/librustdoc/html/static/css/noscript.css
src/librustdoc/html/static/css/rustdoc.css
src/librustdoc/html/static/css/themes/ayu.css
src/librustdoc/html/static/css/themes/dark.css
src/librustdoc/html/static/css/themes/light.css
src/librustdoc/html/static/js/main.js
src/librustdoc/html/templates/page.html
src/librustdoc/json/conversions.rs
src/librustdoc/lib.rs
src/librustdoc/passes/bare_urls.rs
src/librustdoc/passes/calculate_doc_coverage.rs
src/librustdoc/passes/check_code_block_syntax.rs
src/librustdoc/passes/check_doc_test_visibility.rs
src/librustdoc/passes/collect_intra_doc_links.rs
src/librustdoc/passes/collect_trait_impls.rs
src/librustdoc/passes/html_tags.rs
src/librustdoc/scrape_examples.rs
src/librustdoc/visit.rs [new file with mode: 0644]
src/test/assembly/asm/aarch64-types.rs
src/test/assembly/asm/arm-types.rs
src/test/assembly/asm/bpf-types.rs
src/test/assembly/asm/global_asm.rs
src/test/assembly/asm/hexagon-types.rs
src/test/assembly/asm/mips-types.rs
src/test/assembly/asm/nvptx-types.rs
src/test/assembly/asm/powerpc-types.rs
src/test/assembly/asm/riscv-types.rs
src/test/assembly/asm/s390x-types.rs
src/test/assembly/asm/wasm-types.rs
src/test/assembly/asm/x86-types.rs
src/test/codegen-units/item-collection/implicit-panic-call.rs [new file with mode: 0644]
src/test/codegen/asm-powerpc-clobbers.rs
src/test/mir-opt/issue-78192.rs
src/test/run-make-fulldeps/invalid-library/Makefile
src/test/run-make-fulldeps/print-cfg/Makefile
src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile [new file with mode: 0644]
src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/examples/ex.rs [new file with mode: 0644]
src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/lib.rs [new file with mode: 0644]
src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/proc.rs [new file with mode: 0644]
src/test/run-make/invalid-so/Makefile [new file with mode: 0644]
src/test/run-make/invalid-so/bar.rs [new file with mode: 0644]
src/test/run-make/rustdoc-scrape-examples-invalid-expr/Makefile [new file with mode: 0644]
src/test/run-make/rustdoc-scrape-examples-invalid-expr/examples/ex.rs [new file with mode: 0644]
src/test/run-make/rustdoc-scrape-examples-invalid-expr/src/lib.rs [new file with mode: 0644]
src/test/run-make/rustdoc-scrape-examples-multiple/src/lib.rs
src/test/run-make/rustdoc-scrape-examples-ordering/examples/ex1.rs
src/test/run-make/rustdoc-scrape-examples-ordering/examples/ex2.rs
src/test/run-make/rustdoc-scrape-examples-ordering/src/lib.rs
src/test/rustdoc-gui/headings.goml
src/test/rustdoc-gui/javascript-disabled.goml [new file with mode: 0644]
src/test/rustdoc-gui/sidebar.goml
src/test/rustdoc/doc-auto-cfg.rs [new file with mode: 0644]
src/test/rustdoc/doc-cfg-hide.rs
src/test/rustdoc/doc-cfg-implicit.rs
src/test/rustdoc/feature-gate-doc_auto_cfg.rs [new file with mode: 0644]
src/test/ui/argument-passing.rs [deleted file]
src/test/ui/array-slice-vec/mut-vstore-expr.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/bad-reg.rs
src/test/ui/asm/aarch64/const.rs
src/test/ui/asm/aarch64/parse-error.rs
src/test/ui/asm/aarch64/sym.rs
src/test/ui/asm/aarch64/type-check-2.rs
src/test/ui/asm/aarch64/type-check-3.rs
src/test/ui/asm/aarch64/type-check-3.stderr
src/test/ui/asm/bad-template.rs
src/test/ui/asm/issue-89305.rs
src/test/ui/asm/issue-89305.stderr
src/test/ui/asm/naked-functions.rs
src/test/ui/asm/naked-functions.stderr
src/test/ui/asm/named-asm-labels.rs
src/test/ui/asm/type-check-1.rs
src/test/ui/asm/x86_64/bad-reg.rs
src/test/ui/asm/x86_64/const.rs
src/test/ui/asm/x86_64/parse-error.rs
src/test/ui/asm/x86_64/sym.rs
src/test/ui/asm/x86_64/type-check-2.rs
src/test/ui/asm/x86_64/type-check-3.rs
src/test/ui/associated-types/issue-22066.rs [new file with mode: 0644]
src/test/ui/associated-types/issue-22828.rs [new file with mode: 0644]
src/test/ui/associated-types/issue-28871.rs [new file with mode: 0644]
src/test/ui/associated-types/issue-47139-1.rs [new file with mode: 0644]
src/test/ui/associated-types/issue-54467.rs [new file with mode: 0644]
src/test/ui/async-await/issue-64130-non-send-future-diags.rs
src/test/ui/async-await/issue-64130-non-send-future-diags.stderr
src/test/ui/async-await/issue-71137.rs
src/test/ui/async-await/issue-71137.stderr
src/test/ui/async-await/issue-73541-1.rs [new file with mode: 0644]
src/test/ui/async-await/issue-73541-1.stderr [new file with mode: 0644]
src/test/ui/attributes/issue-40962.rs [new file with mode: 0644]
src/test/ui/attributes/unrestricted-attribute-tokens.rs [new file with mode: 0644]
src/test/ui/auxiliary/changing-crates-a1.rs [deleted file]
src/test/ui/auxiliary/changing-crates-a2.rs [deleted file]
src/test/ui/auxiliary/changing-crates-b.rs [deleted file]
src/test/ui/auxiliary/legacy-const-generics.rs [deleted file]
src/test/ui/auxiliary/lto-duplicate-symbols1.rs [deleted file]
src/test/ui/auxiliary/lto-duplicate-symbols2.rs [deleted file]
src/test/ui/auxiliary/lto-rustc-loads-linker-plugin.rs [deleted file]
src/test/ui/auxiliary/nested_item.rs [deleted file]
src/test/ui/bastion-of-the-turbofish.rs [deleted file]
src/test/ui/binop/structured-compare.rs [new file with mode: 0644]
src/test/ui/borrowck/issue-46095.rs [new file with mode: 0644]
src/test/ui/box/new-box.rs [new file with mode: 0644]
src/test/ui/c-variadic/issue-32201.rs [new file with mode: 0644]
src/test/ui/c-variadic/issue-32201.stderr [new file with mode: 0644]
src/test/ui/cast/supported-cast.rs [new file with mode: 0644]
src/test/ui/changing-crates.rs [deleted file]
src/test/ui/changing-crates.stderr [deleted file]
src/test/ui/closures/2229_closure_analysis/issue-90465.fixed [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/issue-90465.rs [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/issue-90465.stderr [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed
src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs
src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed
src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs
src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
src/test/ui/closures/issue-10398.rs [new file with mode: 0644]
src/test/ui/closures/issue-10398.stderr [new file with mode: 0644]
src/test/ui/closures/issue-42463.rs [new file with mode: 0644]
src/test/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr
src/test/ui/closures/print/closure-print-generic-verbose-2.stderr
src/test/ui/closures/print/closure-print-verbose.stderr
src/test/ui/coercion/auxiliary/issue-39823.rs [new file with mode: 0644]
src/test/ui/coercion/issue-14589.rs [new file with mode: 0644]
src/test/ui/coercion/issue-39823.rs [new file with mode: 0644]
src/test/ui/coercion/issue-73886.rs [new file with mode: 0644]
src/test/ui/coercion/issue-73886.stderr [new file with mode: 0644]
src/test/ui/compare-method/issue-90444.rs [new file with mode: 0644]
src/test/ui/compare-method/issue-90444.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/issue-34028.rs [new file with mode: 0644]
src/test/ui/const-generics/auxiliary/legacy-const-generics.rs [new file with mode: 0644]
src/test/ui/const-generics/legacy-const-generics-bad.rs [new file with mode: 0644]
src/test/ui/const-generics/legacy-const-generics-bad.stderr [new file with mode: 0644]
src/test/ui/const-generics/legacy-const-generics.rs [new file with mode: 0644]
src/test/ui/consts/inline_asm.rs
src/test/ui/consts/inline_asm.stderr
src/test/ui/consts/issue-13902.rs [new file with mode: 0644]
src/test/ui/consts/issue-17074.rs [new file with mode: 0644]
src/test/ui/consts/issue-18294.rs [new file with mode: 0644]
src/test/ui/consts/issue-18294.stderr [new file with mode: 0644]
src/test/ui/consts/issue-23968-const-not-overflow.rs [new file with mode: 0644]
src/test/ui/consts/issue-37550-1.rs [new file with mode: 0644]
src/test/ui/consts/issue-37550-1.stderr [new file with mode: 0644]
src/test/ui/consts/issue-37991.rs [new file with mode: 0644]
src/test/ui/consts/promote-not.rs
src/test/ui/consts/promote-not.stderr
src/test/ui/consts/qualif-indirect-mutation-fail.rs
src/test/ui/consts/qualif-indirect-mutation-fail.stderr
src/test/ui/consts/qualif-indirect-mutation-pass.rs
src/test/ui/crate-loading/auxiliary/libfoo.rlib [new file with mode: 0644]
src/test/ui/crate-loading/invalid-rlib.rs [new file with mode: 0644]
src/test/ui/crate-loading/invalid-rlib.stderr [new file with mode: 0644]
src/test/ui/deprecation/try-macro-suggestion.rs [new file with mode: 0644]
src/test/ui/deprecation/try-macro-suggestion.stderr [new file with mode: 0644]
src/test/ui/deriving/issue-19358.rs [new file with mode: 0644]
src/test/ui/deriving/issue-58319.rs [new file with mode: 0644]
src/test/ui/diverging-tuple-parts-39485.rs [deleted file]
src/test/ui/diverging-tuple-parts-39485.stderr [deleted file]
src/test/ui/drop/issue-35546.rs [new file with mode: 0644]
src/test/ui/drop/terminate-in-initializer.rs [new file with mode: 0644]
src/test/ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs [new file with mode: 0644]
src/test/ui/editions-crate-root-2015.rs [deleted file]
src/test/ui/editions-crate-root-2015.stderr [deleted file]
src/test/ui/editions/epoch-gate-feature.rs [new file with mode: 0644]
src/test/ui/enum-discriminant/issue-51582.rs [new file with mode: 0644]
src/test/ui/enum/issue-42747.rs [new file with mode: 0644]
src/test/ui/epoch-gate-feature.rs [deleted file]
src/test/ui/extern/extern-methods.rs
src/test/ui/extern/extern-thiscall.rs
src/test/ui/extern/extern-vectorcall.rs
src/test/ui/extern/issue-28324.mir.stderr [new file with mode: 0644]
src/test/ui/extern/issue-28324.rs [new file with mode: 0644]
src/test/ui/extern/issue-28324.thir.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-asm_const.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-asm_const.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-asm_experimental_arch.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-asm_experimental_arch.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-asm_sym.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-asm_sym.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.rs [deleted file]
src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr [deleted file]
src/test/ui/for-loop-while/issue-51345.rs [new file with mode: 0644]
src/test/ui/for-loop-while/long-while.rs [new file with mode: 0644]
src/test/ui/foreign/nil-decl-in-foreign.rs [new file with mode: 0644]
src/test/ui/generic-associated-types/collections-project-default.rs
src/test/ui/generic-associated-types/collections.rs
src/test/ui/generic-associated-types/generic-associated-type-bounds.rs
src/test/ui/generic-associated-types/issue-70303.rs
src/test/ui/generic-associated-types/issue-76535.rs
src/test/ui/generic-associated-types/issue-76535.stderr
src/test/ui/generic-associated-types/issue-79422.rs
src/test/ui/generic-associated-types/issue-79422.stderr
src/test/ui/generic-associated-types/issue-86787.rs
src/test/ui/generic-associated-types/issue-86787.stderr
src/test/ui/generic-associated-types/issue-88287.rs
src/test/ui/generic-associated-types/issue-88360.rs
src/test/ui/generic-associated-types/issue-88360.stderr
src/test/ui/generic-associated-types/issue-88459.rs [new file with mode: 0644]
src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
src/test/ui/generic-associated-types/self-outlives-lint.rs [new file with mode: 0644]
src/test/ui/generic-associated-types/self-outlives-lint.stderr [new file with mode: 0644]
src/test/ui/generic-associated-types/streaming_iterator.rs
src/test/ui/generic-associated-types/variance_constraints.rs
src/test/ui/generics/issue-1112.rs [new file with mode: 0644]
src/test/ui/generics/issue-333.rs [new file with mode: 0644]
src/test/ui/generics/issue-59508-1.rs [new file with mode: 0644]
src/test/ui/generics/issue-59508-1.stderr [new file with mode: 0644]
src/test/ui/generics/issue-59508.fixed [new file with mode: 0644]
src/test/ui/generics/issue-59508.rs [new file with mode: 0644]
src/test/ui/generics/issue-59508.stderr [new file with mode: 0644]
src/test/ui/hello2021.rs
src/test/ui/higher-rank-trait-bounds/issue-60283.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-60283.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.rs
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.stderr [deleted file]
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs [new file with mode: 0644]
src/test/ui/hrtb/issue-90177.rs [new file with mode: 0644]
src/test/ui/hygiene/lambda-var-hygiene.rs [new file with mode: 0644]
src/test/ui/impl-trait/issue-49579.rs [new file with mode: 0644]
src/test/ui/impl-trait/issue-49685.rs [new file with mode: 0644]
src/test/ui/impl-trait/issue-51185.rs [new file with mode: 0644]
src/test/ui/in-band-lifetimes.rs [deleted file]
src/test/ui/in-band-lifetimes/in-band-lifetimes.rs [new file with mode: 0644]
src/test/ui/inference/lub-glb-with-unbound-infer-var.rs [new file with mode: 0644]
src/test/ui/issues/auxiliary/issue-19163.rs [deleted file]
src/test/ui/issues/auxiliary/issue-39823.rs [deleted file]
src/test/ui/issues/auxiliary/xcrate-issue-43189-a.rs [deleted file]
src/test/ui/issues/auxiliary/xcrate-issue-43189-b.rs [deleted file]
src/test/ui/issues/auxiliary/xcrate-issue-46112-rexport-core.rs [deleted file]
src/test/ui/issues/auxiliary/xcrate-issue-61711-b.rs [deleted file]
src/test/ui/issues/issue-10398.rs [deleted file]
src/test/ui/issues/issue-10398.stderr [deleted file]
src/test/ui/issues/issue-1112.rs [deleted file]
src/test/ui/issues/issue-11577.rs [deleted file]
src/test/ui/issues/issue-11940.rs [deleted file]
src/test/ui/issues/issue-12796.rs [deleted file]
src/test/ui/issues/issue-12796.stderr [deleted file]
src/test/ui/issues/issue-13483.rs [deleted file]
src/test/ui/issues/issue-13483.stderr [deleted file]
src/test/ui/issues/issue-13902.rs [deleted file]
src/test/ui/issues/issue-14227.mir.stderr [deleted file]
src/test/ui/issues/issue-14227.rs [deleted file]
src/test/ui/issues/issue-14227.thir.stderr [deleted file]
src/test/ui/issues/issue-14456.rs [deleted file]
src/test/ui/issues/issue-14589.rs [deleted file]
src/test/ui/issues/issue-14837.rs [deleted file]
src/test/ui/issues/issue-15080.rs [deleted file]
src/test/ui/issues/issue-16098.rs [deleted file]
src/test/ui/issues/issue-16098.stderr [deleted file]
src/test/ui/issues/issue-16272.rs [deleted file]
src/test/ui/issues/issue-17074.rs [deleted file]
src/test/ui/issues/issue-18060.rs [deleted file]
src/test/ui/issues/issue-18294.rs [deleted file]
src/test/ui/issues/issue-18294.stderr [deleted file]
src/test/ui/issues/issue-18652.rs [deleted file]
src/test/ui/issues/issue-19163.rs [deleted file]
src/test/ui/issues/issue-19163.stderr [deleted file]
src/test/ui/issues/issue-19358.rs [deleted file]
src/test/ui/issues/issue-19660.rs [deleted file]
src/test/ui/issues/issue-19660.stderr [deleted file]
src/test/ui/issues/issue-20091.rs [deleted file]
src/test/ui/issues/issue-20616-4.rs [deleted file]
src/test/ui/issues/issue-20616-4.stderr [deleted file]
src/test/ui/issues/issue-20616-5.rs [deleted file]
src/test/ui/issues/issue-20616-5.stderr [deleted file]
src/test/ui/issues/issue-20616-6.rs [deleted file]
src/test/ui/issues/issue-20616-6.stderr [deleted file]
src/test/ui/issues/issue-20616-7.rs [deleted file]
src/test/ui/issues/issue-20616-7.stderr [deleted file]
src/test/ui/issues/issue-20823.rs [deleted file]
src/test/ui/issues/issue-21356.rs [deleted file]
src/test/ui/issues/issue-21356.stderr [deleted file]
src/test/ui/issues/issue-21475.rs [deleted file]
src/test/ui/issues/issue-21520.rs [deleted file]
src/test/ui/issues/issue-22066.rs [deleted file]
src/test/ui/issues/issue-22463.rs [deleted file]
src/test/ui/issues/issue-22828.rs [deleted file]
src/test/ui/issues/issue-23458.rs [deleted file]
src/test/ui/issues/issue-23458.stderr [deleted file]
src/test/ui/issues/issue-23716.rs [deleted file]
src/test/ui/issues/issue-23716.stderr [deleted file]
src/test/ui/issues/issue-23968-const-not-overflow.rs [deleted file]
src/test/ui/issues/issue-24010.rs [deleted file]
src/test/ui/issues/issue-24313.rs [deleted file]
src/test/ui/issues/issue-2444.rs [deleted file]
src/test/ui/issues/issue-26251.rs [deleted file]
src/test/ui/issues/issue-26448-1.rs [deleted file]
src/test/ui/issues/issue-26448-2.rs [deleted file]
src/test/ui/issues/issue-26448-3.rs [deleted file]
src/test/ui/issues/issue-26638.rs [deleted file]
src/test/ui/issues/issue-26638.stderr [deleted file]
src/test/ui/issues/issue-26996.rs [deleted file]
src/test/ui/issues/issue-2748-b.rs [deleted file]
src/test/ui/issues/issue-28324.mir.stderr [deleted file]
src/test/ui/issues/issue-28324.rs [deleted file]
src/test/ui/issues/issue-28324.thir.stderr [deleted file]
src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs [deleted file]
src/test/ui/issues/issue-28871.rs [deleted file]
src/test/ui/issues/issue-29084.rs [deleted file]
src/test/ui/issues/issue-29084.stderr [deleted file]
src/test/ui/issues/issue-3021-c.rs [deleted file]
src/test/ui/issues/issue-3021-c.stderr [deleted file]
src/test/ui/issues/issue-3021.rs [deleted file]
src/test/ui/issues/issue-3021.stderr [deleted file]
src/test/ui/issues/issue-30225.rs [deleted file]
src/test/ui/issues/issue-30225.stderr [deleted file]
src/test/ui/issues/issue-30355.rs [deleted file]
src/test/ui/issues/issue-30355.stderr [deleted file]
src/test/ui/issues/issue-31076.rs [deleted file]
src/test/ui/issues/issue-31076.stderr [deleted file]
src/test/ui/issues/issue-31804.rs [deleted file]
src/test/ui/issues/issue-31804.stderr [deleted file]
src/test/ui/issues/issue-31845.rs [deleted file]
src/test/ui/issues/issue-31845.stderr [deleted file]
src/test/ui/issues/issue-3211.rs [deleted file]
src/test/ui/issues/issue-32201.rs [deleted file]
src/test/ui/issues/issue-32201.stderr [deleted file]
src/test/ui/issues/issue-333.rs [deleted file]
src/test/ui/issues/issue-34028.rs [deleted file]
src/test/ui/issues/issue-34171.rs [deleted file]
src/test/ui/issues/issue-34255-1.rs [deleted file]
src/test/ui/issues/issue-34255-1.stderr [deleted file]
src/test/ui/issues/issue-35546.rs [deleted file]
src/test/ui/issues/issue-37175.rs [deleted file]
src/test/ui/issues/issue-37366.rs [deleted file]
src/test/ui/issues/issue-37550.rs [deleted file]
src/test/ui/issues/issue-37550.stderr [deleted file]
src/test/ui/issues/issue-37991.rs [deleted file]
src/test/ui/issues/issue-38604.rs [deleted file]
src/test/ui/issues/issue-38604.stderr [deleted file]
src/test/ui/issues/issue-39388.rs [deleted file]
src/test/ui/issues/issue-39388.stderr [deleted file]
src/test/ui/issues/issue-3973.rs [deleted file]
src/test/ui/issues/issue-3973.stderr [deleted file]
src/test/ui/issues/issue-39823.rs [deleted file]
src/test/ui/issues/issue-40770.rs [deleted file]
src/test/ui/issues/issue-40962.rs [deleted file]
src/test/ui/issues/issue-42463.rs [deleted file]
src/test/ui/issues/issue-42679.rs [deleted file]
src/test/ui/issues/issue-42747.rs [deleted file]
src/test/ui/issues/issue-43189.rs [deleted file]
src/test/ui/issues/issue-43189.stderr [deleted file]
src/test/ui/issues/issue-44005.rs [deleted file]
src/test/ui/issues/issue-44005.stderr [deleted file]
src/test/ui/issues/issue-4401.rs [deleted file]
src/test/ui/issues/issue-4448.rs [deleted file]
src/test/ui/issues/issue-45124.rs [deleted file]
src/test/ui/issues/issue-45152.rs [deleted file]
src/test/ui/issues/issue-46095.rs [deleted file]
src/test/ui/issues/issue-46112.rs [deleted file]
src/test/ui/issues/issue-46112.stderr [deleted file]
src/test/ui/issues/issue-47139-1.rs [deleted file]
src/test/ui/issues/issue-49040.rs [deleted file]
src/test/ui/issues/issue-49040.stderr [deleted file]
src/test/ui/issues/issue-49579.rs [deleted file]
src/test/ui/issues/issue-49685.rs [deleted file]
src/test/ui/issues/issue-50731.rs [deleted file]
src/test/ui/issues/issue-5099.rs [deleted file]
src/test/ui/issues/issue-5099.stderr [deleted file]
src/test/ui/issues/issue-50993.rs [deleted file]
src/test/ui/issues/issue-50993.stderr [deleted file]
src/test/ui/issues/issue-51185.rs [deleted file]
src/test/ui/issues/issue-51345.rs [deleted file]
src/test/ui/issues/issue-51582.rs [deleted file]
src/test/ui/issues/issue-53787-inline-assembler-macro.rs [deleted file]
src/test/ui/issues/issue-53787-inline-assembler-macro.stderr [deleted file]
src/test/ui/issues/issue-54467.rs [deleted file]
src/test/ui/issues/issue-56031.rs [deleted file]
src/test/ui/issues/issue-56031.stderr [deleted file]
src/test/ui/issues/issue-57410-1.rs [deleted file]
src/test/ui/issues/issue-57597.rs [deleted file]
src/test/ui/issues/issue-57597.stderr [deleted file]
src/test/ui/issues/issue-58319.rs [deleted file]
src/test/ui/issues/issue-59029-1.rs [deleted file]
src/test/ui/issues/issue-59029-1.stderr [deleted file]
src/test/ui/issues/issue-59508-1.rs [deleted file]
src/test/ui/issues/issue-59508-1.stderr [deleted file]
src/test/ui/issues/issue-59508.fixed [deleted file]
src/test/ui/issues/issue-59508.rs [deleted file]
src/test/ui/issues/issue-59508.stderr [deleted file]
src/test/ui/issues/issue-60283.rs [deleted file]
src/test/ui/issues/issue-60283.stderr [deleted file]
src/test/ui/issues/issue-60662.rs [deleted file]
src/test/ui/issues/issue-60662.stdout [deleted file]
src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs [deleted file]
src/test/ui/issues/issue-61882-2.rs [deleted file]
src/test/ui/issues/issue-61882-2.stderr [deleted file]
src/test/ui/issues/issue-61882.rs [deleted file]
src/test/ui/issues/issue-61882.stderr [deleted file]
src/test/ui/issues/issue-63364.rs [deleted file]
src/test/ui/issues/issue-63364.stderr [deleted file]
src/test/ui/issues/issue-6596-1.rs [deleted file]
src/test/ui/issues/issue-6596-1.stderr [deleted file]
src/test/ui/issues/issue-6804.rs [deleted file]
src/test/ui/issues/issue-6804.stderr [deleted file]
src/test/ui/issues/issue-72455.rs [deleted file]
src/test/ui/issues/issue-72574-2.rs [deleted file]
src/test/ui/issues/issue-72574-2.stderr [deleted file]
src/test/ui/issues/issue-73541-1.rs [deleted file]
src/test/ui/issues/issue-73541-1.stderr [deleted file]
src/test/ui/issues/issue-73886.rs [deleted file]
src/test/ui/issues/issue-73886.stderr [deleted file]
src/test/ui/issues/issue-74739.rs [deleted file]
src/test/ui/issues/issue-811.rs [deleted file]
src/test/ui/issues/issue-8351-1.rs [deleted file]
src/test/ui/issues/issue-8351-2.rs [deleted file]
src/test/ui/issues/issue-86865.rs [deleted file]
src/test/ui/issues/issue-86865.stderr [deleted file]
src/test/ui/issues/issue-8827.rs [deleted file]
src/test/ui/issues/issue-9396.rs [deleted file]
src/test/ui/iterators/into-iter-on-arrays-2021.rs
src/test/ui/lambda-var-hygiene.rs [deleted file]
src/test/ui/lang-items/issue-19660.rs [new file with mode: 0644]
src/test/ui/lang-items/issue-19660.stderr [new file with mode: 0644]
src/test/ui/lang-items/issue-31076.rs [new file with mode: 0644]
src/test/ui/lang-items/issue-31076.stderr [new file with mode: 0644]
src/test/ui/lang-items/required-lang-item.rs [new file with mode: 0644]
src/test/ui/lang-items/required-lang-item.stderr [new file with mode: 0644]
src/test/ui/legacy-const-generics-bad.rs [deleted file]
src/test/ui/legacy-const-generics-bad.stderr [deleted file]
src/test/ui/legacy-const-generics.rs [deleted file]
src/test/ui/lifetimes/issue-26638.rs [new file with mode: 0644]
src/test/ui/lifetimes/issue-26638.stderr [new file with mode: 0644]
src/test/ui/lifetimes/issue-90170-elision-mismatch.fixed [new file with mode: 0644]
src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr [new file with mode: 0644]
src/test/ui/lifetimes/issue-90170-elision-mismatch.rs [new file with mode: 0644]
src/test/ui/lifetimes/issue-90170-elision-mismatch.stderr [new file with mode: 0644]
src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr
src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr
src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr
src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr
src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr
src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.rs
src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs
src/test/ui/lint/force-warn/warn-by-default-lint-two-modules.rs
src/test/ui/lint/force-warn/warnings-lint-group.rs
src/test/ui/lint/force-warn/warnings-lint-group.stderr
src/test/ui/lint/issue-14837.rs [new file with mode: 0644]
src/test/ui/lint/issue-57410-1.rs [new file with mode: 0644]
src/test/ui/lint/issue-63364.rs [new file with mode: 0644]
src/test/ui/lint/issue-63364.stderr [new file with mode: 0644]
src/test/ui/lint/issue-90614-accept-allow-text-direction-codepoint-in-comment-lint.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/gated.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/gated.stderr [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/issue-89562.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/mutex.rs
src/test/ui/lint/must_not_suspend/mutex.stderr
src/test/ui/lint/must_not_suspend/warn.rs
src/test/ui/lint/must_not_suspend/warn.stderr
src/test/ui/lint/unnecessary-extern-crate.rs [new file with mode: 0644]
src/test/ui/lint/unnecessary-extern-crate.stderr [new file with mode: 0644]
src/test/ui/lint/unused_parens_json_suggestion.fixed
src/test/ui/lint/unused_parens_json_suggestion.rs
src/test/ui/lint/unused_parens_json_suggestion.stderr
src/test/ui/lint/unused_parens_remove_json_suggestion.fixed
src/test/ui/lint/unused_parens_remove_json_suggestion.rs
src/test/ui/lint/unused_parens_remove_json_suggestion.stderr
src/test/ui/lint/warn-ctypes-inhibit.rs [new file with mode: 0644]
src/test/ui/llvm-asm/issue-23458.rs [new file with mode: 0644]
src/test/ui/llvm-asm/issue-23458.stderr [new file with mode: 0644]
src/test/ui/llvm-asm/issue-37366.rs [new file with mode: 0644]
src/test/ui/llvm-asm/issue-53787-inline-assembler-macro.rs [new file with mode: 0644]
src/test/ui/llvm-asm/issue-53787-inline-assembler-macro.stderr [new file with mode: 0644]
src/test/ui/long-while.rs [deleted file]
src/test/ui/lto-and-no-bitcode-in-rlib.rs [deleted file]
src/test/ui/lto-and-no-bitcode-in-rlib.stderr [deleted file]
src/test/ui/lto-duplicate-symbols.rs [deleted file]
src/test/ui/lto-duplicate-symbols.stderr [deleted file]
src/test/ui/lto-many-codegen-units.rs [deleted file]
src/test/ui/lto-opt-level-s.rs [deleted file]
src/test/ui/lto-opt-level-z.rs [deleted file]
src/test/ui/lto-rustc-loads-linker-plugin.rs [deleted file]
src/test/ui/lto-still-runs-thread-dtors.rs [deleted file]
src/test/ui/lto-thin-rustc-loads-linker-plugin.rs [deleted file]
src/test/ui/lto/all-crates.rs [new file with mode: 0644]
src/test/ui/lto/auxiliary/dylib.rs [new file with mode: 0644]
src/test/ui/lto/auxiliary/lto-duplicate-symbols1.rs [new file with mode: 0644]
src/test/ui/lto/auxiliary/lto-duplicate-symbols2.rs [new file with mode: 0644]
src/test/ui/lto/auxiliary/lto-rustc-loads-linker-plugin.rs [new file with mode: 0644]
src/test/ui/lto/auxiliary/msvc-imp-present.rs [new file with mode: 0644]
src/test/ui/lto/auxiliary/thin-lto-inlines-aux.rs [new file with mode: 0644]
src/test/ui/lto/dylib-works.rs [new file with mode: 0644]
src/test/ui/lto/lto-and-no-bitcode-in-rlib.rs [new file with mode: 0644]
src/test/ui/lto/lto-and-no-bitcode-in-rlib.stderr [new file with mode: 0644]
src/test/ui/lto/lto-duplicate-symbols.rs [new file with mode: 0644]
src/test/ui/lto/lto-duplicate-symbols.stderr [new file with mode: 0644]
src/test/ui/lto/lto-many-codegen-units.rs [new file with mode: 0644]
src/test/ui/lto/lto-opt-level-s.rs [new file with mode: 0644]
src/test/ui/lto/lto-opt-level-z.rs [new file with mode: 0644]
src/test/ui/lto/lto-rustc-loads-linker-plugin.rs [new file with mode: 0644]
src/test/ui/lto/lto-still-runs-thread-dtors.rs [new file with mode: 0644]
src/test/ui/lto/lto-thin-rustc-loads-linker-plugin.rs [new file with mode: 0644]
src/test/ui/lto/msvc-imp-present.rs [new file with mode: 0644]
src/test/ui/lto/thin-lto-global-allocator.rs [new file with mode: 0644]
src/test/ui/lto/thin-lto-inlines.rs [new file with mode: 0644]
src/test/ui/lto/thin-lto-inlines2.rs [new file with mode: 0644]
src/test/ui/lto/weak-works.rs [new file with mode: 0644]
src/test/ui/lub-glb-with-unbound-infer-var.rs [deleted file]
src/test/ui/macros/auxiliary/issue-19163.rs [new file with mode: 0644]
src/test/ui/macros/issue-16098.rs [new file with mode: 0644]
src/test/ui/macros/issue-16098.stderr [new file with mode: 0644]
src/test/ui/macros/issue-19163.rs [new file with mode: 0644]
src/test/ui/macros/issue-19163.stderr [new file with mode: 0644]
src/test/ui/macros/issue-21356.rs [new file with mode: 0644]
src/test/ui/macros/issue-21356.stderr [new file with mode: 0644]
src/test/ui/macros/issue-22463.rs [new file with mode: 0644]
src/test/ui/macros/issue-29084.rs [new file with mode: 0644]
src/test/ui/macros/issue-29084.stderr [new file with mode: 0644]
src/test/ui/macros/issue-34171.rs [new file with mode: 0644]
src/test/ui/macros/issue-37175.rs [new file with mode: 0644]
src/test/ui/macros/issue-39388.rs [new file with mode: 0644]
src/test/ui/macros/issue-39388.stderr [new file with mode: 0644]
src/test/ui/macros/issue-40770.rs [new file with mode: 0644]
src/test/ui/macros/issue-57597.rs [new file with mode: 0644]
src/test/ui/macros/issue-57597.stderr [new file with mode: 0644]
src/test/ui/macros/issue-6596-1.rs [new file with mode: 0644]
src/test/ui/macros/issue-6596-1.stderr [new file with mode: 0644]
src/test/ui/macros/issue-86865.rs [new file with mode: 0644]
src/test/ui/macros/issue-86865.stderr [new file with mode: 0644]
src/test/ui/macros/trace_macros-format.rs [new file with mode: 0644]
src/test/ui/macros/trace_macros-format.stderr [new file with mode: 0644]
src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs [new file with mode: 0644]
src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr [new file with mode: 0644]
src/test/ui/marker_trait_attr/overlap-permitted-for-annotated-marker-traits.rs [new file with mode: 0644]
src/test/ui/match/issue-11940.rs [new file with mode: 0644]
src/test/ui/match/issue-18060.rs [new file with mode: 0644]
src/test/ui/match/issue-26251.rs [new file with mode: 0644]
src/test/ui/match/issue-26996.rs [new file with mode: 0644]
src/test/ui/match/issue-42679.rs [new file with mode: 0644]
src/test/ui/matches2021.rs
src/test/ui/mir-dataflow/indirect-mutation-offset.rs [deleted file]
src/test/ui/mir-dataflow/indirect-mutation-offset.stderr [deleted file]
src/test/ui/mir/issue-74739.rs [new file with mode: 0644]
src/test/ui/mut-vstore-expr.rs [deleted file]
src/test/ui/negative.rs [deleted file]
src/test/ui/nested_item_main.rs [deleted file]
src/test/ui/never_type/diverging-tuple-parts-39485.rs [new file with mode: 0644]
src/test/ui/never_type/diverging-tuple-parts-39485.stderr [new file with mode: 0644]
src/test/ui/new-box.rs [deleted file]
src/test/ui/nil-decl-in-foreign.rs [deleted file]
src/test/ui/numbers-arithmetic/unary-minus-suffix-inference.rs [new file with mode: 0644]
src/test/ui/object-does-not-impl-trait.rs [deleted file]
src/test/ui/object-does-not-impl-trait.stderr [deleted file]
src/test/ui/overlap-doesnt-conflict-with-specialization.rs [deleted file]
src/test/ui/overlap-doesnt-conflict-with-specialization.stderr [deleted file]
src/test/ui/overlap-permitted-for-annotated-marker-traits.rs [deleted file]
src/test/ui/packed/issue-46152.rs [new file with mode: 0644]
src/test/ui/parser/bastion-of-the-turbofish.rs [new file with mode: 0644]
src/test/ui/parser/issue-13483.rs [new file with mode: 0644]
src/test/ui/parser/issue-13483.stderr [new file with mode: 0644]
src/test/ui/parser/issue-20616-4.rs [new file with mode: 0644]
src/test/ui/parser/issue-20616-4.stderr [new file with mode: 0644]
src/test/ui/parser/issue-20616-5.rs [new file with mode: 0644]
src/test/ui/parser/issue-20616-5.stderr [new file with mode: 0644]
src/test/ui/parser/issue-20616-6.rs [new file with mode: 0644]
src/test/ui/parser/issue-20616-6.stderr [new file with mode: 0644]
src/test/ui/parser/issue-20616-7.rs [new file with mode: 0644]
src/test/ui/parser/issue-20616-7.stderr [new file with mode: 0644]
src/test/ui/parser/issue-21475.rs [new file with mode: 0644]
src/test/ui/parser/issue-31804.rs [new file with mode: 0644]
src/test/ui/parser/issue-31804.stderr [new file with mode: 0644]
src/test/ui/parser/issue-34255-1.rs [new file with mode: 0644]
src/test/ui/parser/issue-34255-1.stderr [new file with mode: 0644]
src/test/ui/parser/issue-49040.rs [new file with mode: 0644]
src/test/ui/parser/issue-49040.stderr [new file with mode: 0644]
src/test/ui/parser/issue-56031.rs [new file with mode: 0644]
src/test/ui/parser/issue-56031.stderr [new file with mode: 0644]
src/test/ui/parser/unicode-control-codepoints.rs [new file with mode: 0644]
src/test/ui/parser/unicode-control-codepoints.stderr [new file with mode: 0644]
src/test/ui/pattern/issue-11577.rs [new file with mode: 0644]
src/test/ui/pattern/issue-15080.rs [new file with mode: 0644]
src/test/ui/pattern/issue-72574-2.rs [new file with mode: 0644]
src/test/ui/pattern/issue-72574-2.stderr [new file with mode: 0644]
src/test/ui/pattern/issue-8351-1.rs [new file with mode: 0644]
src/test/ui/pattern/issue-8351-2.rs [new file with mode: 0644]
src/test/ui/privacy/pub-priv-dep/pub-priv1.rs
src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr
src/test/ui/proc-macro/auxiliary/api/parse.rs
src/test/ui/process/issue-14456.rs [new file with mode: 0644]
src/test/ui/process/issue-16272.rs [new file with mode: 0644]
src/test/ui/process/issue-20091.rs [new file with mode: 0644]
src/test/ui/process/signal-exit-status.rs [new file with mode: 0644]
src/test/ui/regions/issue-21520.rs [new file with mode: 0644]
src/test/ui/regions/issue-26448-1.rs [new file with mode: 0644]
src/test/ui/regions/issue-26448-2.rs [new file with mode: 0644]
src/test/ui/regions/issue-26448-3.rs [new file with mode: 0644]
src/test/ui/required-lang-item.rs [deleted file]
src/test/ui/required-lang-item.stderr [deleted file]
src/test/ui/resolve/editions-crate-root-2015.rs [new file with mode: 0644]
src/test/ui/resolve/editions-crate-root-2015.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-12796.rs [new file with mode: 0644]
src/test/ui/resolve/issue-12796.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-23716.rs [new file with mode: 0644]
src/test/ui/resolve/issue-23716.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-3021-c.rs [new file with mode: 0644]
src/test/ui/resolve/issue-3021-c.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-3021.rs [new file with mode: 0644]
src/test/ui/resolve/issue-3021.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-31845.rs [new file with mode: 0644]
src/test/ui/resolve/issue-31845.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-5099.rs [new file with mode: 0644]
src/test/ui/resolve/issue-5099.stderr [new file with mode: 0644]
src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.rs [new file with mode: 0644]
src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr [new file with mode: 0644]
src/test/ui/rust-2021/prelude2021.rs
src/test/ui/rust-2021/reserved-prefixes-migration.fixed
src/test/ui/rust-2021/reserved-prefixes-migration.rs
src/test/ui/self/issue-61882-2.rs [new file with mode: 0644]
src/test/ui/self/issue-61882-2.stderr [new file with mode: 0644]
src/test/ui/self/issue-61882.rs [new file with mode: 0644]
src/test/ui/self/issue-61882.stderr [new file with mode: 0644]
src/test/ui/signal-exit-status.rs [deleted file]
src/test/ui/specialization/transmute-specialization.rs [new file with mode: 0644]
src/test/ui/specialization/transmute-specialization.stderr [new file with mode: 0644]
src/test/ui/static/auxiliary/nested_item.rs [new file with mode: 0644]
src/test/ui/static/nested_item_main.rs [new file with mode: 0644]
src/test/ui/statics/issue-14227.mir.stderr [new file with mode: 0644]
src/test/ui/statics/issue-14227.rs [new file with mode: 0644]
src/test/ui/statics/issue-14227.thir.stderr [new file with mode: 0644]
src/test/ui/structs-enums/issue-50731.rs [new file with mode: 0644]
src/test/ui/structured-compare.rs [deleted file]
src/test/ui/suggestions/boxed-variant-field.rs [new file with mode: 0644]
src/test/ui/suggestions/boxed-variant-field.stderr [new file with mode: 0644]
src/test/ui/suggestions/undeclared-module-alloc.rs [new file with mode: 0644]
src/test/ui/suggestions/undeclared-module-alloc.stderr [new file with mode: 0644]
src/test/ui/supported-cast.rs [deleted file]
src/test/ui/svh/auxiliary/changing-crates-a1.rs [new file with mode: 0644]
src/test/ui/svh/auxiliary/changing-crates-a2.rs [new file with mode: 0644]
src/test/ui/svh/auxiliary/changing-crates-b.rs [new file with mode: 0644]
src/test/ui/svh/changing-crates.rs [new file with mode: 0644]
src/test/ui/svh/changing-crates.stderr [new file with mode: 0644]
src/test/ui/syntax-trait-polarity.rs [deleted file]
src/test/ui/syntax-trait-polarity.stderr [deleted file]
src/test/ui/terminate-in-initializer.rs [deleted file]
src/test/ui/terr-sorts.stderr
src/test/ui/test-attrs/issue-20823.rs [new file with mode: 0644]
src/test/ui/thin-lto-global-allocator.rs [deleted file]
src/test/ui/thinlto/all-crates.rs [deleted file]
src/test/ui/thinlto/auxiliary/dylib.rs [deleted file]
src/test/ui/thinlto/auxiliary/msvc-imp-present.rs [deleted file]
src/test/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs [deleted file]
src/test/ui/thinlto/dylib-works.rs [deleted file]
src/test/ui/thinlto/msvc-imp-present.rs [deleted file]
src/test/ui/thinlto/thin-lto-inlines.rs [deleted file]
src/test/ui/thinlto/thin-lto-inlines2.rs [deleted file]
src/test/ui/thinlto/weak-works.rs [deleted file]
src/test/ui/threads-sendsync/issue-24313.rs [new file with mode: 0644]
src/test/ui/threads-sendsync/issue-4448.rs [new file with mode: 0644]
src/test/ui/threads-sendsync/issue-8827.rs [new file with mode: 0644]
src/test/ui/threads-sendsync/issue-9396.rs [new file with mode: 0644]
src/test/ui/threads-sendsync/trivial-message.rs [new file with mode: 0644]
src/test/ui/threads-sendsync/yield2.rs [new file with mode: 0644]
src/test/ui/trace_macros-format.rs [deleted file]
src/test/ui/trace_macros-format.stderr [deleted file]
src/test/ui/traits/issue-24010.rs [new file with mode: 0644]
src/test/ui/traits/issue-38604.rs [new file with mode: 0644]
src/test/ui/traits/issue-38604.stderr [new file with mode: 0644]
src/test/ui/traits/issue-3973.rs [new file with mode: 0644]
src/test/ui/traits/issue-3973.stderr [new file with mode: 0644]
src/test/ui/traits/issue-59029-1.rs [new file with mode: 0644]
src/test/ui/traits/issue-59029-1.stderr [new file with mode: 0644]
src/test/ui/traits/issue-72455.rs [new file with mode: 0644]
src/test/ui/traits/object-does-not-impl-trait.rs [new file with mode: 0644]
src/test/ui/traits/object-does-not-impl-trait.stderr [new file with mode: 0644]
src/test/ui/traits/syntax-trait-polarity.rs [new file with mode: 0644]
src/test/ui/traits/syntax-trait-polarity.stderr [new file with mode: 0644]
src/test/ui/transmute-specialization.rs [deleted file]
src/test/ui/transmute-specialization.stderr [deleted file]
src/test/ui/trivial-message.rs [deleted file]
src/test/ui/try-block/issue-45124.rs [new file with mode: 0644]
src/test/ui/try-macro-suggestion.rs [deleted file]
src/test/ui/try-macro-suggestion.stderr [deleted file]
src/test/ui/type-alias-impl-trait/issue-60662.rs [new file with mode: 0644]
src/test/ui/type-alias-impl-trait/issue-60662.stdout [new file with mode: 0644]
src/test/ui/type-inference/issue-30225.rs [new file with mode: 0644]
src/test/ui/type-inference/issue-30225.stderr [new file with mode: 0644]
src/test/ui/typeck/auxiliary/xcrate-issue-43189-a.rs [new file with mode: 0644]
src/test/ui/typeck/auxiliary/xcrate-issue-43189-b.rs [new file with mode: 0644]
src/test/ui/typeck/auxiliary/xcrate-issue-46112-rexport-core.rs [new file with mode: 0644]
src/test/ui/typeck/auxiliary/xcrate-issue-61711-b.rs [new file with mode: 0644]
src/test/ui/typeck/issue-43189.rs [new file with mode: 0644]
src/test/ui/typeck/issue-43189.stderr [new file with mode: 0644]
src/test/ui/typeck/issue-46112.rs [new file with mode: 0644]
src/test/ui/typeck/issue-46112.stderr [new file with mode: 0644]
src/test/ui/typeck/issue-61711-once-caused-rustc-inf-loop.rs [new file with mode: 0644]
src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.rs [new file with mode: 0644]
src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.stderr [new file with mode: 0644]
src/test/ui/unary-minus-suffix-inference.rs [deleted file]
src/test/ui/unboxed-closures/issue-18652.rs [new file with mode: 0644]
src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.stderr
src/test/ui/unnecessary-extern-crate.rs [deleted file]
src/test/ui/unnecessary-extern-crate.stderr [deleted file]
src/test/ui/unrestricted-attribute-tokens.rs [deleted file]
src/test/ui/unsized/issue-30355.rs [new file with mode: 0644]
src/test/ui/unsized/issue-30355.stderr [new file with mode: 0644]
src/test/ui/unsized/unchanged-param.rs
src/test/ui/unused-crate-deps/extern-loc-missing-loc.rs
src/test/ui/warn-ctypes-inhibit.rs [deleted file]
src/test/ui/yield2.rs [deleted file]
src/tools/cargo
src/tools/clippy/.cargo/config [deleted file]
src/tools/clippy/.cargo/config.toml [new file with mode: 0644]
src/tools/clippy/.github/deploy.sh
src/tools/clippy/CHANGELOG.md
src/tools/clippy/CONTRIBUTING.md
src/tools/clippy/Cargo.toml
src/tools/clippy/clippy_dev/src/new_lint.rs
src/tools/clippy/clippy_lints/Cargo.toml
src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
src/tools/clippy/clippy_lints/src/casts/mod.rs
src/tools/clippy/clippy_lints/src/deprecated_lints.rs
src/tools/clippy/clippy_lints/src/dereference.rs
src/tools/clippy/clippy_lints/src/doc.rs
src/tools/clippy/clippy_lints/src/entry.rs
src/tools/clippy/clippy_lints/src/enum_variants.rs
src/tools/clippy/clippy_lints/src/eta_reduction.rs
src/tools/clippy/clippy_lints/src/excessive_bools.rs
src/tools/clippy/clippy_lints/src/format.rs
src/tools/clippy/clippy_lints/src/if_not_else.rs
src/tools/clippy/clippy_lints/src/if_then_panic.rs [deleted file]
src/tools/clippy/clippy_lints/src/int_plus_one.rs
src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs
src/tools/clippy/clippy_lints/src/lib.register_all.rs
src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
src/tools/clippy/clippy_lints/src/lib.register_lints.rs
src/tools/clippy/clippy_lints/src/lib.register_nursery.rs
src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs
src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
src/tools/clippy/clippy_lints/src/lib.register_style.rs
src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs
src/tools/clippy/clippy_lints/src/lib.rs
src/tools/clippy/clippy_lints/src/lifetimes.rs
src/tools/clippy/clippy_lints/src/loops/utils.rs
src/tools/clippy/clippy_lints/src/manual_assert.rs [new file with mode: 0644]
src/tools/clippy/clippy_lints/src/match_str_case_mismatch.rs
src/tools/clippy/clippy_lints/src/matches.rs
src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
src/tools/clippy/clippy_lints/src/misc_early/double_neg.rs
src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs [new file with mode: 0644]
src/tools/clippy/clippy_lints/src/misc_early/mod.rs
src/tools/clippy/clippy_lints/src/misc_early/unseparated_literal_suffix.rs [deleted file]
src/tools/clippy/clippy_lints/src/module_style.rs
src/tools/clippy/clippy_lints/src/needless_borrow.rs
src/tools/clippy/clippy_lints/src/non_expressive_names.rs
src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
src/tools/clippy/clippy_lints/src/option_if_let_else.rs
src/tools/clippy/clippy_lints/src/ptr.rs
src/tools/clippy/clippy_lints/src/question_mark.rs
src/tools/clippy/clippy_lints/src/strings.rs
src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
src/tools/clippy/clippy_lints/src/unicode.rs
src/tools/clippy/clippy_lints/src/unit_hash.rs [new file with mode: 0644]
src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
src/tools/clippy/clippy_lints/src/utils/conf.rs
src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
src/tools/clippy/clippy_lints/src/write.rs
src/tools/clippy/clippy_utils/src/ast_utils.rs
src/tools/clippy/clippy_utils/src/camel_case.rs [deleted file]
src/tools/clippy/clippy_utils/src/consts.rs
src/tools/clippy/clippy_utils/src/diagnostics.rs
src/tools/clippy/clippy_utils/src/higher.rs
src/tools/clippy/clippy_utils/src/lib.rs
src/tools/clippy/clippy_utils/src/str_utils.rs [new file with mode: 0644]
src/tools/clippy/doc/adding_lints.md
src/tools/clippy/rust-toolchain
src/tools/clippy/tests/compile-test.rs
src/tools/clippy/tests/missing-test-files.rs
src/tools/clippy/tests/ui-toml/functions_maxlines/test.rs
src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
src/tools/clippy/tests/ui/assertions_on_constants.rs
src/tools/clippy/tests/ui/assertions_on_constants.stderr
src/tools/clippy/tests/ui/async_yields_async.fixed
src/tools/clippy/tests/ui/async_yields_async.rs
src/tools/clippy/tests/ui/async_yields_async.stderr
src/tools/clippy/tests/ui/await_holding_lock.rs
src/tools/clippy/tests/ui/await_holding_lock.stderr
src/tools/clippy/tests/ui/await_holding_refcell_ref.rs
src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
src/tools/clippy/tests/ui/cast.rs
src/tools/clippy/tests/ui/cast.stderr
src/tools/clippy/tests/ui/crashes/auxiliary/ice-7868-aux.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/crashes/ice-3969.rs
src/tools/clippy/tests/ui/crashes/ice-3969.stderr
src/tools/clippy/tests/ui/crashes/ice-5207.rs
src/tools/clippy/tests/ui/crashes/ice-6252.rs
src/tools/clippy/tests/ui/crashes/ice-6252.stderr
src/tools/clippy/tests/ui/crashes/ice-7231.rs
src/tools/clippy/tests/ui/crashes/ice-7868.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/crashes/ice-7868.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/crashes/ice-7869.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/crashes/ice-7869.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs
src/tools/clippy/tests/ui/debug_assert_with_mut_call.rs
src/tools/clippy/tests/ui/deprecated.rs
src/tools/clippy/tests/ui/deprecated.stderr
src/tools/clippy/tests/ui/diverging_sub_expression.rs
src/tools/clippy/tests/ui/diverging_sub_expression.stderr
src/tools/clippy/tests/ui/doc/doc-fixable.fixed [new file with mode: 0644]
src/tools/clippy/tests/ui/doc/doc-fixable.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/doc/doc-fixable.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/doc/doc.rs [deleted file]
src/tools/clippy/tests/ui/doc/doc.stderr [deleted file]
src/tools/clippy/tests/ui/doc/issue_1832.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/doc/issue_902.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
src/tools/clippy/tests/ui/doc_errors.rs
src/tools/clippy/tests/ui/doc_errors.stderr
src/tools/clippy/tests/ui/doc_unsafe.rs
src/tools/clippy/tests/ui/enum_variants.stderr
src/tools/clippy/tests/ui/eval_order_dependence.rs
src/tools/clippy/tests/ui/eval_order_dependence.stderr
src/tools/clippy/tests/ui/fallible_impl_from.rs
src/tools/clippy/tests/ui/fallible_impl_from.stderr
src/tools/clippy/tests/ui/format.fixed
src/tools/clippy/tests/ui/format.rs
src/tools/clippy/tests/ui/format.stderr
src/tools/clippy/tests/ui/format_args.fixed
src/tools/clippy/tests/ui/format_args.rs
src/tools/clippy/tests/ui/format_args.stderr
src/tools/clippy/tests/ui/format_args_unfixable.rs
src/tools/clippy/tests/ui/future_not_send.rs
src/tools/clippy/tests/ui/future_not_send.stderr
src/tools/clippy/tests/ui/if_not_else.rs
src/tools/clippy/tests/ui/if_not_else.stderr
src/tools/clippy/tests/ui/if_then_panic.fixed [deleted file]
src/tools/clippy/tests/ui/if_then_panic.rs [deleted file]
src/tools/clippy/tests/ui/if_then_panic.stderr [deleted file]
src/tools/clippy/tests/ui/implicit_hasher.rs
src/tools/clippy/tests/ui/implicit_hasher.stderr
src/tools/clippy/tests/ui/implicit_return.fixed
src/tools/clippy/tests/ui/implicit_return.rs
src/tools/clippy/tests/ui/implicit_return.stderr
src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
src/tools/clippy/tests/ui/issue-7447.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/issue_4266.rs
src/tools/clippy/tests/ui/issue_4266.stderr
src/tools/clippy/tests/ui/len_without_is_empty.rs
src/tools/clippy/tests/ui/len_without_is_empty.stderr
src/tools/clippy/tests/ui/literals.rs
src/tools/clippy/tests/ui/literals.stderr
src/tools/clippy/tests/ui/macro_use_imports.fixed
src/tools/clippy/tests/ui/macro_use_imports.rs
src/tools/clippy/tests/ui/macro_use_imports.stderr
src/tools/clippy/tests/ui/manual_assert.edition2018.fixed [new file with mode: 0644]
src/tools/clippy/tests/ui/manual_assert.edition2018.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/manual_assert.edition2021.fixed [new file with mode: 0644]
src/tools/clippy/tests/ui/manual_assert.edition2021.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/manual_assert.fixed [new file with mode: 0644]
src/tools/clippy/tests/ui/manual_assert.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/manual_async_fn.fixed
src/tools/clippy/tests/ui/manual_async_fn.rs
src/tools/clippy/tests/ui/manual_async_fn.stderr
src/tools/clippy/tests/ui/manual_map_option.fixed
src/tools/clippy/tests/ui/manual_map_option.rs
src/tools/clippy/tests/ui/manual_map_option.stderr
src/tools/clippy/tests/ui/match_overlapping_arm.rs
src/tools/clippy/tests/ui/match_ref_pats.rs
src/tools/clippy/tests/ui/match_str_case_mismatch.rs
src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/match_wild_err_arm.rs
src/tools/clippy/tests/ui/match_wild_err_arm.stderr [deleted file]
src/tools/clippy/tests/ui/methods.rs
src/tools/clippy/tests/ui/methods.stderr
src/tools/clippy/tests/ui/missing-doc.rs
src/tools/clippy/tests/ui/missing-doc.stderr
src/tools/clippy/tests/ui/missing_panics_doc.rs
src/tools/clippy/tests/ui/missing_panics_doc.stderr
src/tools/clippy/tests/ui/needless_borrow_pat.rs
src/tools/clippy/tests/ui/needless_borrow_pat.stderr
src/tools/clippy/tests/ui/needless_lifetimes.rs
src/tools/clippy/tests/ui/needless_lifetimes.stderr
src/tools/clippy/tests/ui/needless_return.fixed
src/tools/clippy/tests/ui/needless_return.rs
src/tools/clippy/tests/ui/needless_return.stderr
src/tools/clippy/tests/ui/non_expressive_names.rs
src/tools/clippy/tests/ui/option_if_let_else.fixed
src/tools/clippy/tests/ui/option_if_let_else.rs
src/tools/clippy/tests/ui/option_if_let_else.stderr
src/tools/clippy/tests/ui/panic_in_result_fn.rs
src/tools/clippy/tests/ui/panic_in_result_fn.stderr
src/tools/clippy/tests/ui/ptr_arg.rs
src/tools/clippy/tests/ui/ptr_arg.stderr
src/tools/clippy/tests/ui/question_mark.fixed
src/tools/clippy/tests/ui/question_mark.rs
src/tools/clippy/tests/ui/question_mark.stderr
src/tools/clippy/tests/ui/redundant_clone.fixed
src/tools/clippy/tests/ui/redundant_clone.stderr
src/tools/clippy/tests/ui/ref_binding_to_reference.rs
src/tools/clippy/tests/ui/ref_binding_to_reference.stderr
src/tools/clippy/tests/ui/rename.fixed
src/tools/clippy/tests/ui/rename.rs
src/tools/clippy/tests/ui/rename.stderr
src/tools/clippy/tests/ui/should_impl_trait/corner_cases.rs
src/tools/clippy/tests/ui/should_impl_trait/method_list_1.rs
src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr
src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs
src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
src/tools/clippy/tests/ui/single_component_path_imports.fixed
src/tools/clippy/tests/ui/single_component_path_imports.rs
src/tools/clippy/tests/ui/single_component_path_imports.stderr
src/tools/clippy/tests/ui/single_component_path_imports_macro.fixed
src/tools/clippy/tests/ui/single_component_path_imports_macro.rs
src/tools/clippy/tests/ui/single_component_path_imports_macro.stderr
src/tools/clippy/tests/ui/single_component_path_imports_nested_first.rs
src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr
src/tools/clippy/tests/ui/single_component_path_imports_self_after.rs
src/tools/clippy/tests/ui/single_component_path_imports_self_before.rs
src/tools/clippy/tests/ui/string_slice.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/string_slice.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/unit_hash.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/unit_hash.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/unused_async.rs
src/tools/clippy/tests/ui/unused_async.stderr
src/tools/clippy/tests/ui/use_self.fixed
src/tools/clippy/tests/ui/use_self.rs
src/tools/clippy/tests/ui/use_self.stderr
src/tools/clippy/tests/ui/used_underscore_binding.rs
src/tools/clippy/tests/ui/used_underscore_binding.stderr
src/tools/clippy/tests/ui/wildcard_imports.fixed
src/tools/clippy/tests/ui/wildcard_imports.rs
src/tools/clippy/tests/ui/wildcard_imports.stderr
src/tools/clippy/tests/ui/wrong_self_convention.rs
src/tools/clippy/tests/ui/wrong_self_convention.stderr
src/tools/clippy/tests/ui/wrong_self_convention2.rs
src/tools/clippy/tests/ui/wrong_self_convention2.stderr
src/tools/clippy/tests/ui/wrong_self_conventions_mut.rs
src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr
src/tools/compiletest/src/header.rs
src/tools/compiletest/src/header/tests.rs
src/tools/compiletest/src/runtest.rs
src/tools/compiletest/src/util.rs
src/tools/rust-analyzer
src/tools/rustdoc-js/tester.js
src/tools/rustfmt/.github/workflows/rustdoc_check.yml [new file with mode: 0644]
src/tools/rustfmt/Configurations.md
src/tools/rustfmt/Contributing.md
src/tools/rustfmt/README.md
src/tools/rustfmt/appveyor.yml [deleted file]
src/tools/rustfmt/intellij.md
src/tools/rustfmt/legacy-rustfmt.toml [deleted file]
src/tools/rustfmt/rust-toolchain
src/tools/rustfmt/src/attr.rs
src/tools/rustfmt/src/attr/doc_comment.rs
src/tools/rustfmt/src/bin/main.rs
src/tools/rustfmt/src/cargo-fmt/main.rs
src/tools/rustfmt/src/chains.rs
src/tools/rustfmt/src/comment.rs
src/tools/rustfmt/src/config/options.rs
src/tools/rustfmt/src/emitter/checkstyle.rs
src/tools/rustfmt/src/emitter/diff.rs
src/tools/rustfmt/src/expr.rs
src/tools/rustfmt/src/format-diff/main.rs
src/tools/rustfmt/src/formatting.rs
src/tools/rustfmt/src/git-rustfmt/main.rs
src/tools/rustfmt/src/imports.rs
src/tools/rustfmt/src/items.rs
src/tools/rustfmt/src/lib.rs
src/tools/rustfmt/src/lists.rs
src/tools/rustfmt/src/macros.rs
src/tools/rustfmt/src/matches.rs
src/tools/rustfmt/src/modules.rs
src/tools/rustfmt/src/overflow.rs
src/tools/rustfmt/src/pairs.rs
src/tools/rustfmt/src/patterns.rs
src/tools/rustfmt/src/reorder.rs
src/tools/rustfmt/src/syntux/parser.rs
src/tools/rustfmt/src/syntux/session.rs
src/tools/rustfmt/src/test/mod.rs
src/tools/rustfmt/src/test/mod_resolver.rs
src/tools/rustfmt/src/types.rs
src/tools/rustfmt/src/utils.rs
src/tools/rustfmt/src/visitor.rs
src/tools/rustfmt/tests/mod-resolver/issue-5063/foo.rs [new file with mode: 0644]
src/tools/rustfmt/tests/mod-resolver/issue-5063/foo/bar/baz.rs [new file with mode: 0644]
src/tools/rustfmt/tests/mod-resolver/issue-5063/main.rs [new file with mode: 0644]
src/tools/rustfmt/tests/source/configs/group_imports/One-merge_imports.rs [new file with mode: 0644]
src/tools/rustfmt/tests/source/configs/group_imports/One-nested.rs [new file with mode: 0644]
src/tools/rustfmt/tests/source/configs/group_imports/One-no_reorder.rs [new file with mode: 0644]
src/tools/rustfmt/tests/source/configs/group_imports/One.rs [new file with mode: 0644]
src/tools/rustfmt/tests/source/empty-item-single-line-false.rs [new file with mode: 0644]
src/tools/rustfmt/tests/source/item-brace-style-always-next-line.rs
src/tools/rustfmt/tests/target/configs/group_imports/One-merge_imports.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/configs/group_imports/One-nested.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/configs/group_imports/One-no_reorder.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/configs/group_imports/One.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/empty-item-single-line-false.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/issue-5012/trailing_comma_always.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/issue-5012/trailing_comma_never.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/issue-5033/minimum_example.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/issue-5033/nested_modules.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/issue_4850.rs [new file with mode: 0644]
src/tools/rustfmt/tests/target/item-brace-style-always-next-line.rs
src/tools/tidy/src/features.rs
src/tools/tidy/src/ui_tests.rs
triagebot.toml

index 59885472ae9c48d582bfd1ac2e5329d6bfae71bc..6f95dae42a4ab1a9edd126739aacfde5914fdcb8 100644 (file)
@@ -576,7 +576,7 @@ dependencies = [
 name = "clippy"
 version = "0.1.58"
 dependencies = [
- "cargo_metadata 0.12.0",
+ "cargo_metadata 0.14.0",
  "clippy_lints",
  "clippy_utils",
  "compiletest_rs",
@@ -588,7 +588,7 @@ dependencies = [
  "regex",
  "rustc-workspace-hack",
  "rustc_tools_util 0.2.0",
- "semver 0.11.0",
+ "semver 1.0.3",
  "serde",
  "syn",
  "tempfile",
@@ -613,7 +613,7 @@ dependencies = [
 name = "clippy_lints"
 version = "0.1.58"
 dependencies = [
- "cargo_metadata 0.12.0",
+ "cargo_metadata 0.14.0",
  "clippy_utils",
  "if_chain",
  "itertools 0.10.1",
@@ -621,7 +621,7 @@ dependencies = [
  "quine-mc_cluskey",
  "regex-syntax",
  "rustc-semver",
- "semver 0.11.0",
+ "semver 1.0.3",
  "serde",
  "serde_json",
  "toml",
@@ -710,9 +710,9 @@ dependencies = [
 
 [[package]]
 name = "compiletest_rs"
-version = "0.7.0"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64698e5e2435db061a85e6320af12c30c5fd88eb84b35d2c1e03ce4f143255ca"
+checksum = "29843cb8d351febf86557681d049d1e1652b81a086a190fa1173c07fd17fbf83"
 dependencies = [
  "diff",
  "filetime",
@@ -1900,9 +1900,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.103"
+version = "0.2.106"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
+checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -4259,6 +4259,7 @@ dependencies = [
  "rustc_span",
  "tracing",
  "unicode-normalization",
+ "unicode-width",
 ]
 
 [[package]]
index f1584224656ae0f29e95184455ab424d32dd0ed6..a38ab7cabf468c39aace386fb49321579be2dc22 100644 (file)
@@ -1,3 +1,11 @@
+Version 1.56.1 (2021-11-01)
+===========================
+
+- New lints to detect the presence of bidirectional-override Unicode
+  codepoints in the compiled source code ([CVE-2021-42574])
+
+[CVE-2021-42574]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42574
+
 Version 1.56.0 (2021-10-21)
 ========================
 
index dd407dba1f4cca03b3e19bce687b40e49a3ead68..b2b90fed033b3f1192fc3e75f065a957d14b72e6 100644 (file)
@@ -1,6 +1,5 @@
 The `rustc_ast` crate contains those things concerned purely with syntax
-– that is, the AST ("abstract syntax tree"), parser, pretty-printer,
-lexer, macro expander, and utilities for traversing ASTs.
+– that is, the AST ("abstract syntax tree"), along with some definitions for tokens and token streams, data structures/traits for mutating ASTs, and shared definitions for other AST-related parts of the compiler (like the lexer and macro-expansion).
 
 For more information about how these things work in rustc, see the
 rustc dev guide:
index e2424e7d7ad9064f38563795d6ce59f54cba963f..f9e19d30fcc7e5456ca3ab086d145ed1ab6d3fe0 100644 (file)
@@ -2645,34 +2645,42 @@ fn default() -> FnHeader {
 }
 
 #[derive(Clone, Encodable, Decodable, Debug)]
-pub struct TraitKind(
-    pub IsAuto,
-    pub Unsafe,
-    pub Generics,
-    pub GenericBounds,
-    pub Vec<P<AssocItem>>,
-);
+pub struct Trait {
+    pub unsafety: Unsafe,
+    pub is_auto: IsAuto,
+    pub generics: Generics,
+    pub bounds: GenericBounds,
+    pub items: Vec<P<AssocItem>>,
+}
 
 #[derive(Clone, Encodable, Decodable, Debug)]
-pub struct TyAliasKind(pub Defaultness, pub Generics, pub GenericBounds, pub Option<P<Ty>>);
+pub struct TyAlias {
+    pub defaultness: Defaultness,
+    pub generics: Generics,
+    pub bounds: GenericBounds,
+    pub ty: Option<P<Ty>>,
+}
 
 #[derive(Clone, Encodable, Decodable, Debug)]
-pub struct ImplKind {
-    pub unsafety: Unsafe,
-    pub polarity: ImplPolarity,
+pub struct Impl {
     pub defaultness: Defaultness,
-    pub constness: Const,
+    pub unsafety: Unsafe,
     pub generics: Generics,
-
+    pub constness: Const,
+    pub polarity: ImplPolarity,
     /// The trait being implemented, if any.
     pub of_trait: Option<TraitRef>,
-
     pub self_ty: P<Ty>,
     pub items: Vec<P<AssocItem>>,
 }
 
 #[derive(Clone, Encodable, Decodable, Debug)]
-pub struct FnKind(pub Defaultness, pub FnSig, pub Generics, pub Option<P<Block>>);
+pub struct Fn {
+    pub defaultness: Defaultness,
+    pub generics: Generics,
+    pub sig: FnSig,
+    pub body: Option<P<Block>>,
+}
 
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum ItemKind {
@@ -2695,7 +2703,7 @@ pub enum ItemKind {
     /// A function declaration (`fn`).
     ///
     /// E.g., `fn foo(bar: usize) -> usize { .. }`.
-    Fn(Box<FnKind>),
+    Fn(Box<Fn>),
     /// A module declaration (`mod`).
     ///
     /// E.g., `mod foo;` or `mod foo { .. }`.
@@ -2711,7 +2719,7 @@ pub enum ItemKind {
     /// A type alias (`type`).
     ///
     /// E.g., `type Foo = Bar<u8>;`.
-    TyAlias(Box<TyAliasKind>),
+    TyAlias(Box<TyAlias>),
     /// An enum definition (`enum`).
     ///
     /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
@@ -2727,7 +2735,7 @@ pub enum ItemKind {
     /// A trait declaration (`trait`).
     ///
     /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
-    Trait(Box<TraitKind>),
+    Trait(Box<Trait>),
     /// Trait alias
     ///
     /// E.g., `trait Foo = Bar + Quux;`.
@@ -2735,7 +2743,7 @@ pub enum ItemKind {
     /// An implementation.
     ///
     /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
-    Impl(Box<ImplKind>),
+    Impl(Box<Impl>),
     /// A macro invocation.
     ///
     /// E.g., `foo!(..)`.
@@ -2782,14 +2790,14 @@ pub fn descr(&self) -> &str {
 
     pub fn generics(&self) -> Option<&Generics> {
         match self {
-            Self::Fn(box FnKind(_, _, generics, _))
-            | Self::TyAlias(box TyAliasKind(_, generics, ..))
+            Self::Fn(box Fn { generics, .. })
+            | Self::TyAlias(box TyAlias { generics, .. })
             | Self::Enum(_, generics)
             | Self::Struct(_, generics)
             | Self::Union(_, generics)
-            | Self::Trait(box TraitKind(_, _, generics, ..))
+            | Self::Trait(box Trait { generics, .. })
             | Self::TraitAlias(generics, _)
-            | Self::Impl(box ImplKind { generics, .. }) => Some(generics),
+            | Self::Impl(box Impl { generics, .. }) => Some(generics),
             _ => None,
         }
     }
@@ -2812,9 +2820,9 @@ pub enum AssocItemKind {
     /// If `def` is parsed, then the constant is provided, and otherwise required.
     Const(Defaultness, P<Ty>, Option<P<Expr>>),
     /// An associated function.
-    Fn(Box<FnKind>),
+    Fn(Box<Fn>),
     /// An associated type.
-    TyAlias(Box<TyAliasKind>),
+    TyAlias(Box<TyAlias>),
     /// A macro expanding to associated items.
     MacCall(MacCall),
 }
@@ -2825,9 +2833,9 @@ pub enum AssocItemKind {
 impl AssocItemKind {
     pub fn defaultness(&self) -> Defaultness {
         match *self {
-            Self::Const(def, ..)
-            | Self::Fn(box FnKind(def, ..))
-            | Self::TyAlias(box TyAliasKind(def, ..)) => def,
+            Self::Const(defaultness, ..)
+            | Self::Fn(box Fn { defaultness, .. })
+            | Self::TyAlias(box TyAlias { defaultness, .. }) => defaultness,
             Self::MacCall(..) => Defaultness::Final,
         }
     }
@@ -2864,9 +2872,9 @@ pub enum ForeignItemKind {
     /// A foreign static item (`static FOO: u8`).
     Static(P<Ty>, Mutability, Option<P<Expr>>),
     /// An foreign function.
-    Fn(Box<FnKind>),
+    Fn(Box<Fn>),
     /// An foreign type.
-    TyAlias(Box<TyAliasKind>),
+    TyAlias(Box<TyAlias>),
     /// A macro expanding to foreign items.
     MacCall(MacCall),
 }
index e3c610585d978e32c8ef8071aa0ffda993431310..b9db2a7e089de1416d8667ffce0eb08322b50969 100644 (file)
@@ -1,4 +1,4 @@
-//! The Rust parser and macro expander.
+//! The Rust Abstract Syntax Tree (AST).
 //!
 //! # Note
 //!
@@ -16,6 +16,7 @@
 #![feature(nll)]
 #![feature(min_specialization)]
 #![recursion_limit = "256"]
+#![feature(slice_internals)]
 
 #[macro_use]
 extern crate rustc_macros;
@@ -25,6 +26,7 @@ pub mod util {
     pub mod comments;
     pub mod literal;
     pub mod parser;
+    pub mod unicode;
 }
 
 pub mod ast;
index 74def2bab1bfa2a58319e728f6765a2c9dc0f081..fc5cc963992579b76514eeddb92d9fb0a851b3b3 100644 (file)
@@ -459,7 +459,8 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
             vis.visit_mt(mt);
         }
         TyKind::BareFn(bft) => {
-            let BareFnTy { unsafety: _, ext: _, generic_params, decl } = bft.deref_mut();
+            let BareFnTy { unsafety, ext: _, generic_params, decl } = bft.deref_mut();
+            visit_unsafety(unsafety, vis);
             generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
             vis.visit_fn_decl(decl);
         }
@@ -488,7 +489,8 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
 }
 
 pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis: &mut T) {
-    let ForeignMod { unsafety: _, abi: _, items } = foreign_mod;
+    let ForeignMod { unsafety, abi: _, items } = foreign_mod;
+    visit_unsafety(unsafety, vis);
     items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
 }
 
@@ -788,6 +790,38 @@ pub fn visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut
     }
 }
 
+// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
+pub fn visit_defaultness<T: MutVisitor>(defaultness: &mut Defaultness, vis: &mut T) {
+    match defaultness {
+        Defaultness::Default(span) => vis.visit_span(span),
+        Defaultness::Final => {}
+    }
+}
+
+// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
+pub fn visit_unsafety<T: MutVisitor>(unsafety: &mut Unsafe, vis: &mut T) {
+    match unsafety {
+        Unsafe::Yes(span) => vis.visit_span(span),
+        Unsafe::No => {}
+    }
+}
+
+// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
+pub fn visit_polarity<T: MutVisitor>(polarity: &mut ImplPolarity, vis: &mut T) {
+    match polarity {
+        ImplPolarity::Positive => {}
+        ImplPolarity::Negative(span) => vis.visit_span(span),
+    }
+}
+
+// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
+pub fn visit_constness<T: MutVisitor>(constness: &mut Const, vis: &mut T) {
+    match constness {
+        Const::Yes(span) => vis.visit_span(span),
+        Const::No => {}
+    }
+}
+
 pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut Async, vis: &mut T) {
     match asyncness {
         Async::Yes { span: _, closure_id, return_impl_trait_id } => {
@@ -955,25 +989,35 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
     match kind {
         ItemKind::ExternCrate(_orig_name) => {}
         ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
-        ItemKind::Static(ty, _, expr) | ItemKind::Const(_, ty, expr) => {
+        ItemKind::Static(ty, _, expr) => {
             vis.visit_ty(ty);
             visit_opt(expr, |expr| vis.visit_expr(expr));
         }
-        ItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+        ItemKind::Const(defaultness, ty, expr) => {
+            visit_defaultness(defaultness, vis);
+            vis.visit_ty(ty);
+            visit_opt(expr, |expr| vis.visit_expr(expr));
+        }
+        ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
+            visit_defaultness(defaultness, vis);
             visit_fn_sig(sig, vis);
             vis.visit_generics(generics);
             visit_opt(body, |body| vis.visit_block(body));
         }
-        ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
-            ModKind::Loaded(items, _inline, inner_span) => {
-                vis.visit_span(inner_span);
-                items.flat_map_in_place(|item| vis.flat_map_item(item));
+        ItemKind::Mod(unsafety, mod_kind) => {
+            visit_unsafety(unsafety, vis);
+            match mod_kind {
+                ModKind::Loaded(items, _inline, inner_span) => {
+                    vis.visit_span(inner_span);
+                    items.flat_map_in_place(|item| vis.flat_map_item(item));
+                }
+                ModKind::Unloaded => {}
             }
-            ModKind::Unloaded => {}
-        },
+        }
         ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
         ItemKind::GlobalAsm(asm) => noop_visit_inline_asm(asm, vis),
-        ItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+        ItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
+            visit_defaultness(defaultness, vis);
             vis.visit_generics(generics);
             visit_bounds(bounds, vis);
             visit_opt(ty, |ty| vis.visit_ty(ty));
@@ -986,22 +1030,27 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
             vis.visit_variant_data(variant_data);
             vis.visit_generics(generics);
         }
-        ItemKind::Impl(box ImplKind {
-            unsafety: _,
-            polarity: _,
-            defaultness: _,
-            constness: _,
+        ItemKind::Impl(box Impl {
+            defaultness,
+            unsafety,
             generics,
+            constness,
+            polarity,
             of_trait,
             self_ty,
             items,
         }) => {
+            visit_defaultness(defaultness, vis);
+            visit_unsafety(unsafety, vis);
             vis.visit_generics(generics);
+            visit_constness(constness, vis);
+            visit_polarity(polarity, vis);
             visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
             vis.visit_ty(self_ty);
             items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
         }
-        ItemKind::Trait(box TraitKind(.., generics, bounds, items)) => {
+        ItemKind::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }) => {
+            visit_unsafety(unsafety, vis);
             vis.visit_generics(generics);
             visit_bounds(bounds, vis);
             items.flat_map_in_place(|item| vis.flat_map_trait_item(item));
@@ -1025,16 +1074,19 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
     visitor.visit_vis(vis);
     visit_attrs(attrs, visitor);
     match kind {
-        AssocItemKind::Const(_, ty, expr) => {
+        AssocItemKind::Const(defaultness, ty, expr) => {
+            visit_defaultness(defaultness, visitor);
             visitor.visit_ty(ty);
             visit_opt(expr, |expr| visitor.visit_expr(expr));
         }
-        AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+        AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
+            visit_defaultness(defaultness, visitor);
             visitor.visit_generics(generics);
             visit_fn_sig(sig, visitor);
             visit_opt(body, |body| visitor.visit_block(body));
         }
-        AssocItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+        AssocItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
+            visit_defaultness(defaultness, visitor);
             visitor.visit_generics(generics);
             visit_bounds(bounds, visitor);
             visit_opt(ty, |ty| visitor.visit_ty(ty));
@@ -1047,8 +1099,10 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
 }
 
 pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
-    let FnHeader { unsafety: _, asyncness, constness: _, ext: _ } = header;
+    let FnHeader { unsafety, asyncness, constness, ext: _ } = header;
+    visit_constness(constness, vis);
     vis.visit_asyncness(asyncness);
+    visit_unsafety(unsafety, vis);
 }
 
 // FIXME: Avoid visiting the crate as a `Mod` item, flat map only the inner items if possible,
@@ -1114,12 +1168,14 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
             visitor.visit_ty(ty);
             visit_opt(expr, |expr| visitor.visit_expr(expr));
         }
-        ForeignItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+        ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
+            visit_defaultness(defaultness, visitor);
             visitor.visit_generics(generics);
             visit_fn_sig(sig, visitor);
             visit_opt(body, |body| visitor.visit_block(body));
         }
-        ForeignItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+        ForeignItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
+            visit_defaultness(defaultness, visitor);
             visitor.visit_generics(generics);
             visit_bounds(bounds, visitor);
             visit_opt(ty, |ty| visitor.visit_ty(ty));
index 500c97e65ef9cc868611037369912944f783430a..742a7d1d2df70907fa087b4221fffbf816b835bf 100644 (file)
@@ -212,7 +212,8 @@ pub fn to_ast_binop(&self) -> Option<BinOpKind> {
     /// parentheses while having a high degree of confidence on the correctness of the suggestion.
     pub fn can_continue_expr_unambiguously(&self) -> bool {
         use AssocOp::*;
-        match self {
+        matches!(
+            self,
             BitXor | // `{ 42 } ^ 3`
             Assign | // `{ 42 } = { 42 }`
             Divide | // `{ 42 } / 42`
@@ -225,9 +226,8 @@ pub fn can_continue_expr_unambiguously(&self) -> bool {
             As | // `{ 42 } as usize`
             // Equal | // `{ 42 } == { 42 }`    Accepting these here would regress incorrect
             // NotEqual | // `{ 42 } != { 42 }  struct literals parser recovery.
-            Colon => true, // `{ 42 }: usize`
-            _ => false,
-        }
+            Colon, // `{ 42 }: usize`
+        )
     }
 }
 
diff --git a/compiler/rustc_ast/src/util/unicode.rs b/compiler/rustc_ast/src/util/unicode.rs
new file mode 100644 (file)
index 0000000..f009f7b
--- /dev/null
@@ -0,0 +1,35 @@
+pub const TEXT_FLOW_CONTROL_CHARS: &[char] = &[
+    '\u{202A}', '\u{202B}', '\u{202D}', '\u{202E}', '\u{2066}', '\u{2067}', '\u{2068}', '\u{202C}',
+    '\u{2069}',
+];
+
+#[inline]
+pub fn contains_text_flow_control_chars(s: &str) -> bool {
+    // Char   - UTF-8
+    // U+202A - E2 80 AA
+    // U+202B - E2 80 AB
+    // U+202C - E2 80 AC
+    // U+202D - E2 80 AD
+    // U+202E - E2 80 AE
+    // U+2066 - E2 81 A6
+    // U+2067 - E2 81 A7
+    // U+2068 - E2 81 A8
+    // U+2069 - E2 81 A9
+    let mut bytes = s.as_bytes();
+    loop {
+        match core::slice::memchr::memchr(0xE2, &bytes) {
+            Some(idx) => {
+                // bytes are valid UTF-8 -> E2 must be followed by two bytes
+                let ch = &bytes[idx..idx + 3];
+                match ch {
+                    [_, 0x80, 0xAA..=0xAE] | [_, 0x81, 0xA6..=0xA9] => break true,
+                    _ => {}
+                }
+                bytes = &bytes[idx + 3..];
+            }
+            None => {
+                break false;
+            }
+        }
+    }
+}
index b38031042e0f09ed1265acf60725eca661dc84f5..be794ed221ae702331d0940d0df935545d255b61 100644 (file)
@@ -285,7 +285,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_ty(typ);
             walk_list!(visitor, visit_expr, expr);
         }
-        ItemKind::Fn(box FnKind(_, ref sig, ref generics, ref body)) => {
+        ItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
             visitor.visit_generics(generics);
             let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref());
             visitor.visit_fn(kind, item.span, item.id)
@@ -300,7 +300,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             walk_list!(visitor, visit_foreign_item, &foreign_module.items);
         }
         ItemKind::GlobalAsm(ref asm) => walk_inline_asm(visitor, asm),
-        ItemKind::TyAlias(box TyAliasKind(_, ref generics, ref bounds, ref ty)) => {
+        ItemKind::TyAlias(box TyAlias { defaultness: _, ref generics, ref bounds, ref ty }) => {
             visitor.visit_generics(generics);
             walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_ty, ty);
@@ -309,12 +309,12 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_generics(generics);
             visitor.visit_enum_def(enum_definition, generics, item.id, item.span)
         }
-        ItemKind::Impl(box ImplKind {
-            unsafety: _,
-            polarity: _,
+        ItemKind::Impl(box Impl {
             defaultness: _,
-            constness: _,
+            unsafety: _,
             ref generics,
+            constness: _,
+            polarity: _,
             ref of_trait,
             ref self_ty,
             ref items,
@@ -329,7 +329,13 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_generics(generics);
             visitor.visit_variant_data(struct_definition);
         }
-        ItemKind::Trait(box TraitKind(.., ref generics, ref bounds, ref items)) => {
+        ItemKind::Trait(box Trait {
+            unsafety: _,
+            is_auto: _,
+            ref generics,
+            ref bounds,
+            ref items,
+        }) => {
             visitor.visit_generics(generics);
             walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
@@ -547,12 +553,12 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI
             visitor.visit_ty(ty);
             walk_list!(visitor, visit_expr, expr);
         }
-        ForeignItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+        ForeignItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
             visitor.visit_generics(generics);
             let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
             visitor.visit_fn(kind, span, id);
         }
-        ForeignItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+        ForeignItemKind::TyAlias(box TyAlias { defaultness: _, generics, bounds, ty }) => {
             visitor.visit_generics(generics);
             walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_ty, ty);
@@ -653,12 +659,12 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
             visitor.visit_ty(ty);
             walk_list!(visitor, visit_expr, expr);
         }
-        AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+        AssocItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
             visitor.visit_generics(generics);
             let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
             visitor.visit_fn(kind, span, id);
         }
-        AssocItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+        AssocItemKind::TyAlias(box TyAlias { defaultness: _, generics, bounds, ty }) => {
             visitor.visit_generics(generics);
             walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_ty, ty);
index d0da88f1cc095163e82ebef41dd2df9a95eea2e3..95997a37d845b97e18a86b779992aae0b8e6b7b5 100644 (file)
@@ -4,7 +4,8 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
-use rustc_span::{Span, Symbol};
+use rustc_session::parse::feature_err;
+use rustc_span::{sym, Span, Symbol};
 use rustc_target::asm;
 use std::collections::hash_map::Entry;
 use std::fmt::Write;
@@ -18,6 +19,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             struct_span_err!(self.sess, sp, E0472, "inline assembly is unsupported on this target")
                 .emit();
         }
+        if let Some(asm_arch) = asm_arch {
+            // Inline assembly is currently only stable for these architectures.
+            let is_stable = matches!(
+                asm_arch,
+                asm::InlineAsmArch::X86
+                    | asm::InlineAsmArch::X86_64
+                    | asm::InlineAsmArch::Arm
+                    | asm::InlineAsmArch::AArch64
+                    | asm::InlineAsmArch::RiscV32
+                    | asm::InlineAsmArch::RiscV64
+            );
+            if !is_stable && !self.sess.features_untracked().asm_experimental_arch {
+                feature_err(
+                    &self.sess.parse_sess,
+                    sym::asm_experimental_arch,
+                    sp,
+                    "inline assembly is not stable yet on this architecture",
+                )
+                .emit();
+            }
+        }
         if asm.options.contains(InlineAsmOptions::ATT_SYNTAX)
             && !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64))
             && !self.sess.opts.actually_rustdoc
@@ -121,10 +143,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
                         }
                     }
-                    InlineAsmOperand::Const { ref anon_const } => hir::InlineAsmOperand::Const {
-                        anon_const: self.lower_anon_const(anon_const),
-                    },
+                    InlineAsmOperand::Const { ref anon_const } => {
+                        if !self.sess.features_untracked().asm_const {
+                            feature_err(
+                                &self.sess.parse_sess,
+                                sym::asm_const,
+                                *op_sp,
+                                "const operands for inline assembly are unstable",
+                            )
+                            .emit();
+                        }
+                        hir::InlineAsmOperand::Const {
+                            anon_const: self.lower_anon_const(anon_const),
+                        }
+                    }
                     InlineAsmOperand::Sym { ref expr } => {
+                        if !self.sess.features_untracked().asm_sym {
+                            feature_err(
+                                &self.sess.parse_sess,
+                                sym::asm_sym,
+                                *op_sp,
+                                "sym operands for inline assembly are unstable",
+                            )
+                            .emit();
+                        }
                         hir::InlineAsmOperand::Sym { expr: self.lower_expr_mut(expr) }
                     }
                 };
index 63b20cd320b37b60ef04f67f0acd4b81f1c79625..6a4571cf6d278928ab4bd8ae10ceda56613f7e56 100644 (file)
@@ -49,7 +49,7 @@ fn visit_item(&mut self, item: &'a Item) {
         self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
             let this = &mut ItemLowerer { lctx: this };
             match item.kind {
-                ItemKind::Impl(box ImplKind { ref of_trait, .. }) => {
+                ItemKind::Impl(box Impl { ref of_trait, .. }) => {
                     this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
                 }
                 _ => visit::walk_item(this, item),
@@ -218,12 +218,12 @@ fn lower_item_kind(
                 let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
                 hir::ItemKind::Const(ty, body_id)
             }
-            ItemKind::Fn(box FnKind(
-                _,
-                FnSig { ref decl, header, span: fn_sig_span },
+            ItemKind::Fn(box Fn {
+                sig: FnSig { ref decl, header, span: fn_sig_span },
                 ref generics,
                 ref body,
-            )) => {
+                ..
+            }) => {
                 let fn_def_id = self.resolver.local_def_id(id);
                 self.with_new_scopes(|this| {
                     this.current_item = Some(ident.span);
@@ -273,7 +273,7 @@ fn lower_item_kind(
             ItemKind::GlobalAsm(ref asm) => {
                 hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm))
             }
-            ItemKind::TyAlias(box TyAliasKind(_, ref gen, _, Some(ref ty))) => {
+            ItemKind::TyAlias(box TyAlias { ref generics, ty: Some(ref ty), .. }) => {
                 // We lower
                 //
                 // type Foo = impl Trait
@@ -288,10 +288,10 @@ fn lower_item_kind(
                         capturable_lifetimes: &mut FxHashSet::default(),
                     },
                 );
-                let generics = self.lower_generics(gen, ImplTraitContext::disallowed());
+                let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
                 hir::ItemKind::TyAlias(ty, generics)
             }
-            ItemKind::TyAlias(box TyAliasKind(_, ref generics, _, None)) => {
+            ItemKind::TyAlias(box TyAlias { ref generics, ty: None, .. }) => {
                 let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
                 let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
                 hir::ItemKind::TyAlias(ty, generics)
@@ -318,7 +318,7 @@ fn lower_item_kind(
                     self.lower_generics(generics, ImplTraitContext::disallowed()),
                 )
             }
-            ItemKind::Impl(box ImplKind {
+            ItemKind::Impl(box Impl {
                 unsafety,
                 polarity,
                 defaultness,
@@ -384,13 +384,13 @@ fn lower_item_kind(
                     items: new_impl_items,
                 })
             }
-            ItemKind::Trait(box TraitKind(
+            ItemKind::Trait(box Trait {
                 is_auto,
                 unsafety,
                 ref generics,
                 ref bounds,
                 ref items,
-            )) => {
+            }) => {
                 let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
                 let items = self
                     .arena
@@ -655,7 +655,7 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir
             def_id,
             ident: self.lower_ident(i.ident),
             kind: match i.kind {
-                ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
+                ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
                     let fdec = &sig.decl;
                     let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
                         generics,
@@ -772,13 +772,13 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
                 let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
                 (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body))
             }
-            AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, None)) => {
+            AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
                 let names = self.lower_fn_params_to_names(&sig.decl);
                 let (generics, sig) =
                     self.lower_method_sig(generics, sig, trait_item_def_id, false, None);
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
             }
-            AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, Some(ref body))) => {
+            AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
                 let asyncness = sig.header.asyncness;
                 let body_id =
                     self.lower_maybe_async_body(i.span, &sig.decl, asyncness, Some(&body));
@@ -791,8 +791,8 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
                 );
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
             }
-            AssocItemKind::TyAlias(box TyAliasKind(_, ref generics, ref bounds, ref default)) => {
-                let ty = default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed()));
+            AssocItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
+                let ty = ty.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed()));
                 let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
                 let kind = hir::TraitItemKind::Type(
                     self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
@@ -818,11 +818,11 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
     fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
         let (kind, has_default) = match &i.kind {
             AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()),
-            AssocItemKind::TyAlias(box TyAliasKind(_, _, _, default)) => {
-                (hir::AssocItemKind::Type, default.is_some())
+            AssocItemKind::TyAlias(box TyAlias { ty, .. }) => {
+                (hir::AssocItemKind::Type, ty.is_some())
             }
-            AssocItemKind::Fn(box FnKind(_, sig, _, default)) => {
-                (hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, default.is_some())
+            AssocItemKind::Fn(box Fn { sig, body, .. }) => {
+                (hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, body.is_some())
             }
             AssocItemKind::MacCall(..) => unimplemented!(),
         };
@@ -853,7 +853,7 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
                     hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
                 )
             }
-            AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+            AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
                 self.current_item = Some(i.span);
                 let asyncness = sig.header.asyncness;
                 let body_id =
@@ -869,7 +869,7 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
 
                 (generics, hir::ImplItemKind::Fn(sig, body_id))
             }
-            AssocItemKind::TyAlias(box TyAliasKind(_, generics, _, ty)) => {
+            AssocItemKind::TyAlias(box TyAlias { generics, ty, .. }) => {
                 let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
                 let kind = match ty {
                     None => {
@@ -920,7 +920,7 @@ fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
             kind: match &i.kind {
                 AssocItemKind::Const(..) => hir::AssocItemKind::Const,
                 AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type,
-                AssocItemKind::Fn(box FnKind(_, sig, ..)) => {
+                AssocItemKind::Fn(box Fn { sig, .. }) => {
                     hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
                 }
                 AssocItemKind::MacCall(..) => unimplemented!(),
index 793f6504be6f79f030ea168db247a9a4793f1d80..1822ba6ec996493d952d217a25fa39253c5c383a 100644 (file)
@@ -1064,7 +1064,7 @@ fn visit_item(&mut self, item: &'a Item) {
         }
 
         match item.kind {
-            ItemKind::Impl(box ImplKind {
+            ItemKind::Impl(box Impl {
                 unsafety,
                 polarity,
                 defaultness: _,
@@ -1111,7 +1111,7 @@ fn visit_item(&mut self, item: &'a Item) {
                 });
                 return; // Avoid visiting again.
             }
-            ItemKind::Impl(box ImplKind {
+            ItemKind::Impl(box Impl {
                 unsafety,
                 polarity,
                 defaultness,
@@ -1152,8 +1152,8 @@ fn visit_item(&mut self, item: &'a Item) {
                         .emit();
                 }
             }
-            ItemKind::Fn(box FnKind(def, ref sig, ref generics, ref body)) => {
-                self.check_defaultness(item.span, def);
+            ItemKind::Fn(box Fn { defaultness, ref sig, ref generics, ref body }) => {
+                self.check_defaultness(item.span, defaultness);
 
                 if body.is_none() {
                     let msg = "free function without a body";
@@ -1195,19 +1195,13 @@ fn visit_item(&mut self, item: &'a Item) {
                     }
                 }
             }
-            ItemKind::Trait(box TraitKind(
-                is_auto,
-                _,
-                ref generics,
-                ref bounds,
-                ref trait_items,
-            )) => {
+            ItemKind::Trait(box Trait { is_auto, ref generics, ref bounds, ref items, .. }) => {
                 if is_auto == IsAuto::Yes {
                     // Auto traits cannot have generics, super traits nor contain items.
                     self.deny_generic_params(generics, item.ident.span);
                     self.deny_super_traits(bounds, item.ident.span);
                     self.deny_where_clause(&generics.where_clause, item.ident.span);
-                    self.deny_items(trait_items, item.ident.span);
+                    self.deny_items(items, item.ident.span);
                 }
                 self.no_questions_in_bounds(bounds, "supertraits", true);
 
@@ -1217,7 +1211,7 @@ fn visit_item(&mut self, item: &'a Item) {
                 self.visit_ident(item.ident);
                 self.visit_generics(generics);
                 self.with_banned_tilde_const(|this| walk_list!(this, visit_param_bound, bounds));
-                walk_list!(self, visit_assoc_item, trait_items, AssocCtxt::Trait);
+                walk_list!(self, visit_assoc_item, items, AssocCtxt::Trait);
                 walk_list!(self, visit_attribute, &item.attrs);
                 return;
             }
@@ -1278,9 +1272,9 @@ fn visit_item(&mut self, item: &'a Item) {
                 let msg = "free static item without body";
                 self.error_item_without_body(item.span, "static", msg, " = <expr>;");
             }
-            ItemKind::TyAlias(box TyAliasKind(def, _, ref bounds, ref body)) => {
-                self.check_defaultness(item.span, def);
-                if body.is_none() {
+            ItemKind::TyAlias(box TyAlias { defaultness, ref bounds, ref ty, .. }) => {
+                self.check_defaultness(item.span, defaultness);
+                if ty.is_none() {
                     let msg = "free type alias without body";
                     self.error_item_without_body(item.span, "type", msg, " = <type>;");
                 }
@@ -1294,15 +1288,15 @@ fn visit_item(&mut self, item: &'a Item) {
 
     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
         match &fi.kind {
-            ForeignItemKind::Fn(box FnKind(def, sig, _, body)) => {
-                self.check_defaultness(fi.span, *def);
+            ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {
+                self.check_defaultness(fi.span, *defaultness);
                 self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
                 self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
                 self.check_foreign_item_ascii_only(fi.ident);
             }
-            ForeignItemKind::TyAlias(box TyAliasKind(def, generics, bounds, body)) => {
-                self.check_defaultness(fi.span, *def);
-                self.check_foreign_kind_bodyless(fi.ident, "type", body.as_ref().map(|b| b.span));
+            ForeignItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty, .. }) => {
+                self.check_defaultness(fi.span, *defaultness);
+                self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
                 self.check_type_no_bounds(bounds, "`extern` blocks");
                 self.check_foreign_ty_genericless(generics);
                 self.check_foreign_item_ascii_only(fi.ident);
@@ -1587,11 +1581,11 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
                 AssocItemKind::Const(_, _, body) => {
                     self.check_impl_item_provided(item.span, body, "constant", " = <expr>;");
                 }
-                AssocItemKind::Fn(box FnKind(_, _, _, body)) => {
+                AssocItemKind::Fn(box Fn { body, .. }) => {
                     self.check_impl_item_provided(item.span, body, "function", " { <body> }");
                 }
-                AssocItemKind::TyAlias(box TyAliasKind(_, _, bounds, body)) => {
-                    self.check_impl_item_provided(item.span, body, "type", " = <type>;");
+                AssocItemKind::TyAlias(box TyAlias { bounds, ty, .. }) => {
+                    self.check_impl_item_provided(item.span, ty, "type", " = <type>;");
                     self.check_type_no_bounds(bounds, "`impl`s");
                 }
                 _ => {}
@@ -1600,7 +1594,7 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
 
         if ctxt == AssocCtxt::Trait || self.in_trait_impl {
             self.invalid_visibility(&item.vis, None);
-            if let AssocItemKind::Fn(box FnKind(_, sig, _, _)) = &item.kind {
+            if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
                 self.check_trait_fn_not_const(sig.header.constness);
                 self.check_trait_fn_not_async(item.span, sig.header.asyncness);
             }
@@ -1611,7 +1605,7 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
         }
 
         match item.kind {
-            AssocItemKind::TyAlias(box TyAliasKind(_, ref generics, ref bounds, ref ty))
+            AssocItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. })
                 if ctxt == AssocCtxt::Trait =>
             {
                 self.visit_vis(&item.vis);
@@ -1623,7 +1617,7 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
                 });
                 walk_list!(self, visit_ty, ty);
             }
-            AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, ref body))
+            AssocItemKind::Fn(box Fn { ref sig, ref generics, ref body, .. })
                 if self.in_const_trait_impl
                     || ctxt == AssocCtxt::Trait
                     || matches!(sig.header.constness, Const::Yes(_)) =>
index 91b4597a9bb1f021357f9bfff3aada7bcee74ff0..f45a79f026fb53521ab83117144b2c91a9003a2f 100644 (file)
@@ -423,9 +423,7 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                 }
             }
 
-            ast::ItemKind::Impl(box ast::ImplKind {
-                polarity, defaultness, ref of_trait, ..
-            }) => {
+            ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, ref of_trait, .. }) => {
                 if let ast::ImplPolarity::Negative(span) = polarity {
                     gate_feature_post!(
                         &self,
@@ -441,7 +439,7 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                 }
             }
 
-            ast::ItemKind::Trait(box ast::TraitKind(ast::IsAuto::Yes, ..)) => {
+            ast::ItemKind::Trait(box ast::Trait { is_auto: ast::IsAuto::Yes, .. }) => {
                 gate_feature_post!(
                     &self,
                     auto_traits,
@@ -459,7 +457,7 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                 gate_feature_post!(&self, decl_macro, i.span, msg);
             }
 
-            ast::ItemKind::TyAlias(box ast::TyAliasKind(_, _, _, Some(ref ty))) => {
+            ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ref ty), .. }) => {
                 self.check_impl_trait(&ty)
             }
 
@@ -541,15 +539,13 @@ fn visit_expr(&mut self, e: &'a ast::Expr) {
             ast::ExprKind::TryBlock(_) => {
                 gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
             }
-            ast::ExprKind::Block(_, opt_label) => {
-                if let Some(label) = opt_label {
-                    gate_feature_post!(
-                        &self,
-                        label_break_value,
-                        label.ident.span,
-                        "labels on blocks are unstable"
-                    );
-                }
+            ast::ExprKind::Block(_, Some(label)) => {
+                gate_feature_post!(
+                    &self,
+                    label_break_value,
+                    label.ident.span,
+                    "labels on blocks are unstable"
+                );
             }
             _ => {}
         }
@@ -634,7 +630,7 @@ fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
     fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
         let is_fn = match i.kind {
             ast::AssocItemKind::Fn(_) => true,
-            ast::AssocItemKind::TyAlias(box ast::TyAliasKind(_, ref generics, _, ref ty)) => {
+            ast::AssocItemKind::TyAlias(box ast::TyAlias { ref generics, ref ty, .. }) => {
                 if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
                     gate_feature_post!(
                         &self,
index 6d0589b7ba1af7a5ae205dc8a45df5f09ae9257e..b59e49926add91d9d2a1c6fdb13c17e00c8ddcb1 100644 (file)
@@ -1044,15 +1044,27 @@ pub fn print_type(&mut self, ty: &ast::Ty) {
         self.maybe_print_comment(span.lo());
         self.print_outer_attributes(attrs);
         match kind {
-            ast::ForeignItemKind::Fn(box ast::FnKind(def, sig, gen, body)) => {
-                self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs);
+            ast::ForeignItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
+                self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
             }
             ast::ForeignItemKind::Static(ty, mutbl, body) => {
                 let def = ast::Defaultness::Final;
                 self.print_item_const(ident, Some(*mutbl), ty, body.as_deref(), vis, def);
             }
-            ast::ForeignItemKind::TyAlias(box ast::TyAliasKind(def, generics, bounds, ty)) => {
-                self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def);
+            ast::ForeignItemKind::TyAlias(box ast::TyAlias {
+                defaultness,
+                generics,
+                bounds,
+                ty,
+            }) => {
+                self.print_associated_type(
+                    ident,
+                    generics,
+                    bounds,
+                    ty.as_deref(),
+                    vis,
+                    *defaultness,
+                );
             }
             ast::ForeignItemKind::MacCall(m) => {
                 self.print_mac(m);
@@ -1156,9 +1168,17 @@ fn print_associated_type(
             ast::ItemKind::Const(def, ref ty, ref body) => {
                 self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def);
             }
-            ast::ItemKind::Fn(box ast::FnKind(def, ref sig, ref gen, ref body)) => {
+            ast::ItemKind::Fn(box ast::Fn { defaultness, ref sig, ref generics, ref body }) => {
                 let body = body.as_deref();
-                self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs);
+                self.print_fn_full(
+                    sig,
+                    item.ident,
+                    generics,
+                    &item.vis,
+                    defaultness,
+                    body,
+                    &item.attrs,
+                );
             }
             ast::ItemKind::Mod(unsafety, ref mod_kind) => {
                 self.head(self.to_string(|s| {
@@ -1203,9 +1223,21 @@ fn print_associated_type(
                 self.print_inline_asm(asm);
                 self.end();
             }
-            ast::ItemKind::TyAlias(box ast::TyAliasKind(def, ref generics, ref bounds, ref ty)) => {
+            ast::ItemKind::TyAlias(box ast::TyAlias {
+                defaultness,
+                ref generics,
+                ref bounds,
+                ref ty,
+            }) => {
                 let ty = ty.as_deref();
-                self.print_associated_type(item.ident, generics, bounds, ty, &item.vis, def);
+                self.print_associated_type(
+                    item.ident,
+                    generics,
+                    bounds,
+                    ty,
+                    &item.vis,
+                    defaultness,
+                );
             }
             ast::ItemKind::Enum(ref enum_definition, ref params) => {
                 self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis);
@@ -1218,7 +1250,7 @@ fn print_associated_type(
                 self.head(visibility_qualified(&item.vis, "union"));
                 self.print_struct(struct_def, generics, item.ident, item.span, true);
             }
-            ast::ItemKind::Impl(box ast::ImplKind {
+            ast::ItemKind::Impl(box ast::Impl {
                 unsafety,
                 polarity,
                 defaultness,
@@ -1261,13 +1293,14 @@ fn print_associated_type(
                 }
                 self.bclose(item.span);
             }
-            ast::ItemKind::Trait(box ast::TraitKind(
+            ast::ItemKind::Trait(box ast::Trait {
                 is_auto,
                 unsafety,
                 ref generics,
                 ref bounds,
-                ref trait_items,
-            )) => {
+                ref items,
+                ..
+            }) => {
                 self.head("");
                 self.print_visibility(&item.vis);
                 self.print_unsafety(unsafety);
@@ -1290,7 +1323,7 @@ fn print_associated_type(
                 self.s.word(" ");
                 self.bopen();
                 self.print_inner_attributes(&item.attrs);
-                for trait_item in trait_items {
+                for trait_item in items {
                     self.print_assoc_item(trait_item);
                 }
                 self.bclose(item.span);
@@ -1405,11 +1438,7 @@ fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
         }
     }
 
-    crate fn print_record_struct_body(
-        &mut self,
-        fields: &Vec<ast::FieldDef>,
-        span: rustc_span::Span,
-    ) {
+    crate fn print_record_struct_body(&mut self, fields: &[ast::FieldDef], span: rustc_span::Span) {
         self.nbsp();
         self.bopen();
         self.hardbreak_if_not_bol();
@@ -1483,14 +1512,21 @@ fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
         self.maybe_print_comment(span.lo());
         self.print_outer_attributes(attrs);
         match kind {
-            ast::AssocItemKind::Fn(box ast::FnKind(def, sig, gen, body)) => {
-                self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs);
+            ast::AssocItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
+                self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
             }
             ast::AssocItemKind::Const(def, ty, body) => {
                 self.print_item_const(ident, None, ty, body.as_deref(), vis, *def);
             }
-            ast::AssocItemKind::TyAlias(box ast::TyAliasKind(def, generics, bounds, ty)) => {
-                self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def);
+            ast::AssocItemKind::TyAlias(box ast::TyAlias { defaultness, generics, bounds, ty }) => {
+                self.print_associated_type(
+                    ident,
+                    generics,
+                    bounds,
+                    ty.as_deref(),
+                    vis,
+                    *defaultness,
+                );
             }
             ast::AssocItemKind::MacCall(m) => {
                 self.print_mac(m);
index d5de0801ac4431ccfcaab25872a16923501b8925..79973ab170cad8e362dd85199181b79b2e4c24ff 100644 (file)
@@ -53,10 +53,7 @@ pub(crate) enum LaterUseKind {
 
 impl BorrowExplanation {
     pub(crate) fn is_explained(&self) -> bool {
-        match self {
-            BorrowExplanation::Unexplained => false,
-            _ => true,
-        }
+        !matches!(self, BorrowExplanation::Unexplained)
     }
     pub(crate) fn add_explanation_to_diagnostic<'tcx>(
         &self,
index 22bb3a29425ee1b49d5b44a3bc228030af3d0ac7..f4a5da1fe36fa8d0f6d2c9465c9f56f65f6b5784 100644 (file)
@@ -2110,14 +2110,14 @@ fn check_member_constraints(
                     _ => constraint_sup_scc != target_scc,
                 }
             } else {
-                match categorized_path[*i].category {
+                !matches!(
+                    categorized_path[*i].category,
                     ConstraintCategory::OpaqueType
-                    | ConstraintCategory::Boring
-                    | ConstraintCategory::BoringNoLocation
-                    | ConstraintCategory::Internal
-                    | ConstraintCategory::Predicate(_) => false,
-                    _ => true,
-                }
+                        | ConstraintCategory::Boring
+                        | ConstraintCategory::BoringNoLocation
+                        | ConstraintCategory::Internal
+                        | ConstraintCategory::Predicate(_)
+                )
             }
         };
 
index 7e6a481ca69a1b76f62008c1282b3ea676662ac0..06e34bdce3f8678284b5c5abf55706eef0737ea7 100644 (file)
@@ -655,7 +655,7 @@ fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Locatio
             // If the region is live at at least one location in the promoted MIR,
             // then add a liveness constraint to the main MIR for this region
             // at the location provided as an argument to this method
-            if let Some(_) = liveness_constraints.get_elements(region).next() {
+            if liveness_constraints.get_elements(region).next().is_some() {
                 self.cx
                     .borrowck_context
                     .constraints
index bebd19370299d00cdf360796c578638612f80312..147e2aead648db509356fe9e77b8cd02f6f72c12 100644 (file)
@@ -138,17 +138,11 @@ pub fn implicit_inputs(self) -> usize {
     }
 
     pub fn is_fn_def(&self) -> bool {
-        match *self {
-            DefiningTy::FnDef(..) => true,
-            _ => false,
-        }
+        matches!(*self, DefiningTy::FnDef(..))
     }
 
     pub fn is_const(&self) -> bool {
-        match *self {
-            DefiningTy::Const(..) => true,
-            _ => false,
-        }
+        matches!(*self, DefiningTy::Const(..))
     }
 
     pub fn def_id(&self) -> DefId {
index 198287f608e3973d318d9d4e6e869be0dbd48c26..50127b5b15ce8fc6a87b1f38995b59a69beef96f 100644 (file)
@@ -547,7 +547,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
                 if let Some(snippet) = &template_snippet {
                     if let Some(pos) = snippet.find(needle) {
                         let end = pos
-                            + &snippet[pos..]
+                            + snippet[pos..]
                                 .find(|c| matches!(c, '\n' | ';' | '\\' | '"'))
                                 .unwrap_or(snippet[pos..].len() - 1);
                         let inner = InnerSpan::new(pos, end);
index a225b328ab6a4fc205c260e5bce01e440866384c..994a74a5a9b9f939190f50b3bcfa5184b3f9f4bb 100644 (file)
@@ -557,12 +557,12 @@ fn create_derived_impl(
                     tokens: None,
                 },
                 attrs: Vec::new(),
-                kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAliasKind(
-                    ast::Defaultness::Final,
-                    Generics::default(),
-                    Vec::new(),
-                    Some(type_def.to_ty(cx, self.span, type_ident, generics)),
-                ))),
+                kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias {
+                    defaultness: ast::Defaultness::Final,
+                    generics: Generics::default(),
+                    bounds: Vec::new(),
+                    ty: Some(type_def.to_ty(cx, self.span, type_ident, generics)),
+                })),
                 tokens: None,
             })
         });
@@ -726,7 +726,7 @@ fn create_derived_impl(
             self.span,
             Ident::empty(),
             a,
-            ast::ItemKind::Impl(Box::new(ast::ImplKind {
+            ast::ItemKind::Impl(Box::new(ast::Impl {
                 unsafety,
                 polarity: ast::ImplPolarity::Positive,
                 defaultness: ast::Defaultness::Final,
@@ -955,7 +955,7 @@ fn create_method(
             decl: fn_decl,
             span: trait_.span,
         };
-        let def = ast::Defaultness::Final;
+        let defaultness = ast::Defaultness::Final;
 
         // Create the method.
         P(ast::AssocItem {
@@ -968,12 +968,12 @@ fn create_method(
                 tokens: None,
             },
             ident: method_ident,
-            kind: ast::AssocItemKind::Fn(Box::new(ast::FnKind(
-                def,
+            kind: ast::AssocItemKind::Fn(Box::new(ast::Fn {
+                defaultness,
                 sig,
-                fn_generics,
-                Some(body_block),
-            ))),
+                generics: fn_generics,
+                body: Some(body_block),
+            })),
             tokens: None,
         })
     }
index fa389a51115782696ef49c9d7a7c860aaab1e624..367a5aa732370a0dff03491b22f151322989206e 100644 (file)
@@ -2,7 +2,7 @@
 
 use rustc_ast as ast;
 use rustc_ast::ptr::P;
-use rustc_ast::{ImplKind, ItemKind, MetaItem};
+use rustc_ast::{Impl, ItemKind, MetaItem};
 use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
@@ -180,7 +180,7 @@ fn inject_impl_of_structural_trait(
         span,
         Ident::empty(),
         attrs,
-        ItemKind::Impl(Box::new(ImplKind {
+        ItemKind::Impl(Box::new(Impl {
             unsafety: ast::Unsafe::No,
             polarity: ast::ImplPolarity::Positive,
             defaultness: ast::Defaultness::Final,
index 3f71ee6f489a08fbbdd1d413f92905f9fe769417..a433876147f8d903edbc8568485649f5eef0cf92 100644 (file)
@@ -5,7 +5,7 @@
 };
 use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
-use rustc_ast::{FnKind, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
+use rustc_ast::{Fn, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
@@ -84,13 +84,13 @@ fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt {
         let decl = self.cx.fn_decl(abi_args, ast::FnRetTy::Ty(output_ty));
         let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() };
         let sig = FnSig { decl, header, span: self.span };
-        let block = Some(self.cx.block_expr(output_expr));
-        let kind = ItemKind::Fn(Box::new(FnKind(
-            ast::Defaultness::Final,
+        let body = Some(self.cx.block_expr(output_expr));
+        let kind = ItemKind::Fn(Box::new(Fn {
+            defaultness: ast::Defaultness::Final,
             sig,
-            Generics::default(),
-            block,
-        )));
+            generics: Generics::default(),
+            body,
+        }));
         let item = self.cx.item(
             self.span,
             Ident::from_str_and_span(&self.kind.fn_name(method.name), self.span),
index bbca07085ea3615043d6b0db868459dc68c39de9..d2629926b51da705f3ae4e1dfbb28b9c1f54911d 100644 (file)
@@ -429,7 +429,7 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
 fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
     let has_should_panic_attr = cx.sess.contains_name(&i.attrs, sym::should_panic);
     let sd = &cx.sess.parse_sess.span_diagnostic;
-    if let ast::ItemKind::Fn(box ast::FnKind(_, ref sig, ref generics, _)) = i.kind {
+    if let ast::ItemKind::Fn(box ast::Fn { ref sig, ref generics, .. }) = i.kind {
         if let ast::Unsafe::Yes(span) = sig.header.unsafety {
             sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
                 .span_label(span, "`unsafe` because of this")
@@ -478,7 +478,7 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
 }
 
 fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
-    let has_sig = if let ast::ItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) = i.kind {
+    let has_sig = if let ast::ItemKind::Fn(box ast::Fn { ref sig, .. }) = i.kind {
         // N.B., inadequate check, but we're running
         // well before resolve, can't get too deep.
         sig.decl.inputs.len() == 1
index d791677cb8ee1adbd64cd24f9df8aa3fe5aa1c2c..64ccd4331e58a7c3492840e3bba07e8d88452e4b 100644 (file)
@@ -313,13 +313,13 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
 
     let decl = ecx.fn_decl(vec![], ast::FnRetTy::Ty(main_ret_ty));
     let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
-    let def = ast::Defaultness::Final;
-    let main = ast::ItemKind::Fn(Box::new(ast::FnKind(
-        def,
+    let defaultness = ast::Defaultness::Final;
+    let main = ast::ItemKind::Fn(Box::new(ast::Fn {
+        defaultness,
         sig,
-        ast::Generics::default(),
-        Some(main_body),
-    )));
+        generics: ast::Generics::default(),
+        body: Some(main_body),
+    }));
 
     // Honor the reexport_test_harness_main attribute
     let main_id = match cx.reexport_test_harness_main {
index dca9c1f04d3c0fd40672c6babd21295aeb89473b..bedd3523d899e89f0f8205c28b72ad7e03307c17 100644 (file)
@@ -1,7 +1,6 @@
 use crate::builder::Builder;
 use crate::context::CodegenCx;
 use crate::llvm::{self, AttributePlace};
-use crate::llvm_util;
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
@@ -53,15 +52,10 @@ fn apply_attrs_to_callsite(
 }
 
 fn should_use_mutable_noalias(cx: &CodegenCx<'_, '_>) -> bool {
-    // LLVM prior to version 12 has known miscompiles in the presence of
-    // noalias attributes (see #54878). Only enable mutable noalias by
-    // default for versions we believe to be safe.
-    cx.tcx
-        .sess
-        .opts
-        .debugging_opts
-        .mutable_noalias
-        .unwrap_or_else(|| llvm_util::get_version() >= (12, 0, 0))
+    // LLVM prior to version 12 had known miscompiles in the presence of
+    // noalias attributes (see #54878), but we don't support earlier
+    // versions at all anymore. We now enable mutable noalias by default.
+    cx.tcx.sess.opts.debugging_opts.mutable_noalias.unwrap_or(true)
 }
 
 impl ArgAttributesExt for ArgAttributes {
index 0707faf610cf3e4edc312bf9f3b8d0cac413adcf..6c74163fb496c18bf33923b9c2fc0c5f949a2e30 100644 (file)
@@ -731,7 +731,7 @@ fn sext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
     }
 
     fn fptoui_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> {
-        if llvm_util::get_version() >= (12, 0, 0) && !self.fptoint_sat_broken_in_llvm() {
+        if !self.fptoint_sat_broken_in_llvm() {
             let src_ty = self.cx.val_ty(val);
             let float_width = self.cx.float_width(src_ty);
             let int_width = self.cx.int_width(dest_ty);
@@ -743,7 +743,7 @@ fn fptoui_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Val
     }
 
     fn fptosi_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> {
-        if llvm_util::get_version() >= (12, 0, 0) && !self.fptoint_sat_broken_in_llvm() {
+        if !self.fptoint_sat_broken_in_llvm() {
             let src_ty = self.cx.val_ty(val);
             let float_width = self.cx.float_width(src_ty);
             let int_width = self.cx.int_width(dest_ty);
index cda766039c16728f9b4c70433bed31a191266fc0..1dba264a9614a32a5ae9fa62dce679a1d3fc5318 100644 (file)
@@ -134,9 +134,6 @@ pub unsafe fn create_module(
     let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
 
     let mut target_data_layout = sess.target.data_layout.clone();
-    if llvm_util::get_version() < (12, 0, 0) && sess.target.arch == "powerpc64" {
-        target_data_layout = target_data_layout.replace("-v256:256:256-v512:512:512", "");
-    }
     if llvm_util::get_version() < (13, 0, 0) {
         if sess.target.arch == "powerpc64" {
             target_data_layout = target_data_layout.replace("-S128", "");
index 8f4d79e7147d349ac7ab7978b654c062569757a4..64fedb7bc1a5cbb7b20559e67dd126d563a9e403 100644 (file)
@@ -76,6 +76,27 @@ pub mod llvm {
 #[derive(Clone)]
 pub struct LlvmCodegenBackend(());
 
+struct TimeTraceProfiler {
+    enabled: bool,
+}
+
+impl TimeTraceProfiler {
+    fn new(enabled: bool) -> Self {
+        if enabled {
+            unsafe { llvm::LLVMTimeTraceProfilerInitialize() }
+        }
+        TimeTraceProfiler { enabled }
+    }
+}
+
+impl Drop for TimeTraceProfiler {
+    fn drop(&mut self) {
+        if self.enabled {
+            unsafe { llvm::LLVMTimeTraceProfilerFinishThread() }
+        }
+    }
+}
+
 impl ExtraBackendMethods for LlvmCodegenBackend {
     fn new_metadata(&self, tcx: TyCtxt<'_>, mod_name: &str) -> ModuleLlvm {
         ModuleLlvm::new_metadata(tcx, mod_name)
@@ -119,6 +140,34 @@ fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str {
     fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str> {
         llvm_util::tune_cpu(sess)
     }
+
+    fn spawn_thread<F, T>(time_trace: bool, f: F) -> std::thread::JoinHandle<T>
+    where
+        F: FnOnce() -> T,
+        F: Send + 'static,
+        T: Send + 'static,
+    {
+        std::thread::spawn(move || {
+            let _profiler = TimeTraceProfiler::new(time_trace);
+            f()
+        })
+    }
+
+    fn spawn_named_thread<F, T>(
+        time_trace: bool,
+        name: String,
+        f: F,
+    ) -> std::io::Result<std::thread::JoinHandle<T>>
+    where
+        F: FnOnce() -> T,
+        F: Send + 'static,
+        T: Send + 'static,
+    {
+        std::thread::Builder::new().name(name).spawn(move || {
+            let _profiler = TimeTraceProfiler::new(time_trace);
+            f()
+        })
+    }
 }
 
 impl WriteBackendMethods for LlvmCodegenBackend {
index 21d2388fc3054f458dcf12a200d2c169324627fb..749eec459aca1334be2f17da146280b6cb3fcc5c 100644 (file)
@@ -1737,6 +1737,8 @@ pub fn LLVMRustBuildAtomicFence(
 
     pub fn LLVMTimeTraceProfilerInitialize();
 
+    pub fn LLVMTimeTraceProfilerFinishThread();
+
     pub fn LLVMTimeTraceProfilerFinish(FileName: *const c_char);
 
     pub fn LLVMAddAnalysisPasses(T: &'a TargetMachine, PM: &PassManager<'a>);
index baa257069aa1ce156b0ae22d9736dac39a838dd6..c3e7e7169a92c913934c223b7dfc60a522753a25 100644 (file)
@@ -113,11 +113,6 @@ fn llvm_arg_to_arg_name(full_arg: &str) -> &str {
     }
 
     if sess.opts.debugging_opts.llvm_time_trace {
-        // time-trace is not thread safe and running it in parallel will cause seg faults.
-        if !sess.opts.debugging_opts.no_parallel_llvm {
-            bug!("`-Z llvm-time-trace` requires `-Z no-parallel-llvm")
-        }
-
         llvm::LLVMTimeTraceProfilerInitialize();
     }
 
@@ -180,6 +175,7 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> Vec<&'a str> {
         ("aarch64", "dpb2") => vec!["ccdp"],
         ("aarch64", "frintts") => vec!["fptoint"],
         ("aarch64", "fcma") => vec!["complxnum"],
+        ("aarch64", "pmuv3") => vec!["perfmon"],
         (_, s) => vec![s],
     }
 }
@@ -405,11 +401,6 @@ pub fn llvm_global_features(sess: &Session) -> Vec<String> {
     // -Ctarget-features
     features.extend(sess.opts.cg.target_feature.split(',').flat_map(&filter));
 
-    // FIXME: Move outline-atomics to target definition when earliest supported LLVM is 12.
-    if get_version() >= (12, 0, 0) && sess.target.llvm_target.contains("aarch64-unknown-linux") {
-        features.push("+outline-atomics".to_string());
-    }
-
     features
 }
 
index be50911f4e143a8b5cb91fc4e0c8d344c9600982..6c02543bd7cc4fc49c04e6b83c638bcff386546a 100644 (file)
@@ -1095,10 +1095,10 @@ fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut d
 }
 
 fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
-    fn find_sanitizer_runtime(sess: &Session, filename: &String) -> PathBuf {
+    fn find_sanitizer_runtime(sess: &Session, filename: &str) -> PathBuf {
         let session_tlib =
             filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple());
-        let path = session_tlib.join(&filename);
+        let path = session_tlib.join(filename);
         if path.exists() {
             return session_tlib;
         } else {
index da34612ce76acb274b996feb2538efb03e49eb92..b2edc6c0183a0b8ce13475e2d3b406c18105221a 100644 (file)
@@ -310,6 +310,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
     pub no_landing_pads: bool,
     pub save_temps: bool,
     pub fewer_names: bool,
+    pub time_trace: bool,
     pub exported_symbols: Option<Arc<ExportedSymbols>>,
     pub opts: Arc<config::Options>,
     pub crate_types: Vec<CrateType>,
@@ -1039,6 +1040,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
         no_landing_pads: sess.panic_strategy() == PanicStrategy::Abort,
         fewer_names: sess.fewer_names(),
         save_temps: sess.opts.cg.save_temps,
+        time_trace: sess.opts.debugging_opts.llvm_time_trace,
         opts: Arc::new(sess.opts.clone()),
         prof: sess.prof.clone(),
         exported_symbols,
@@ -1198,7 +1200,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
     // Each LLVM module is automatically sent back to the coordinator for LTO if
     // necessary. There's already optimizations in place to avoid sending work
     // back to the coordinator if LTO isn't requested.
-    return thread::spawn(move || {
+    return B::spawn_thread(cgcx.time_trace, move || {
         let mut worker_id_counter = 0;
         let mut free_worker_ids = Vec::new();
         let mut get_worker_id = |free_worker_ids: &mut Vec<usize>| {
@@ -1615,59 +1617,57 @@ fn maybe_start_llvm_timer<'a>(
 pub struct WorkerFatalError;
 
 fn spawn_work<B: ExtraBackendMethods>(cgcx: CodegenContext<B>, work: WorkItem<B>) {
-    let builder = thread::Builder::new().name(work.short_description());
-    builder
-        .spawn(move || {
-            // Set up a destructor which will fire off a message that we're done as
-            // we exit.
-            struct Bomb<B: ExtraBackendMethods> {
-                coordinator_send: Sender<Box<dyn Any + Send>>,
-                result: Option<Result<WorkItemResult<B>, FatalError>>,
-                worker_id: usize,
-            }
-            impl<B: ExtraBackendMethods> Drop for Bomb<B> {
-                fn drop(&mut self) {
-                    let worker_id = self.worker_id;
-                    let msg = match self.result.take() {
-                        Some(Ok(WorkItemResult::Compiled(m))) => {
-                            Message::Done::<B> { result: Ok(m), worker_id }
-                        }
-                        Some(Ok(WorkItemResult::NeedsLink(m))) => {
-                            Message::NeedsLink::<B> { module: m, worker_id }
-                        }
-                        Some(Ok(WorkItemResult::NeedsFatLTO(m))) => {
-                            Message::NeedsFatLTO::<B> { result: m, worker_id }
-                        }
-                        Some(Ok(WorkItemResult::NeedsThinLTO(name, thin_buffer))) => {
-                            Message::NeedsThinLTO::<B> { name, thin_buffer, worker_id }
-                        }
-                        Some(Err(FatalError)) => {
-                            Message::Done::<B> { result: Err(Some(WorkerFatalError)), worker_id }
-                        }
-                        None => Message::Done::<B> { result: Err(None), worker_id },
-                    };
-                    drop(self.coordinator_send.send(Box::new(msg)));
-                }
+    B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || {
+        // Set up a destructor which will fire off a message that we're done as
+        // we exit.
+        struct Bomb<B: ExtraBackendMethods> {
+            coordinator_send: Sender<Box<dyn Any + Send>>,
+            result: Option<Result<WorkItemResult<B>, FatalError>>,
+            worker_id: usize,
+        }
+        impl<B: ExtraBackendMethods> Drop for Bomb<B> {
+            fn drop(&mut self) {
+                let worker_id = self.worker_id;
+                let msg = match self.result.take() {
+                    Some(Ok(WorkItemResult::Compiled(m))) => {
+                        Message::Done::<B> { result: Ok(m), worker_id }
+                    }
+                    Some(Ok(WorkItemResult::NeedsLink(m))) => {
+                        Message::NeedsLink::<B> { module: m, worker_id }
+                    }
+                    Some(Ok(WorkItemResult::NeedsFatLTO(m))) => {
+                        Message::NeedsFatLTO::<B> { result: m, worker_id }
+                    }
+                    Some(Ok(WorkItemResult::NeedsThinLTO(name, thin_buffer))) => {
+                        Message::NeedsThinLTO::<B> { name, thin_buffer, worker_id }
+                    }
+                    Some(Err(FatalError)) => {
+                        Message::Done::<B> { result: Err(Some(WorkerFatalError)), worker_id }
+                    }
+                    None => Message::Done::<B> { result: Err(None), worker_id },
+                };
+                drop(self.coordinator_send.send(Box::new(msg)));
             }
+        }
 
-            let mut bomb = Bomb::<B> {
-                coordinator_send: cgcx.coordinator_send.clone(),
-                result: None,
-                worker_id: cgcx.worker,
-            };
+        let mut bomb = Bomb::<B> {
+            coordinator_send: cgcx.coordinator_send.clone(),
+            result: None,
+            worker_id: cgcx.worker,
+        };
 
-            // Execute the work itself, and if it finishes successfully then flag
-            // ourselves as a success as well.
-            //
-            // Note that we ignore any `FatalError` coming out of `execute_work_item`,
-            // as a diagnostic was already sent off to the main thread - just
-            // surface that there was an error in this worker.
-            bomb.result = {
-                let _prof_timer = work.start_profiling(&cgcx);
-                Some(execute_work_item(&cgcx, work))
-            };
-        })
-        .expect("failed to spawn thread");
+        // Execute the work itself, and if it finishes successfully then flag
+        // ourselves as a success as well.
+        //
+        // Note that we ignore any `FatalError` coming out of `execute_work_item`,
+        // as a diagnostic was already sent off to the main thread - just
+        // surface that there was an error in this worker.
+        bomb.result = {
+            let _prof_timer = work.start_profiling(&cgcx);
+            Some(execute_work_item(&cgcx, work))
+        };
+    })
+    .expect("failed to spawn thread");
 }
 
 enum SharedEmitterMessage {
index accb54e464553292fcd567093f4743a4fa453122..ab119ae25f5e89d496b69388ce65ab9058b4131b 100644 (file)
@@ -124,10 +124,7 @@ fn push_debuginfo_type_name<'tcx>(
             // info for MSVC debugger. However, wrapping these types' names in a synthetic type
             // causes the .natvis engine for WinDbg to fail to display their data, so we opt these
             // types out to aid debugging in MSVC.
-            let is_slice_or_str = match *inner_type.kind() {
-                ty::Slice(_) | ty::Str => true,
-                _ => false,
-            };
+            let is_slice_or_str = matches!(*inner_type.kind(), ty::Slice(_) | ty::Str);
 
             if !cpp_like_names {
                 output.push('&');
index 297dcde99b3d4e950fcd728db3addc55ff864ddb..a9471f7b7716052c60f0228c13bfd793c1c52361 100644 (file)
@@ -832,7 +832,7 @@ fn codegen_call_terminator(
             // FIXME(rcvalle): Add support for generalized identifiers.
             // FIXME(rcvalle): Create distinct unnamed MDNodes for internal identifiers.
             let typeid = typeid_for_fnabi(bx.tcx(), fn_abi);
-            let typeid_metadata = bx.typeid_metadata(typeid.clone());
+            let typeid_metadata = bx.typeid_metadata(typeid);
 
             // Test whether the function pointer is associated with the type identifier.
             let cond = bx.type_test(fn_ptr, typeid_metadata);
index 1cd400eecfbd2b0253d9af93a443174cfe6fc086..1ef863e84af7fe757b691c6fb0167bcda350f489 100644 (file)
@@ -250,7 +250,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     // is associated with a type identifier).
     if cx.tcx().sess.is_sanitizer_cfi_enabled() {
         let typeid = typeid_for_fnabi(cx.tcx(), fn_abi);
-        bx.type_metadata(llfn, typeid.clone());
+        bx.type_metadata(llfn, typeid);
     }
 }
 
index fe7f6288adb273913a8545f0ee4160d54395a244..2c96987d3399eb63f25d0a32ca0db16f3d5c4492 100644 (file)
@@ -125,7 +125,7 @@ pub fn codegen_statement(&mut self, mut bx: Bx, statement: &mir::Statement<'tcx>
                 let count = self.codegen_operand(&mut bx, count).immediate();
                 let pointee_layout = dst_val
                     .layout
-                    .pointee_info_at(&mut bx, rustc_target::abi::Size::ZERO)
+                    .pointee_info_at(&bx, rustc_target::abi::Size::ZERO)
                     .expect("Expected pointer");
                 let bytes = bx.mul(count, bx.const_usize(pointee_layout.size.bytes()));
 
index dbffb266be88c3a320738c11eac3546fb2e2e465..caeeb23feb471bf48f86dcc753c44daf94adf7b1 100644 (file)
@@ -36,7 +36,6 @@
     ("thumb-mode", Some(sym::arm_target_feature)),
 ];
 
-// Commented features are not available in LLVM 10.0, or have since been renamed
 const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     // FEAT_AdvSimd
     ("neon", Some(sym::aarch64_target_feature)),
     // FEAT_DIT
     ("dit", Some(sym::aarch64_target_feature)),
     // FEAT_FLAGM
-    // ("flagm", Some(sym::aarch64_target_feature)),
+    ("flagm", Some(sym::aarch64_target_feature)),
     // FEAT_SSBS
     ("ssbs", Some(sym::aarch64_target_feature)),
     // FEAT_SB
     ("sb", Some(sym::aarch64_target_feature)),
     // FEAT_PAUTH
-    // ("pauth", Some(sym::aarch64_target_feature)),
+    ("pauth", Some(sym::aarch64_target_feature)),
     // FEAT_DPB
     ("dpb", Some(sym::aarch64_target_feature)),
     // FEAT_DPB2
     // FEAT_I8MM
     ("i8mm", Some(sym::aarch64_target_feature)),
     // FEAT_F32MM
-    // ("f32mm", Some(sym::aarch64_target_feature)),
+    ("f32mm", Some(sym::aarch64_target_feature)),
     // FEAT_F64MM
-    // ("f64mm", Some(sym::aarch64_target_feature)),
+    ("f64mm", Some(sym::aarch64_target_feature)),
     // FEAT_BF16
-    // ("bf16", Some(sym::aarch64_target_feature)),
+    ("bf16", Some(sym::aarch64_target_feature)),
     // FEAT_RAND
     ("rand", Some(sym::aarch64_target_feature)),
     // FEAT_BTI
     ("sha3", Some(sym::aarch64_target_feature)),
     // FEAT_SM3 & FEAT_SM4
     ("sm4", Some(sym::aarch64_target_feature)),
+    // FEAT_PAN
+    ("pan", Some(sym::aarch64_target_feature)),
+    // FEAT_LOR
+    ("lor", Some(sym::aarch64_target_feature)),
+    // FEAT_VHE
+    ("vh", Some(sym::aarch64_target_feature)),
+    // FEAT_PMUv3
+    ("pmuv3", Some(sym::aarch64_target_feature)),
+    // FEAT_SPE
+    ("spe", Some(sym::aarch64_target_feature)),
     ("v8.1a", Some(sym::aarch64_target_feature)),
     ("v8.2a", Some(sym::aarch64_target_feature)),
     ("v8.3a", Some(sym::aarch64_target_feature)),
     ("v8.4a", Some(sym::aarch64_target_feature)),
     ("v8.5a", Some(sym::aarch64_target_feature)),
-    // ("v8.6a", Some(sym::aarch64_target_feature)),
-    // ("v8.7a", Some(sym::aarch64_target_feature)),
+    ("v8.6a", Some(sym::aarch64_target_feature)),
+    ("v8.7a", Some(sym::aarch64_target_feature)),
 ];
 
 const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
index 8fef8314a5ccd1aeea37ee4c83b7659d31e80cda..9c8bc3b2109881be537bd36682c4cc80cab8adb5 100644 (file)
@@ -142,4 +142,26 @@ fn target_machine_factory(
     ) -> TargetMachineFactoryFn<Self>;
     fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str;
     fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str>;
+
+    fn spawn_thread<F, T>(_time_trace: bool, f: F) -> std::thread::JoinHandle<T>
+    where
+        F: FnOnce() -> T,
+        F: Send + 'static,
+        T: Send + 'static,
+    {
+        std::thread::spawn(f)
+    }
+
+    fn spawn_named_thread<F, T>(
+        _time_trace: bool,
+        name: String,
+        f: F,
+    ) -> std::io::Result<std::thread::JoinHandle<T>>
+    where
+        F: FnOnce() -> T,
+        F: Send + 'static,
+        T: Send + 'static,
+    {
+        std::thread::Builder::new().name(name).spawn(f)
+    }
 }
index 5da1681662577648009f96b1da5b0aabfe02229d..87298023980ed8c2ff2ccde238122e1a7556fb53 100644 (file)
@@ -25,10 +25,7 @@ pub enum ConstEvalErrKind {
 
 impl MachineStopType for ConstEvalErrKind {
     fn is_hard_err(&self) -> bool {
-        match self {
-            Self::Panic { .. } => true,
-            _ => false,
-        }
+        matches!(self, Self::Panic { .. })
     }
 }
 
index 80551518d3c5d8bdbe10341d2fd5d98e8ec1dafb..821b048eb9bcfc80331ce6f46616bcd3b42babc1 100644 (file)
@@ -51,10 +51,8 @@ fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         // If the function itself is not annotated with `const`, it may still be a `const fn`
         // if it resides in a const trait impl.
         is_parent_const_impl_raw(tcx, hir_id)
-    } else if let hir::Node::Ctor(_) = node {
-        true
     } else {
-        false
+        matches!(node, hir::Node::Ctor(_))
     }
 }
 
index a7012cd63f313059b270808ebea4cc8fe6d16c8d..5b4a5ac3577224722763b872f6ede27acbac6b2d 100644 (file)
@@ -138,10 +138,8 @@ fn path_generic_args(
         args: &[GenericArg<'tcx>],
     ) -> Result<Self::Path, Self::Error> {
         self = print_prefix(self)?;
-        let args = args.iter().cloned().filter(|arg| match arg.unpack() {
-            GenericArgKind::Lifetime(_) => false,
-            _ => true,
-        });
+        let args =
+            args.iter().cloned().filter(|arg| !matches!(arg.unpack(), GenericArgKind::Lifetime(_)));
         if args.clone().next().is_some() {
             self.generic_delimiters(|cx| cx.comma_sep(args))
         } else {
index 8d3544d434acf8560f81ab6b544ae1fe121e271d..00208574c555e9b77207dbb063a7041b2fba3427 100644 (file)
@@ -345,10 +345,8 @@ pub(crate) fn eval_fn_call(
 
                     // Figure out how to pass which arguments.
                     // The Rust ABI is special: ZST get skipped.
-                    let rust_abi = match caller_abi {
-                        Abi::Rust | Abi::RustCall => true,
-                        _ => false,
-                    };
+                    let rust_abi = matches!(caller_abi, Abi::Rust | Abi::RustCall);
+
                     // We have two iterators: Where the arguments come from,
                     // and where they go to.
 
index 3a5bc37b85ad6937da526276508e61b31da90e8c..3785c170f6b2b9a931f2eb93143b7c6a6cb2a953 100644 (file)
@@ -131,10 +131,7 @@ fn in_return_place(
             .body
             .basic_blocks()
             .iter_enumerated()
-            .find(|(_, block)| match block.terminator().kind {
-                TerminatorKind::Return => true,
-                _ => false,
-            })
+            .find(|(_, block)| matches!(block.terminator().kind, TerminatorKind::Return))
             .map(|(bb, _)| bb);
 
         let return_block = match return_block {
index 0fdb772c262dddbbe774fa948551a5c1a5e9e565..abc5a3c6a5206b352fe017a1f5dbef97b286d265 100644 (file)
@@ -170,11 +170,12 @@ fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, mut ty: Ty<'tcx>) -> bool {
             let mut selcx = SelectionContext::with_constness(&infcx, hir::Constness::Const);
             selcx.select(&obligation)
         });
-        match implsrc {
-            Ok(Some(ImplSource::ConstDrop(_)))
-            | Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => false,
-            _ => true,
-        }
+        !matches!(
+            implsrc,
+            Ok(Some(
+                ImplSource::ConstDrop(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
+            ))
+        )
     }
 
     fn in_adt_inherently(cx: &ConstCx<'_, 'tcx>, adt: &'tcx AdtDef, _: SubstsRef<'tcx>) -> bool {
index 38576230883cd8b87f514312c4fbab2bea021b0b..fcce829eba4121a23c0f0336cd0023ec2310b6dd 100644 (file)
@@ -94,11 +94,10 @@ fn apply_call_return_effect(
         }
     }
 
-    fn address_of_allows_mutation(&self, mt: mir::Mutability, place: mir::Place<'tcx>) -> bool {
-        match mt {
-            mir::Mutability::Mut => true,
-            mir::Mutability::Not => self.shared_borrow_allows_mutation(place),
-        }
+    fn address_of_allows_mutation(&self, _mt: mir::Mutability, _place: mir::Place<'tcx>) -> bool {
+        // Exact set of permissions granted by AddressOf is undecided. Conservatively assume that
+        // it might allow mutation until resolution of #56604.
+        true
     }
 
     fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
@@ -110,6 +109,15 @@ fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) ->
         }
     }
 
+    /// `&` only allow mutation if the borrowed place is `!Freeze`.
+    ///
+    /// This assumes that it is UB to take the address of a struct field whose type is
+    /// `Freeze`, then use pointer arithmetic to derive a pointer to a *different* field of
+    /// that same struct whose type is `!Freeze`. If we decide that this is not UB, we will
+    /// have to check the type of the borrowed **local** instead of the borrowed **place**
+    /// below. See [rust-lang/unsafe-code-guidelines#134].
+    ///
+    /// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
     fn shared_borrow_allows_mutation(&self, place: mir::Place<'tcx>) -> bool {
         !place
             .ty(self.ccx.body, self.ccx.tcx)
index 67664d2ede1dd657ca7c78ed0a5b4f72434318f5..7bf378601e053317963dcdc036129b94c05be7e3 100644 (file)
@@ -835,11 +835,7 @@ fn promote_temp(&mut self, temp: Local) -> Local {
         new_temp
     }
 
-    fn promote_candidate(
-        mut self,
-        candidate: Candidate,
-        next_promoted_id: usize,
-    ) -> Option<Body<'tcx>> {
+    fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Body<'tcx> {
         let def = self.source.source.with_opt_param();
         let mut rvalue = {
             let promoted = &mut self.promoted;
@@ -938,7 +934,7 @@ fn promote_candidate(
 
         let span = self.promoted.span;
         self.assign(RETURN_PLACE, rvalue, span);
-        Some(self.promoted)
+        self.promoted
     }
 }
 
@@ -1011,11 +1007,9 @@ pub fn promote_candidates<'tcx>(
             keep_original: false,
         };
 
-        //FIXME(oli-obk): having a `maybe_push()` method on `IndexVec` might be nice
-        if let Some(mut promoted) = promoter.promote_candidate(candidate, promotions.len()) {
-            promoted.source.promoted = Some(promotions.next_index());
-            promotions.push(promoted);
-        }
+        let mut promoted = promoter.promote_candidate(candidate, promotions.len());
+        promoted.source.promoted = Some(promotions.next_index());
+        promotions.push(promoted);
     }
 
     // Insert each of `extra_statements` before its indicated location, which
index a1ffbae8b15f6dd7d3c02264ade7a1c2faf2d24d..a3ece6550473cce4ce080bbdc5e28f15b69e1cc2 100644 (file)
@@ -34,7 +34,7 @@ pub fn new(value: T) -> Self {
     #[track_caller]
     pub fn borrow(&self) -> MappedReadGuard<'_, T> {
         let borrow = self.value.borrow();
-        if let None = &*borrow {
+        if borrow.is_none() {
             panic!("attempted to read from stolen value: {}", std::any::type_name::<T>());
         }
         ReadGuard::map(borrow, |opt| opt.as_ref().unwrap())
index 724e3f7fed3996e1aeb2638a71681fda46a5a2ca..ce26ff62235f466103df17ccdf0b1e07287460d6 100644 (file)
 E0783: include_str!("./error_codes/E0783.md"),
 E0784: include_str!("./error_codes/E0784.md"),
 E0785: include_str!("./error_codes/E0785.md"),
+E0786: include_str!("./error_codes/E0786.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
-//  E0019, merged into E0015
-//  E0035, merged into E0087/E0089
-//  E0036, merged into E0087/E0089
+//  E0019, // merged into E0015
+//  E0035, // merged into E0087/E0089
+//  E0036, // merged into E0087/E0089
 //  E0068,
 //  E0085,
 //  E0086,
 //  E0134,
 //  E0135,
 //  E0141,
-//  E0153, unused error code
-//  E0157, unused error code
+//  E0153, // unused error code
+//  E0157, // unused error code
 //  E0159, // use of trait `{}` as struct constructor
 //  E0163, // merged into E0071
 //  E0167,
            // between structures with the same definition
 //  E0385, // {} in an aliasable location
 //  E0402, // cannot use an outer type parameter in this context
-//  E0406, merged into 420
-//  E0410, merged into 408
-//  E0413, merged into 530
-//  E0414, merged into 530
-//  E0417, merged into 532
-//  E0418, merged into 532
-//  E0419, merged into 531
-//  E0420, merged into 532
-//  E0421, merged into 531
-//  E0427, merged into 530
+//  E0406, // merged into 420
+//  E0410, // merged into 408
+//  E0413, // merged into 530
+//  E0414, // merged into 530
+//  E0417, // merged into 532
+//  E0418, // merged into 532
+//  E0419, // merged into 531
+//  E0420, // merged into 532
+//  E0421, // merged into 531
+//  E0427, // merged into 530
 //  E0456, // plugin `..` is not available for triple `..`
     E0457, // plugin `..` only found in rlib format, but must be available...
     E0460, // found possibly newer version of crate `..`
     E0461, // couldn't find crate `..` with expected target triple ..
     E0462, // found staticlib `..` instead of rlib or dylib
     E0465, // multiple .. candidates for `..` found
-//  E0467, removed
-//  E0470, removed
+//  E0467, // removed
+//  E0470, // removed
 //  E0471, // constant evaluation error (in pattern)
     E0472, // llvm_asm! is unsupported on this target
 //  E0473, // dereference of reference outside its lifetime
     E0490, // a value of type `..` is borrowed for too long
     E0514, // metadata version mismatch
     E0519, // local crate and dependency have same (crate-name, disambiguator)
-    // two dependencies have same (crate-name, disambiguator) but different SVH
-    E0523,
+    E0523, // two dependencies have same (crate-name, disambiguator) but different SVH
 //  E0526, // shuffle indices are not constant
 //  E0540, // multiple rustc_deprecated attributes
 //  E0548, // replaced with a generic attribute input check
     E0711, // a feature has been declared with conflicting stability attributes
     E0717, // rustc_promotable without stability attribute
 //  E0721, // `await` keyword
-//  E0723, unstable feature in `const` context
+//  E0723, // unstable feature in `const` context
     E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
 //  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
     E0772, // `'static' obligation coming from `impl dyn Trait {}` or `impl Foo for dyn Bar {}`.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0786.md b/compiler/rustc_error_codes/src/error_codes/E0786.md
new file mode 100644 (file)
index 0000000..4a9635b
--- /dev/null
@@ -0,0 +1,14 @@
+A metadata file was invalid.
+
+Erroneous code example:
+
+```ignore (needs extern files)
+use ::foo; // error: found invalid metadata files for crate `foo`
+```
+
+When loading crates, each crate must have a valid metadata file.
+Invalid files could be caused by filesystem corruption,
+an IO error while reading the file, or (rarely) a bug in the compiler itself.
+
+Consider deleting the file and recreating it,
+or reporting a bug against the compiler.
index e17604740f0319eedad22501bae4622fc1f2bedc..e16ff9741229148c75827914ede58af494849180 100644 (file)
@@ -2063,8 +2063,26 @@ fn num_decimal_digits(num: usize) -> usize {
     MAX_DIGITS
 }
 
+// We replace some characters so the CLI output is always consistent and underlines aligned.
+const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
+    ('\t', "    "),   // We do our own tab replacement
+    ('\u{202A}', ""), // The following unicode text flow control characters are inconsistently
+    ('\u{202B}', ""), // supported accross CLIs and can cause confusion due to the bytes on disk
+    ('\u{202D}', ""), // not corresponding to the visible source code, so we replace them always.
+    ('\u{202E}', ""),
+    ('\u{2066}', ""),
+    ('\u{2067}', ""),
+    ('\u{2068}', ""),
+    ('\u{202C}', ""),
+    ('\u{2069}', ""),
+];
+
 fn replace_tabs(str: &str) -> String {
-    str.replace('\t', "    ")
+    let mut s = str.to_string();
+    for (c, replacement) in OUTPUT_REPLACEMENTS {
+        s = s.replace(*c, replacement);
+    }
+    s
 }
 
 fn draw_col_separator(buffer: &mut StyledBuffer, line: usize, col: usize) {
index 0d7a2afb6367d6b92d6dfd26d7ae3f01097342cb..941d957103c0cef98dd5e474ee99fd13caa5ba72 100644 (file)
@@ -297,6 +297,8 @@ macro_rules! declare_features {
     (accepted, macro_attributes_in_derive_output, "1.57.0", Some(81119), None),
     /// Allows panicking during const eval (producing compile-time errors).
     (accepted, const_panic, "1.57.0", Some(51999), None),
+    /// Lessens the requirements for structs to implement `Unsize`.
+    (accepted, relaxed_struct_unsize, "1.58.0", Some(81793), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
index 2bbfb561ba59461a6ea310f6417673d5c497ffc0..0266b7844ba7fce5181ef9bfef21631e058be0af 100644 (file)
@@ -101,9 +101,13 @@ pub fn set(&self, features: &mut Features, span: Span) {
     }
 }
 
+// See https://rustc-dev-guide.rust-lang.org/feature-gates.html#feature-gates for more
+// documentation about handling feature gates.
+//
 // If you change this, please modify `src/doc/unstable-book` as well.
 //
-// Don't ever remove anything from this list; move them to `removed.rs`.
+// Don't ever remove anything from this list; move them to `accepted.rs` if
+// accepted or `removed.rs` if removed.
 //
 // The version numbers here correspond to the version in which the current status
 // was set. This is most important for knowing when a particular feature became
@@ -589,9 +593,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Allows `extern "C-cmse-nonsecure-call" fn()`.
     (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None),
 
-    /// Lessens the requirements for structs to implement `Unsize`.
-    (active, relaxed_struct_unsize, "1.51.0", Some(81793), None),
-
     /// Allows associated types in inherent impls.
     (incomplete, inherent_associated_types, "1.52.0", Some(8995), None),
 
@@ -688,6 +689,18 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// not changed from prior instances of the same struct (RFC #2528)
     (incomplete, type_changing_struct_update, "1.58.0", Some(86555), None),
 
+    /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
+    (active, doc_auto_cfg, "1.58.0", Some(43781), None),
+
+    /// Allows using `const` operands in inline assembly.
+    (active, asm_const, "1.58.0", Some(72016), None),
+
+    /// Allows using `sym` operands in inline assembly.
+    (active, asm_sym, "1.58.0", Some(72016), None),
+
+    /// Enables experimental inline assembly support for additional architectures.
+    (active, asm_experimental_arch, "1.58.0", Some(72016), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
index 877871f7c3d80b69655319fe65775e97a7c79f20..39552eb9f3102afa193135fcad0722cfd7a5dfe9 100644 (file)
@@ -1,5 +1,4 @@
 use crate::def_id::{LocalDefId, CRATE_DEF_INDEX};
-use rustc_index::vec::IndexVec;
 use std::fmt;
 
 /// Uniquely identifies a node in the HIR of the current crate. It is
@@ -66,70 +65,3 @@ impl ItemLocalId {
     owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
     local_id: ItemLocalId::from_u32(0),
 };
-
-/// N.B. This collection is currently unused, but will be used by #72015 and future PRs.
-#[derive(Clone, Default, Debug, Encodable, Decodable)]
-pub struct HirIdVec<T> {
-    map: IndexVec<LocalDefId, IndexVec<ItemLocalId, T>>,
-}
-
-impl<T> HirIdVec<T> {
-    pub fn push_owner(&mut self, id: LocalDefId) {
-        self.map.ensure_contains_elem(id, IndexVec::new);
-    }
-
-    pub fn push(&mut self, id: HirId, value: T) {
-        if id.local_id == ItemLocalId::from_u32(0) {
-            self.push_owner(id.owner);
-        }
-        let submap = &mut self.map[id.owner];
-        let _ret_id = submap.push(value);
-        debug_assert_eq!(_ret_id, id.local_id);
-    }
-
-    pub fn push_sparse(&mut self, id: HirId, value: T)
-    where
-        T: Default,
-    {
-        self.map.ensure_contains_elem(id.owner, IndexVec::new);
-        let submap = &mut self.map[id.owner];
-        let i = id.local_id.index();
-        let len = submap.len();
-        if i >= len {
-            submap.extend(std::iter::repeat_with(T::default).take(i - len + 1));
-        }
-        submap[id.local_id] = value;
-    }
-
-    pub fn get(&self, id: HirId) -> Option<&T> {
-        self.map.get(id.owner)?.get(id.local_id)
-    }
-
-    pub fn get_owner(&self, id: LocalDefId) -> &IndexVec<ItemLocalId, T> {
-        &self.map[id]
-    }
-
-    pub fn iter(&self) -> impl Iterator<Item = &T> {
-        self.map.iter().flat_map(|la| la.iter())
-    }
-
-    pub fn iter_enumerated(&self) -> impl Iterator<Item = (HirId, &T)> {
-        self.map.iter_enumerated().flat_map(|(owner, la)| {
-            la.iter_enumerated().map(move |(local_id, attr)| (HirId { owner, local_id }, attr))
-        })
-    }
-}
-
-impl<T> std::ops::Index<HirId> for HirIdVec<T> {
-    type Output = T;
-
-    fn index(&self, id: HirId) -> &T {
-        &self.map[id.owner][id.local_id]
-    }
-}
-
-impl<T> std::ops::IndexMut<HirId> for HirIdVec<T> {
-    fn index_mut(&mut self, id: HirId) -> &mut T {
-        &mut self.map[id.owner][id.local_id]
-    }
-}
index 97d4123138e8fa846e6255feec3545b3bcfd3da0..3037996d48bc03bb8e1a0ca1cc4847b53c7d082f 100644 (file)
@@ -281,12 +281,12 @@ pub fn extract<'a, F>(check_name: F, attrs: &'a [ast::Attribute]) -> Option<(Sym
     // in the sense that a crate is not required to have it defined to use it, but a final product
     // is required to define it somewhere. Additionally, there are restrictions on crates that use
     // a weak lang item, but do not have it defined.
-    Panic,                   sym::panic,               panic_fn,                   Target::Fn,             GenericRequirement::None;
+    Panic,                   sym::panic,               panic_fn,                   Target::Fn,             GenericRequirement::Exact(0);
     PanicFmt,                sym::panic_fmt,           panic_fmt,                  Target::Fn,             GenericRequirement::None;
     PanicDisplay,            sym::panic_display,       panic_display,              Target::Fn,             GenericRequirement::None;
     PanicStr,                sym::panic_str,           panic_str,                  Target::Fn,             GenericRequirement::None;
     ConstPanicFmt,           sym::const_panic_fmt,     const_panic_fmt,            Target::Fn,             GenericRequirement::None;
-    PanicBoundsCheck,        sym::panic_bounds_check,  panic_bounds_check_fn,      Target::Fn,             GenericRequirement::None;
+    PanicBoundsCheck,        sym::panic_bounds_check,  panic_bounds_check_fn,      Target::Fn,             GenericRequirement::Exact(0);
     PanicInfo,               sym::panic_info,          panic_info,                 Target::Struct,         GenericRequirement::None;
     PanicLocation,           sym::panic_location,      panic_location,             Target::Struct,         GenericRequirement::None;
     PanicImpl,               sym::panic_impl,          panic_impl,                 Target::Fn,             GenericRequirement::None;
index 2173ff1f9ab035823c013e08abc3d757ea9602d3..8849d623b2dad2b7273e2d2525fc4f4973f14e5c 100644 (file)
@@ -1466,7 +1466,7 @@ fn add_labels_for_types(
                     let mut returned_async_output_error = false;
                     for &sp in values {
                         if sp.is_desugaring(DesugaringKind::Async) && !returned_async_output_error {
-                            if &[sp] != err.span.primary_spans() {
+                            if [sp] != err.span.primary_spans() {
                                 let mut span: MultiSpan = sp.into();
                                 span.push_span_label(
                                     sp,
index 1b35c4032f44c5d14e3fe30e935deb79a7dc4a64..ac57796763fb3cf30082f085707e5428cdd6785e 100644 (file)
@@ -7,7 +7,10 @@
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::infer::SubregionOrigin;
 
-use rustc_errors::{struct_span_err, ErrorReported};
+use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
+use rustc_hir as hir;
+use rustc_hir::{GenericParamKind, Ty};
+use rustc_middle::ty::Region;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when both the concerned regions are anonymous.
@@ -160,11 +163,13 @@ pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> {
                 }
             };
 
-        let mut e = struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch");
+        let mut err = struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch");
 
-        e.span_label(span_1, main_label);
-        e.span_label(span_2, String::new());
-        e.span_label(span, span_label);
+        err.span_label(span_1, main_label);
+        err.span_label(span_2, String::new());
+        err.span_label(span, span_label);
+
+        self.suggest_adding_lifetime_params(sub, ty_sup, ty_sub, &mut err);
 
         if let Some(t) = future_return_type {
             let snip = self
@@ -178,14 +183,87 @@ pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> {
                     (_, "") => None,
                     _ => Some(s),
                 })
-                .unwrap_or("{unnamed_type}".to_string());
+                .unwrap_or_else(|| "{unnamed_type}".to_string());
 
-            e.span_label(
+            err.span_label(
                 t.span,
                 &format!("this `async fn` implicitly returns an `impl Future<Output = {}>`", snip),
             );
         }
-        e.emit();
+        err.emit();
         Some(ErrorReported)
     }
+
+    fn suggest_adding_lifetime_params(
+        &self,
+        sub: Region<'tcx>,
+        ty_sup: &Ty<'_>,
+        ty_sub: &Ty<'_>,
+        err: &mut DiagnosticBuilder<'_>,
+    ) {
+        if let (
+            hir::Ty { kind: hir::TyKind::Rptr(lifetime_sub, _), .. },
+            hir::Ty { kind: hir::TyKind::Rptr(lifetime_sup, _), .. },
+        ) = (ty_sub, ty_sup)
+        {
+            if lifetime_sub.name.is_elided() && lifetime_sup.name.is_elided() {
+                if let Some(anon_reg) = self.tcx().is_suitable_region(sub) {
+                    let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id);
+                    if let hir::Node::Item(&hir::Item {
+                        kind: hir::ItemKind::Fn(_, ref generics, ..),
+                        ..
+                    }) = self.tcx().hir().get(hir_id)
+                    {
+                        let (suggestion_param_name, introduce_new) = generics
+                            .params
+                            .iter()
+                            .find(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
+                            .and_then(|p| self.tcx().sess.source_map().span_to_snippet(p.span).ok())
+                            .map(|name| (name, false))
+                            .unwrap_or_else(|| ("'a".to_string(), true));
+
+                        let mut suggestions = vec![
+                            if let hir::LifetimeName::Underscore = lifetime_sub.name {
+                                (lifetime_sub.span, suggestion_param_name.clone())
+                            } else {
+                                (
+                                    lifetime_sub.span.shrink_to_hi(),
+                                    suggestion_param_name.clone() + " ",
+                                )
+                            },
+                            if let hir::LifetimeName::Underscore = lifetime_sup.name {
+                                (lifetime_sup.span, suggestion_param_name.clone())
+                            } else {
+                                (
+                                    lifetime_sup.span.shrink_to_hi(),
+                                    suggestion_param_name.clone() + " ",
+                                )
+                            },
+                        ];
+
+                        if introduce_new {
+                            let new_param_suggestion = match &generics.params {
+                                [] => (generics.span, format!("<{}>", suggestion_param_name)),
+                                [first, ..] => (
+                                    first.span.shrink_to_lo(),
+                                    format!("{}, ", suggestion_param_name),
+                                ),
+                            };
+
+                            suggestions.push(new_param_suggestion);
+                        }
+
+                        err.multipart_suggestion(
+                            "consider introducing a named lifetime parameter",
+                            suggestions,
+                            Applicability::MaybeIncorrect,
+                        );
+                        err.note(
+                            "each elided lifetime in input position becomes a distinct lifetime",
+                        );
+                    }
+                }
+            }
+        }
+    }
 }
index 6b905f67e683f900b53ed0e9ca99dba49342161a..9dae978dcde7d9b79dd59c74335b6d2529a0684c 100644 (file)
@@ -1252,16 +1252,16 @@ pub fn set_tainted_by_errors(&self) {
         self.tainted_by_errors_flag.set(true)
     }
 
-    /// Process the region constraints and report any errors that
+    /// Process the region constraints and return any any errors that
     /// result. After this, no more unification operations should be
     /// done -- or the compiler will panic -- but it is legal to use
     /// `resolve_vars_if_possible` as well as `fully_resolve`.
-    pub fn resolve_regions_and_report_errors(
+    pub fn resolve_regions(
         &self,
         region_context: DefId,
         outlives_env: &OutlivesEnvironment<'tcx>,
         mode: RegionckMode,
-    ) {
+    ) -> Vec<RegionResolutionError<'tcx>> {
         let (var_infos, data) = {
             let mut inner = self.inner.borrow_mut();
             let inner = &mut *inner;
@@ -1287,6 +1287,21 @@ pub fn resolve_regions_and_report_errors(
         let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
         assert!(old_value.is_none());
 
+        errors
+    }
+
+    /// Process the region constraints and report any errors that
+    /// result. After this, no more unification operations should be
+    /// done -- or the compiler will panic -- but it is legal to use
+    /// `resolve_vars_if_possible` as well as `fully_resolve`.
+    pub fn resolve_regions_and_report_errors(
+        &self,
+        region_context: DefId,
+        outlives_env: &OutlivesEnvironment<'tcx>,
+        mode: RegionckMode,
+    ) {
+        let errors = self.resolve_regions(region_context, outlives_env, mode);
+
         if !self.is_tainted_by_errors() {
             // As a heuristic, just skip reporting region errors
             // altogether if other errors have been reported while
index 62f5f09aa48279a7a1eed4031bd3c858cc11f42d..3f6e879e6e44b778ef2576debe9424308d4be975 100644 (file)
@@ -47,7 +47,7 @@
 use std::io::{self, BufWriter, Write};
 use std::lazy::SyncLazy;
 use std::marker::PhantomPinned;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::pin::Pin;
 use std::rc::Rc;
 use std::{env, fs, iter};
@@ -536,7 +536,7 @@ fn check_output<F, T>(output_paths: &[PathBuf], f: F) -> Option<T>
     None
 }
 
-fn output_contains_path(output_paths: &[PathBuf], input_path: &PathBuf) -> bool {
+fn output_contains_path(output_paths: &[PathBuf], input_path: &Path) -> bool {
     let input_path = input_path.canonicalize().ok();
     if input_path.is_none() {
         return false;
@@ -552,7 +552,7 @@ fn output_conflicts_with_dir(output_paths: &[PathBuf]) -> Option<PathBuf> {
     check_output(output_paths, check)
 }
 
-fn escape_dep_filename(filename: &String) -> String {
+fn escape_dep_filename(filename: &str) -> String {
     // Apparently clang and gcc *only* escape spaces:
     // https://llvm.org/klaus/clang/commit/9d50634cfc268ecc9a7250226dd5ca0e945240d4
     filename.replace(" ", "\\ ")
index cffb087af187f9be0d080b798b90b08dd8e93bba..946502378732a55dc2b373ae1cbcc06a715b41e9 100644 (file)
@@ -776,7 +776,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
     fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
         let is_const = match i {
             ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
-            ast::ItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) => Self::is_sig_const(sig),
+            ast::ItemKind::Fn(box ast::Fn { ref sig, .. }) => Self::is_sig_const(sig),
             _ => false,
         };
         self.run(is_const, |s| noop_visit_item_kind(i, s))
@@ -785,7 +785,7 @@ fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
     fn flat_map_trait_item(&mut self, i: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
         let is_const = match i.kind {
             ast::AssocItemKind::Const(..) => true,
-            ast::AssocItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) => Self::is_sig_const(sig),
+            ast::AssocItemKind::Fn(box ast::Fn { ref sig, .. }) => Self::is_sig_const(sig),
             _ => false,
         };
         self.run(is_const, |s| noop_flat_map_assoc_item(i, s))
index b970c9e4911fafb36ff0612c0e30fb417d46437f..d789237e692d2beea5f514ee6f41b89080674be4 100644 (file)
@@ -68,11 +68,10 @@ pub enum EscapeError {
 impl EscapeError {
     /// Returns true for actual errors, as opposed to warnings.
     pub fn is_fatal(&self) -> bool {
-        match self {
-            EscapeError::UnskippedWhitespaceWarning => false,
-            EscapeError::MultipleSkippedLinesWarning => false,
-            _ => true,
-        }
+        !matches!(
+            self,
+            EscapeError::UnskippedWhitespaceWarning | EscapeError::MultipleSkippedLinesWarning
+        )
     }
 }
 
index c228ecb03fdec25f1d475fd9d9a2ef63ce0c6f0e..6548cdc0fdc52686e510fdd6b773371ab3377677 100644 (file)
@@ -369,12 +369,12 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
 
     fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
         match it.kind {
-            ast::ItemKind::Trait(box ast::TraitKind(_, ast::Unsafe::Yes(_), ..)) => self
+            ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => self
                 .report_unsafe(cx, it.span, |lint| {
                     lint.build("declaration of an `unsafe` trait").emit()
                 }),
 
-            ast::ItemKind::Impl(box ast::ImplKind { unsafety: ast::Unsafe::Yes(_), .. }) => self
+            ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => self
                 .report_unsafe(cx, it.span, |lint| {
                     lint.build("implementation of an `unsafe` trait").emit()
                 }),
@@ -921,7 +921,7 @@ fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
             // This is a hard error in future editions; avoid linting and erroring
             return;
         }
-        if let ast::AssocItemKind::Fn(box FnKind(_, ref sig, _, _)) = it.kind {
+        if let ast::AssocItemKind::Fn(box Fn { ref sig, .. }) = it.kind {
             for arg in sig.decl.inputs.iter() {
                 if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind {
                     if ident.name == kw::Empty {
@@ -3130,18 +3130,13 @@ fn is_zero(expr: &hir::Expr<'_>) -> bool {
             false
         }
 
-        if let rustc_hir::ExprKind::Unary(ref un_op, ref expr_deref) = expr.kind {
-            if let rustc_hir::UnOp::Deref = un_op {
-                if is_null_ptr(cx, expr_deref) {
-                    cx.struct_span_lint(DEREF_NULLPTR, expr.span, |lint| {
-                        let mut err = lint.build("dereferencing a null pointer");
-                        err.span_label(
-                            expr.span,
-                            "this code causes undefined behavior when executed",
-                        );
-                        err.emit();
-                    });
-                }
+        if let rustc_hir::ExprKind::Unary(rustc_hir::UnOp::Deref, expr_deref) = expr.kind {
+            if is_null_ptr(cx, expr_deref) {
+                cx.struct_span_lint(DEREF_NULLPTR, expr.span, |lint| {
+                    let mut err = lint.build("dereferencing a null pointer");
+                    err.span_label(expr.span, "this code causes undefined behavior when executed");
+                    err.emit();
+                });
             }
         }
     }
@@ -3196,7 +3191,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
                         let snippet = template_snippet.as_str();
                         if let Some(pos) = snippet.find(needle) {
                             let end = pos
-                                + &snippet[pos..]
+                                + snippet[pos..]
                                     .find(|c| c == ':')
                                     .unwrap_or(snippet[pos..].len() - 1);
                             let inner = InnerSpan::new(pos, end);
index d235b2209444eb8bd7dfb7e6896d416e95597499..4c936dec6f2cd3a72af9c3ca199a98708768009b 100644 (file)
@@ -18,6 +18,7 @@
 
 use crate::levels::{is_known_lint_tool, LintLevelsBuilder};
 use crate::passes::{EarlyLintPassObject, LateLintPassObject};
+use ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync;
@@ -39,7 +40,7 @@
 use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
 use rustc_session::Session;
 use rustc_span::lev_distance::find_best_match_for_name;
-use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
+use rustc_span::{symbol::Symbol, BytePos, MultiSpan, Span, DUMMY_SP};
 use rustc_target::abi;
 use tracing::debug;
 
@@ -597,6 +598,42 @@ fn lookup_with_diagnostics(
             // Now, set up surrounding context.
             let sess = self.sess();
             match diagnostic {
+                BuiltinLintDiagnostics::UnicodeTextFlow(span, content) => {
+                    let spans: Vec<_> = content
+                        .char_indices()
+                        .filter_map(|(i, c)| {
+                            TEXT_FLOW_CONTROL_CHARS.contains(&c).then(|| {
+                                let lo = span.lo() + BytePos(2 + i as u32);
+                                (c, span.with_lo(lo).with_hi(lo + BytePos(c.len_utf8() as u32)))
+                            })
+                        })
+                        .collect();
+                    let (an, s) = match spans.len() {
+                        1 => ("an ", ""),
+                        _ => ("", "s"),
+                    };
+                    db.span_label(span, &format!(
+                        "this comment contains {}invisible unicode text flow control codepoint{}",
+                        an,
+                        s,
+                    ));
+                    for (c, span) in &spans {
+                        db.span_label(*span, format!("{:?}", c));
+                    }
+                    db.note(
+                        "these kind of unicode codepoints change the way text flows on \
+                         applications that support them, but can cause confusion because they \
+                         change the order of characters on the screen",
+                    );
+                    if !spans.is_empty() {
+                        db.multipart_suggestion_with_style(
+                            "if their presence wasn't intentional, you can remove them",
+                            spans.into_iter().map(|(_, span)| (span, "".to_string())).collect(),
+                            Applicability::MachineApplicable,
+                            SuggestionStyle::HideCodeAlways,
+                        );
+                    }
+                },
                 BuiltinLintDiagnostics::Normal => (),
                 BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
                     let (sugg, app) = match sess.source_map().span_to_snippet(span) {
diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
new file mode 100644 (file)
index 0000000..fde84be
--- /dev/null
@@ -0,0 +1,157 @@
+use crate::{EarlyContext, EarlyLintPass, LintContext};
+use ast::util::unicode::{contains_text_flow_control_chars, TEXT_FLOW_CONTROL_CHARS};
+use rustc_ast as ast;
+use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_span::{BytePos, Span, Symbol};
+
+declare_lint! {
+    /// The `text_direction_codepoint_in_literal` lint detects Unicode codepoints that change the
+    /// visual representation of text on screen in a way that does not correspond to their on
+    /// memory representation.
+    ///
+    /// ### Explanation
+    ///
+    /// The unicode characters `\u{202A}`, `\u{202B}`, `\u{202D}`, `\u{202E}`, `\u{2066}`,
+    /// `\u{2067}`, `\u{2068}`, `\u{202C}` and `\u{2069}` make the flow of text on screen change
+    /// its direction on software that supports these codepoints. This makes the text "abc" display
+    /// as "cba" on screen. By leveraging software that supports these, people can write specially
+    /// crafted literals that make the surrounding code seem like it's performing one action, when
+    /// in reality it is performing another. Because of this, we proactively lint against their
+    /// presence to avoid surprises.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(text_direction_codepoint_in_literal)]
+    /// fn main() {
+    ///     println!("{:?}", '‮');
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    pub TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
+    Deny,
+    "detect special Unicode codepoints that affect the visual representation of text on screen, \
+     changing the direction in which text flows",
+}
+
+declare_lint_pass!(HiddenUnicodeCodepoints => [TEXT_DIRECTION_CODEPOINT_IN_LITERAL]);
+
+impl HiddenUnicodeCodepoints {
+    fn lint_text_direction_codepoint(
+        &self,
+        cx: &EarlyContext<'_>,
+        text: Symbol,
+        span: Span,
+        padding: u32,
+        point_at_inner_spans: bool,
+        label: &str,
+    ) {
+        // Obtain the `Span`s for each of the forbidden chars.
+        let spans: Vec<_> = text
+            .as_str()
+            .char_indices()
+            .filter_map(|(i, c)| {
+                TEXT_FLOW_CONTROL_CHARS.contains(&c).then(|| {
+                    let lo = span.lo() + BytePos(i as u32 + padding);
+                    (c, span.with_lo(lo).with_hi(lo + BytePos(c.len_utf8() as u32)))
+                })
+            })
+            .collect();
+
+        cx.struct_span_lint(TEXT_DIRECTION_CODEPOINT_IN_LITERAL, span, |lint| {
+            let mut err = lint.build(&format!(
+                "unicode codepoint changing visible direction of text present in {}",
+                label
+            ));
+            let (an, s) = match spans.len() {
+                1 => ("an ", ""),
+                _ => ("", "s"),
+            };
+            err.span_label(
+                span,
+                &format!(
+                    "this {} contains {}invisible unicode text flow control codepoint{}",
+                    label, an, s,
+                ),
+            );
+            if point_at_inner_spans {
+                for (c, span) in &spans {
+                    err.span_label(*span, format!("{:?}", c));
+                }
+            }
+            err.note(
+                "these kind of unicode codepoints change the way text flows on applications that \
+                 support them, but can cause confusion because they change the order of \
+                 characters on the screen",
+            );
+            if point_at_inner_spans && !spans.is_empty() {
+                err.multipart_suggestion_with_style(
+                    "if their presence wasn't intentional, you can remove them",
+                    spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
+                    Applicability::MachineApplicable,
+                    SuggestionStyle::HideCodeAlways,
+                );
+                err.multipart_suggestion(
+                    "if you want to keep them but make them visible in your source code, you can \
+                    escape them",
+                    spans
+                        .into_iter()
+                        .map(|(c, span)| {
+                            let c = format!("{:?}", c);
+                            (span, c[1..c.len() - 1].to_string())
+                        })
+                        .collect(),
+                    Applicability::MachineApplicable,
+                );
+            } else {
+                // FIXME: in other suggestions we've reversed the inner spans of doc comments. We
+                // should do the same here to provide the same good suggestions as we do for
+                // literals above.
+                err.note("if their presence wasn't intentional, you can remove them");
+                err.note(&format!(
+                    "if you want to keep them but make them visible in your source code, you can \
+                     escape them: {}",
+                    spans
+                        .into_iter()
+                        .map(|(c, _)| { format!("{:?}", c) })
+                        .collect::<Vec<String>>()
+                        .join(", "),
+                ));
+            }
+            err.emit();
+        });
+    }
+}
+impl EarlyLintPass for HiddenUnicodeCodepoints {
+    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
+        if let ast::AttrKind::DocComment(_, comment) = attr.kind {
+            if contains_text_flow_control_chars(&comment.as_str()) {
+                self.lint_text_direction_codepoint(cx, comment, attr.span, 0, false, "doc comment");
+            }
+        }
+    }
+
+    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
+        // byte strings are already handled well enough by `EscapeError::NonAsciiCharInByteString`
+        let (text, span, padding) = match &expr.kind {
+            ast::ExprKind::Lit(ast::Lit { token, kind, span }) => {
+                let text = token.symbol;
+                if !contains_text_flow_control_chars(&text.as_str()) {
+                    return;
+                }
+                let padding = match kind {
+                    // account for `"` or `'`
+                    ast::LitKind::Str(_, ast::StrStyle::Cooked) | ast::LitKind::Char(_) => 1,
+                    // account for `r###"`
+                    ast::LitKind::Str(_, ast::StrStyle::Raw(val)) => *val as u32 + 2,
+                    _ => return,
+                };
+                (text, span, padding)
+            }
+            _ => return,
+        };
+        self.lint_text_direction_codepoint(cx, text, *span, padding, true, "literal");
+    }
+}
index 50a0d211a366a913613ea622df502554413c00bd..c64a67b6b9f1b5c38dbc774948c62c0078930ed7 100644 (file)
@@ -101,33 +101,31 @@ fn check_path(&mut self, cx: &LateContext<'_>, path: &'tcx Path<'tcx>, _: HirId)
 
     fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx Ty<'tcx>) {
         match &ty.kind {
-            TyKind::Path(qpath) => {
-                if let QPath::Resolved(_, path) = qpath {
-                    if let Some(last) = path.segments.iter().last() {
-                        if lint_ty_kind_usage(cx, last) {
-                            cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, |lint| {
-                                lint.build("usage of `ty::TyKind`")
-                                    .help("try using `Ty` instead")
-                                    .emit();
-                            })
-                        } else {
-                            if ty.span.from_expansion() {
-                                return;
-                            }
-                            if let Some(t) = is_ty_or_ty_ctxt(cx, ty) {
-                                if path.segments.len() > 1 {
-                                    cx.struct_span_lint(USAGE_OF_QUALIFIED_TY, path.span, |lint| {
-                                        lint.build(&format!("usage of qualified `ty::{}`", t))
-                                            .span_suggestion(
-                                                path.span,
-                                                "try using it unqualified",
-                                                t,
-                                                // The import probably needs to be changed
-                                                Applicability::MaybeIncorrect,
-                                            )
-                                            .emit();
-                                    })
-                                }
+            TyKind::Path(QPath::Resolved(_, path)) => {
+                if let Some(last) = path.segments.iter().last() {
+                    if lint_ty_kind_usage(cx, last) {
+                        cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, |lint| {
+                            lint.build("usage of `ty::TyKind`")
+                                .help("try using `Ty` instead")
+                                .emit();
+                        })
+                    } else {
+                        if ty.span.from_expansion() {
+                            return;
+                        }
+                        if let Some(t) = is_ty_or_ty_ctxt(cx, ty) {
+                            if path.segments.len() > 1 {
+                                cx.struct_span_lint(USAGE_OF_QUALIFIED_TY, path.span, |lint| {
+                                    lint.build(&format!("usage of qualified `ty::{}`", t))
+                                        .span_suggestion(
+                                            path.span,
+                                            "try using it unqualified",
+                                            t,
+                                            // The import probably needs to be changed
+                                            Applicability::MaybeIncorrect,
+                                        )
+                                        .emit();
+                                })
                             }
                         }
                     }
@@ -169,37 +167,30 @@ fn lint_ty_kind_usage(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> bool {
 }
 
 fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, ty: &Ty<'_>) -> Option<String> {
-    if let TyKind::Path(qpath) = &ty.kind {
-        if let QPath::Resolved(_, path) = qpath {
-            match path.res {
-                Res::Def(_, def_id) => {
-                    if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(def_id)
-                    {
-                        return Some(format!(
-                            "{}{}",
-                            name,
-                            gen_args(path.segments.last().unwrap())
-                        ));
-                    }
+    if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind {
+        match path.res {
+            Res::Def(_, def_id) => {
+                if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(def_id) {
+                    return Some(format!("{}{}", name, gen_args(path.segments.last().unwrap())));
                 }
-                // Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
-                Res::SelfTy(None, Some((did, _))) => {
-                    if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
-                        if let Some(name @ (sym::Ty | sym::TyCtxt)) =
-                            cx.tcx.get_diagnostic_name(adt.did)
-                        {
-                            // NOTE: This path is currently unreachable as `Ty<'tcx>` is
-                            // defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`
-                            // is not actually allowed.
-                            //
-                            // I(@lcnr) still kept this branch in so we don't miss this
-                            // if we ever change it in the future.
-                            return Some(format!("{}<{}>", name, substs[0]));
-                        }
+            }
+            // Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
+            Res::SelfTy(None, Some((did, _))) => {
+                if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
+                    if let Some(name @ (sym::Ty | sym::TyCtxt)) =
+                        cx.tcx.get_diagnostic_name(adt.did)
+                    {
+                        // NOTE: This path is currently unreachable as `Ty<'tcx>` is
+                        // defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`
+                        // is not actually allowed.
+                        //
+                        // I(@lcnr) still kept this branch in so we don't miss this
+                        // if we ever change it in the future.
+                        return Some(format!("{}<{}>", name, substs[0]));
                     }
                 }
-                _ => (),
             }
+            _ => (),
         }
     }
 
@@ -238,8 +229,7 @@ fn gen_args(segment: &PathSegment<'_>) -> String {
 
 impl EarlyLintPass for LintPassImpl {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
-        if let ast::ItemKind::Impl(box ast::ImplKind { of_trait: Some(lint_pass), .. }) = &item.kind
-        {
+        if let ast::ItemKind::Impl(box ast::Impl { of_trait: Some(lint_pass), .. }) = &item.kind {
             if let Some(last) = lint_pass.path.segments.last() {
                 if last.ident.name == sym::LintPass {
                     let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
index 6f684a0fe5128658eaaa61dd955d505b5d80b24f..f6514ddca9f57c26bf54647f7e1485520c5c237c 100644 (file)
@@ -48,6 +48,7 @@
 mod context;
 mod early;
 mod enum_intrinsics_non_enums;
+pub mod hidden_unicode_codepoints;
 mod internal;
 mod late;
 mod levels;
@@ -78,6 +79,7 @@
 use array_into_iter::ArrayIntoIter;
 use builtin::*;
 use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
+use hidden_unicode_codepoints::*;
 use internal::*;
 use methods::*;
 use non_ascii_idents::*;
@@ -129,6 +131,7 @@ macro_rules! early_lint_passes {
                 DeprecatedAttr: DeprecatedAttr::new(),
                 WhileTrue: WhileTrue,
                 NonAsciiIdents: NonAsciiIdents,
+                HiddenUnicodeCodepoints: HiddenUnicodeCodepoints,
                 IncompleteFeatures: IncompleteFeatures,
                 RedundantSemicolons: RedundantSemicolons,
                 UnusedDocComment: UnusedDocComment,
@@ -300,7 +303,6 @@ macro_rules! register_passes {
         UNUSED_LABELS,
         UNUSED_PARENS,
         UNUSED_BRACES,
-        MUST_NOT_SUSPEND,
         REDUNDANT_SEMICOLONS
     );
 
index f35ca2659fd65661eae69ac75c8aa58e4f886729..c1a53c34b7a244d27cfbcdb8bc8289108b5debf4 100644 (file)
     ///
     /// ```rust
     /// #![feature(must_not_suspend)]
+    /// #![warn(must_not_suspend)]
     ///
     /// #[must_not_suspend]
     /// struct SyncThing {}
     /// `MutexGuard`'s)
     ///
     pub MUST_NOT_SUSPEND,
-    Warn,
+    Allow,
     "use of a `#[must_not_suspend]` value across a yield point",
+    @feature_gate = rustc_span::symbol::sym::must_not_suspend;
 }
 
 declare_lint! {
         BREAK_WITH_LABEL_AND_LOOP,
         UNUSED_ATTRIBUTES,
         NON_EXHAUSTIVE_OMITTED_PATTERNS,
+        TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
         DEREF_INTO_DYN_SUPERTRAIT,
     ]
 }
     @feature_gate = sym::non_exhaustive_omitted_patterns_lint;
 }
 
+declare_lint! {
+    /// The `text_direction_codepoint_in_comment` lint detects Unicode codepoints in comments that
+    /// change the visual representation of text on screen in a way that does not correspond to
+    /// their on memory representation.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(text_direction_codepoint_in_comment)]
+    /// fn main() {
+    ///     println!("{:?}"); // '‮');
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Unicode allows changing the visual flow of text on screen in order to support scripts that
+    /// are written right-to-left, but a specially crafted comment can make code that will be
+    /// compiled appear to be part of a comment, depending on the software used to read the code.
+    /// To avoid potential problems or confusion, such as in CVE-2021-42574, by default we deny
+    /// their use.
+    pub TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
+    Deny,
+    "invisible directionality-changing codepoints in comment"
+}
+
 declare_lint! {
     /// The `deref_into_dyn_supertrait` lint is output whenever there is a use of the
     /// `Deref` implementation with a `dyn SuperTrait` type as `Output`.
index f89d531b5ef5ceb8e403004c874d0c469d681cb8..feac2a7cfa48a77a8b0c88c296f5f584023478ab 100644 (file)
@@ -306,6 +306,7 @@ pub enum BuiltinLintDiagnostics {
     TrailingMacro(bool, Ident),
     BreakWithLabelAndLoop(Span),
     NamedAsmLabel(String),
+    UnicodeTextFlow(Span, String),
 }
 
 /// Lints that are buffered up early on in the `Session` before the
index 32b866e81b131eca15e114368170038fa9d8e0e1..ddbc3c5912836f1f8a9b3525c6045d9715fbca41 100644 (file)
@@ -75,6 +75,10 @@ extern "C" void LLVMTimeTraceProfilerInitialize() {
       /* ProcName */ "rustc");
 }
 
+extern "C" void LLVMTimeTraceProfilerFinishThread() {
+  timeTraceProfilerFinishThread();
+}
+
 extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
   StringRef FN(FileName);
   std::error_code EC;
index dba885a27fe229f3c73176568cb4891135acf097..63bdcea87f8170a97df6b45df4f8bc8d8032e910 100644 (file)
@@ -24,11 +24,9 @@ fn parse_attributes(field: &syn::Field) -> Attributes {
                         }
                         if meta.path().is_ident("project") {
                             if let Meta::List(list) = meta {
-                                if let Some(nested) = list.nested.iter().next() {
-                                    if let NestedMeta::Meta(meta) = nested {
-                                        attrs.project = meta.path().get_ident().cloned();
-                                        any_attr = true;
-                                    }
+                                if let Some(NestedMeta::Meta(meta)) = list.nested.iter().next() {
+                                    attrs.project = meta.path().get_ident().cloned();
+                                    any_attr = true;
                                 }
                             }
                         }
index 95b74fd5306e54c75117f8508669406ca8488873..eb0a693226c480d51c91311cd63ddcc5bd1cfd76 100644 (file)
@@ -29,6 +29,7 @@
 
 use proc_macro::bridge::client::ProcMacro;
 use std::collections::BTreeMap;
+use std::ops::Fn;
 use std::path::Path;
 use std::{cmp, env};
 use tracing::{debug, info};
index bbd30c9327a6c3d501b5cf0720dc28e62cda7d91..7cba16e0a9ae38d9333afc16d1dc1b0b65699dfc 100644 (file)
 use std::io::{Read, Result as IoResult, Write};
 use std::path::{Path, PathBuf};
 use std::{cmp, fmt, fs};
-use tracing::{debug, info, warn};
+use tracing::{debug, info};
 
 #[derive(Clone)]
 crate struct CrateLocator<'a> {
@@ -350,6 +350,7 @@ impl<'a> CrateLocator<'a> {
         self.crate_rejections.via_kind.clear();
         self.crate_rejections.via_version.clear();
         self.crate_rejections.via_filename.clear();
+        self.crate_rejections.via_invalid.clear();
     }
 
     crate fn maybe_load_library_crate(&mut self) -> Result<Option<Library>, CrateError> {
@@ -548,8 +549,18 @@ fn extract_one(
                             continue;
                         }
                     }
-                    Err(err) => {
-                        warn!("no metadata found: {}", err);
+                    Err(MetadataError::LoadFailure(err)) => {
+                        info!("no metadata found: {}", err);
+                        // The file was present and created by the same compiler version, but we
+                        // couldn't load it for some reason.  Give a hard error instead of silently
+                        // ignoring it, but only if we would have given an error anyway.
+                        self.crate_rejections
+                            .via_invalid
+                            .push(CrateMismatch { path: lib, got: err });
+                        continue;
+                    }
+                    Err(err @ MetadataError::NotPresent(_)) => {
+                        info!("no metadata found: {}", err);
                         continue;
                     }
                 };
@@ -726,25 +737,28 @@ fn find_commandline_library(&mut self) -> Result<Option<Library>, CrateError> {
 fn get_metadata_section(
     target: &Target,
     flavor: CrateFlavor,
-    filename: &Path,
+    filename: &'p Path,
     loader: &dyn MetadataLoader,
-) -> Result<MetadataBlob, String> {
+) -> Result<MetadataBlob, MetadataError<'p>> {
     if !filename.exists() {
-        return Err(format!("no such file: '{}'", filename.display()));
+        return Err(MetadataError::NotPresent(filename));
     }
     let raw_bytes: MetadataRef = match flavor {
-        CrateFlavor::Rlib => loader.get_rlib_metadata(target, filename)?,
+        CrateFlavor::Rlib => {
+            loader.get_rlib_metadata(target, filename).map_err(MetadataError::LoadFailure)?
+        }
         CrateFlavor::Dylib => {
-            let buf = loader.get_dylib_metadata(target, filename)?;
+            let buf =
+                loader.get_dylib_metadata(target, filename).map_err(MetadataError::LoadFailure)?;
             // The header is uncompressed
             let header_len = METADATA_HEADER.len();
             debug!("checking {} bytes of metadata-version stamp", header_len);
             let header = &buf[..cmp::min(header_len, buf.len())];
             if header != METADATA_HEADER {
-                return Err(format!(
-                    "incompatible metadata version found: '{}'",
+                return Err(MetadataError::LoadFailure(format!(
+                    "invalid metadata version found: {}",
                     filename.display()
-                ));
+                )));
             }
 
             // Header is okay -> inflate the actual metadata
@@ -756,17 +770,28 @@ fn get_metadata_section(
             match FrameDecoder::new(compressed_bytes).read_to_end(&mut inflated) {
                 Ok(_) => rustc_erase_owner!(OwningRef::new(inflated).map_owner_box()),
                 Err(_) => {
-                    return Err(format!("failed to decompress metadata: {}", filename.display()));
+                    return Err(MetadataError::LoadFailure(format!(
+                        "failed to decompress metadata: {}",
+                        filename.display()
+                    )));
                 }
             }
         }
         CrateFlavor::Rmeta => {
             // mmap the file, because only a small fraction of it is read.
-            let file = std::fs::File::open(filename)
-                .map_err(|_| format!("failed to open rmeta metadata: '{}'", filename.display()))?;
+            let file = std::fs::File::open(filename).map_err(|_| {
+                MetadataError::LoadFailure(format!(
+                    "failed to open rmeta metadata: '{}'",
+                    filename.display()
+                ))
+            })?;
             let mmap = unsafe { Mmap::map(file) };
-            let mmap = mmap
-                .map_err(|_| format!("failed to mmap rmeta metadata: '{}'", filename.display()))?;
+            let mmap = mmap.map_err(|_| {
+                MetadataError::LoadFailure(format!(
+                    "failed to mmap rmeta metadata: '{}'",
+                    filename.display()
+                ))
+            })?;
 
             rustc_erase_owner!(OwningRef::new(mmap).map_owner_box())
         }
@@ -775,7 +800,10 @@ fn get_metadata_section(
     if blob.is_compatible() {
         Ok(blob)
     } else {
-        Err(format!("incompatible metadata version found: '{}'", filename.display()))
+        Err(MetadataError::LoadFailure(format!(
+            "invalid metadata version found: {}",
+            filename.display()
+        )))
     }
 }
 
@@ -854,6 +882,7 @@ struct CrateRejections {
     via_kind: Vec<CrateMismatch>,
     via_version: Vec<CrateMismatch>,
     via_filename: Vec<CrateMismatch>,
+    via_invalid: Vec<CrateMismatch>,
 }
 
 /// Candidate rejection reasons collected during crate search.
@@ -883,6 +912,24 @@ struct CrateRejections {
     NonDylibPlugin(Symbol),
 }
 
+enum MetadataError<'a> {
+    /// The file was missing.
+    NotPresent(&'a Path),
+    /// The file was present and invalid.
+    LoadFailure(String),
+}
+
+impl fmt::Display for MetadataError<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            MetadataError::NotPresent(filename) => {
+                f.write_str(&format!("no such file: '{}'", filename.display()))
+            }
+            MetadataError::LoadFailure(msg) => f.write_str(msg),
+        }
+    }
+}
+
 impl CrateError {
     crate fn report(self, sess: &Session, span: Span, missing_core: bool) -> ! {
         let mut err = match self {
@@ -1064,6 +1111,19 @@ impl CrateError {
                     }
                     err.note(&msg);
                     err
+                } else if !locator.crate_rejections.via_invalid.is_empty() {
+                    let mut err = struct_span_err!(
+                        sess,
+                        span,
+                        E0786,
+                        "found invalid metadata files for crate `{}`{}",
+                        crate_name,
+                        add,
+                    );
+                    for CrateMismatch { path: _, got } in locator.crate_rejections.via_invalid {
+                        err.note(&got);
+                    }
+                    err
                 } else {
                     let mut err = struct_span_err!(
                         sess,
index 2431b819a3f30e25d3507cd84c735703a2205771..bd5cda15b91abcfc18b6a6cc8ac089d25e7c5389 100644 (file)
@@ -309,7 +309,7 @@ fn process_command_line(&mut self) {
                     .libs
                     .iter()
                     .filter_map(|lib| lib.name.as_ref())
-                    .any(|n| &n.as_str() == &lib.name);
+                    .any(|n| n.as_str() == lib.name);
                 if new_name.is_empty() {
                     self.tcx.sess.err(&format!(
                         "an empty renaming target was specified for library `{}`",
index 9472a287e5a41907c5f434729376484048582a1e..7a51bb4a1f32ae828f9de259450a815ba37981c1 100644 (file)
@@ -538,12 +538,12 @@ impl InterpError<'_> {
     /// To avoid performance issues, there are places where we want to be sure to never raise these formatting errors,
     /// so this method lets us detect them and `bug!` on unexpected errors.
     pub fn formatted_string(&self) -> bool {
-        match self {
+        matches!(
+            self,
             InterpError::Unsupported(UnsupportedOpInfo::Unsupported(_))
-            | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ValidationFailure { .. })
-            | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_)) => true,
-            _ => false,
-        }
+                | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ValidationFailure { .. })
+                | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_))
+        )
     }
 
     /// Should this error be reported as a hard error, preventing compilation, or a soft error,
index 971556d4463004328c08c94838ebf1b73b3528e5..253ac266bedaa246cc1039b9a6e5191447cb152b 100644 (file)
@@ -2665,7 +2665,7 @@ fn map_projections(
         mut self,
         mut f: impl FnMut(UserTypeProjection) -> UserTypeProjection,
     ) -> Self {
-        self.contents = self.contents.drain(..).map(|(proj, span)| (f(proj), span)).collect();
+        self.contents = self.contents.into_iter().map(|(proj, span)| (f(proj), span)).collect();
         self
     }
 
index 42683dac426e3b1fdd5271658149c50ca42bd014..1260c691e7844cfb1fc1447c51d938114233f280 100644 (file)
@@ -632,11 +632,11 @@ fn tooltip<'tcx>(
     for statement in statements {
         let source_range = source_range_no_file(tcx, &statement.source_info.span);
         text.push(format!(
-            "\n{}{}: {}: {}",
+            "\n{}{}: {}: {:?}",
             TOOLTIP_INDENT,
             source_range,
             statement_kind_name(&statement),
-            format!("{:?}", statement)
+            statement
         ));
     }
     if let Some(term) = terminator {
index 8ec5f4c79781f34902df49db679edbcfc574a8a6..b87e23af72b702076ea2ea84f8d5b48bf87b6f43 100644 (file)
@@ -3060,9 +3060,10 @@ fn fn_abi_new_uncached(
                     // LLVM's definition of `noalias` is based solely on memory
                     // dependencies rather than pointer equality
                     //
-                    // Due to miscompiles in LLVM < 12, we apply a separate NoAliasMutRef attribute
-                    // for UniqueBorrowed arguments, so that the codegen backend can decide
-                    // whether or not to actually emit the attribute.
+                    // Due to past miscompiles in LLVM, we apply a separate NoAliasMutRef attribute
+                    // for UniqueBorrowed arguments, so that the codegen backend can decide whether
+                    // or not to actually emit the attribute. It can also be controlled with the
+                    // `-Zmutable-noalias` debugging option.
                     let no_alias = match kind {
                         PointerKind::Shared | PointerKind::UniqueBorrowed => false,
                         PointerKind::UniqueOwned => true,
index b11a54d5dcb11e5558437eaf22043cc991b3209e..742005e245f9d160ed91387e209975e1f1ddf0da 100644 (file)
@@ -744,6 +744,7 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
                     p!(print_def_path(did, substs));
                     if !substs.as_closure().is_valid() {
                         p!(" closure_substs=(unavailable)");
+                        p!(write(" substs={:?}", substs));
                     } else {
                         p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
                         p!(
index 8b20e1eec9a86e03ba2d3992530b195e385f4a59..c7d8bec506f6b80af01ed5e80d120ea8879ac7bb 100644 (file)
@@ -187,8 +187,12 @@ fn relate<R: TypeRelation<'tcx>>(
             })
             .enumerate()
             .map(|(i, r)| match r {
-                Err(TypeError::Sorts(exp_found)) => Err(TypeError::ArgumentSorts(exp_found, i)),
-                Err(TypeError::Mutability) => Err(TypeError::ArgumentMutability(i)),
+                Err(TypeError::Sorts(exp_found) | TypeError::ArgumentSorts(exp_found, _)) => {
+                    Err(TypeError::ArgumentSorts(exp_found, i))
+                }
+                Err(TypeError::Mutability | TypeError::ArgumentMutability(_)) => {
+                    Err(TypeError::ArgumentMutability(i))
+                }
                 r => r,
             });
         Ok(ty::FnSig {
index 158ba1b942528072c7416f70fe9cb434590e83a6..d38b567a95849be35d1995a6e2e8c3707dd2e1e4 100644 (file)
@@ -3,25 +3,14 @@
 use crate::{AnalysisDomain, GenKill, GenKillAnalysis};
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
-use rustc_middle::ty::{ParamEnv, TyCtxt};
-use rustc_span::DUMMY_SP;
-
-pub type MaybeMutBorrowedLocals<'mir, 'tcx> = MaybeBorrowedLocals<MutBorrow<'mir, 'tcx>>;
 
 /// A dataflow analysis that tracks whether a pointer or reference could possibly exist that points
 /// to a given local.
 ///
-/// The `K` parameter determines what kind of borrows are tracked. By default,
-/// `MaybeBorrowedLocals` looks for *any* borrow of a local. If you are only interested in borrows
-/// that might allow mutation, use the `MaybeMutBorrowedLocals` type alias instead.
-///
 /// At present, this is used as a very limited form of alias analysis. For example,
 /// `MaybeBorrowedLocals` is used to compute which locals are live during a yield expression for
-/// immovable generators. `MaybeMutBorrowedLocals` is used during const checking to prove that a
-/// local has not been mutated via indirect assignment (e.g., `*p = 42`), the side-effects of a
-/// function call or inline assembly.
-pub struct MaybeBorrowedLocals<K = AnyBorrow> {
-    kind: K,
+/// immovable generators.
+pub struct MaybeBorrowedLocals {
     ignore_borrow_on_drop: bool,
 }
 
@@ -29,29 +18,11 @@ impl MaybeBorrowedLocals {
     /// A dataflow analysis that records whether a pointer or reference exists that may alias the
     /// given local.
     pub fn all_borrows() -> Self {
-        MaybeBorrowedLocals { kind: AnyBorrow, ignore_borrow_on_drop: false }
-    }
-}
-
-impl MaybeMutBorrowedLocals<'mir, 'tcx> {
-    /// A dataflow analysis that records whether a pointer or reference exists that may *mutably*
-    /// alias the given local.
-    ///
-    /// This includes `&mut` and pointers derived from an `&mut`, as well as shared borrows of
-    /// types with interior mutability.
-    pub fn mut_borrows_only(
-        tcx: TyCtxt<'tcx>,
-        body: &'mir mir::Body<'tcx>,
-        param_env: ParamEnv<'tcx>,
-    ) -> Self {
-        MaybeBorrowedLocals {
-            kind: MutBorrow { body, tcx, param_env },
-            ignore_borrow_on_drop: false,
-        }
+        MaybeBorrowedLocals { ignore_borrow_on_drop: false }
     }
 }
 
-impl<K> MaybeBorrowedLocals<K> {
+impl MaybeBorrowedLocals {
     /// During dataflow analysis, ignore the borrow that may occur when a place is dropped.
     ///
     /// Drop terminators may call custom drop glue (`Drop::drop`), which takes `&mut self` as a
@@ -69,21 +40,14 @@ pub fn unsound_ignore_borrow_on_drop(self) -> Self {
         MaybeBorrowedLocals { ignore_borrow_on_drop: true, ..self }
     }
 
-    fn transfer_function<'a, T>(&'a self, trans: &'a mut T) -> TransferFunction<'a, T, K> {
-        TransferFunction {
-            kind: &self.kind,
-            trans,
-            ignore_borrow_on_drop: self.ignore_borrow_on_drop,
-        }
+    fn transfer_function<'a, T>(&'a self, trans: &'a mut T) -> TransferFunction<'a, T> {
+        TransferFunction { trans, ignore_borrow_on_drop: self.ignore_borrow_on_drop }
     }
 }
 
-impl<K> AnalysisDomain<'tcx> for MaybeBorrowedLocals<K>
-where
-    K: BorrowAnalysisKind<'tcx>,
-{
+impl AnalysisDomain<'tcx> for MaybeBorrowedLocals {
     type Domain = BitSet<Local>;
-    const NAME: &'static str = K::ANALYSIS_NAME;
+    const NAME: &'static str = "maybe_borrowed_locals";
 
     fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
         // bottom = unborrowed
@@ -95,10 +59,7 @@ fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) {
     }
 }
 
-impl<K> GenKillAnalysis<'tcx> for MaybeBorrowedLocals<K>
-where
-    K: BorrowAnalysisKind<'tcx>,
-{
+impl GenKillAnalysis<'tcx> for MaybeBorrowedLocals {
     type Idx = Local;
 
     fn statement_effect(
@@ -131,16 +92,14 @@ fn call_return_effect(
 }
 
 /// A `Visitor` that defines the transfer function for `MaybeBorrowedLocals`.
-struct TransferFunction<'a, T, K> {
+struct TransferFunction<'a, T> {
     trans: &'a mut T,
-    kind: &'a K,
     ignore_borrow_on_drop: bool,
 }
 
-impl<T, K> Visitor<'tcx> for TransferFunction<'a, T, K>
+impl<T> Visitor<'tcx> for TransferFunction<'a, T>
 where
     T: GenKill<Local>,
-    K: BorrowAnalysisKind<'tcx>,
 {
     fn visit_statement(&mut self, stmt: &Statement<'tcx>, location: Location) {
         self.super_statement(stmt, location);
@@ -156,14 +115,14 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
         self.super_rvalue(rvalue, location);
 
         match rvalue {
-            mir::Rvalue::AddressOf(mt, borrowed_place) => {
-                if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, *borrowed_place) {
+            mir::Rvalue::AddressOf(_mt, borrowed_place) => {
+                if !borrowed_place.is_indirect() {
                     self.trans.gen(borrowed_place.local);
                 }
             }
 
-            mir::Rvalue::Ref(_, kind, borrowed_place) => {
-                if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, *borrowed_place) {
+            mir::Rvalue::Ref(_, _kind, borrowed_place) => {
+                if !borrowed_place.is_indirect() {
                     self.trans.gen(borrowed_place.local);
                 }
             }
@@ -211,64 +170,3 @@ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Loc
         }
     }
 }
-
-pub struct AnyBorrow;
-
-pub struct MutBorrow<'mir, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    body: &'mir Body<'tcx>,
-    param_env: ParamEnv<'tcx>,
-}
-
-impl MutBorrow<'mir, 'tcx> {
-    /// `&` and `&raw` only allow mutation if the borrowed place is `!Freeze`.
-    ///
-    /// This assumes that it is UB to take the address of a struct field whose type is
-    /// `Freeze`, then use pointer arithmetic to derive a pointer to a *different* field of
-    /// that same struct whose type is `!Freeze`. If we decide that this is not UB, we will
-    /// have to check the type of the borrowed **local** instead of the borrowed **place**
-    /// below. See [rust-lang/unsafe-code-guidelines#134].
-    ///
-    /// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
-    fn shared_borrow_allows_mutation(&self, place: Place<'tcx>) -> bool {
-        !place.ty(self.body, self.tcx).ty.is_freeze(self.tcx.at(DUMMY_SP), self.param_env)
-    }
-}
-
-pub trait BorrowAnalysisKind<'tcx> {
-    const ANALYSIS_NAME: &'static str;
-
-    fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool;
-    fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool;
-}
-
-impl BorrowAnalysisKind<'tcx> for AnyBorrow {
-    const ANALYSIS_NAME: &'static str = "maybe_borrowed_locals";
-
-    fn in_ref(&self, _: mir::BorrowKind, _: Place<'_>) -> bool {
-        true
-    }
-    fn in_address_of(&self, _: Mutability, _: Place<'_>) -> bool {
-        true
-    }
-}
-
-impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> {
-    const ANALYSIS_NAME: &'static str = "maybe_mut_borrowed_locals";
-
-    fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool {
-        match kind {
-            mir::BorrowKind::Mut { .. } => true,
-            mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => {
-                self.shared_borrow_allows_mutation(place)
-            }
-        }
-    }
-
-    fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool {
-        match mt {
-            Mutability::Mut => true,
-            Mutability::Not => self.shared_borrow_allows_mutation(place),
-        }
-    }
-}
index 474f4f2a79b2a7475a25344d49f0f9193b48d04c..91dddc6cd55c5d415b76548051dd488b0774bb4a 100644 (file)
@@ -22,7 +22,7 @@
 mod liveness;
 mod storage_liveness;
 
-pub use self::borrowed_locals::{MaybeBorrowedLocals, MaybeMutBorrowedLocals};
+pub use self::borrowed_locals::MaybeBorrowedLocals;
 pub use self::init_locals::MaybeInitializedLocals;
 pub use self::liveness::MaybeLiveLocals;
 pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageLive};
index 2d27d085b489398440fb2e4a3640624b469063ad..28e5d76783aa4015cb8af5bc2cce5b2a618cf584 100644 (file)
@@ -11,8 +11,7 @@
 use rustc_middle::ty::{self, Ty, TyCtxt};
 
 use crate::impls::{
-    DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeLiveLocals, MaybeMutBorrowedLocals,
-    MaybeUninitializedPlaces,
+    DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeLiveLocals, MaybeUninitializedPlaces,
 };
 use crate::move_paths::{HasMoveData, MoveData};
 use crate::move_paths::{LookupResult, MovePathIndex};
@@ -62,14 +61,6 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             sanity_check_via_rustc_peek(tcx, body, &attributes, &flow_def_inits);
         }
 
-        if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_indirectly_mutable).is_some() {
-            let flow_mut_borrowed = MaybeMutBorrowedLocals::mut_borrows_only(tcx, body, param_env)
-                .into_engine(tcx, body)
-                .iterate_to_fixpoint();
-
-            sanity_check_via_rustc_peek(tcx, body, &attributes, &flow_mut_borrowed);
-        }
-
         if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_liveness).is_some() {
             let flow_liveness = MaybeLiveLocals.into_engine(tcx, body).iterate_to_fixpoint();
 
@@ -281,26 +272,6 @@ fn peek_at(
     }
 }
 
-impl<'tcx> RustcPeekAt<'tcx> for MaybeMutBorrowedLocals<'_, 'tcx> {
-    fn peek_at(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        place: mir::Place<'tcx>,
-        flow_state: &BitSet<Local>,
-        call: PeekCall,
-    ) {
-        info!(?place, "peek_at");
-        let Some(local) = place.as_local() else {
-            tcx.sess.span_err(call.span, "rustc_peek: argument was not a local");
-            return;
-        };
-
-        if !flow_state.contains(local) {
-            tcx.sess.span_err(call.span, "rustc_peek: bit not set");
-        }
-    }
-}
-
 impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals {
     fn peek_at(
         &self,
index 4ac93f716192308709d3c18b73b58d8cb63041f6..6807d02519e2b3305f46278f1b33f861fafb14bd 100644 (file)
@@ -485,7 +485,7 @@ fn inject_statement(
 
 // Non-code expressions are injected into the coverage map, without generating executable code.
 fn inject_intermediate_expression(mir_body: &mut mir::Body<'tcx>, expression: CoverageKind) {
-    debug_assert!(if let CoverageKind::Expression { .. } = expression { true } else { false });
+    debug_assert!(matches!(expression, CoverageKind::Expression { .. }));
     debug!("  injecting non-code expression {:?}", expression);
     let inject_in_bb = mir::START_BLOCK;
     let data = &mut mir_body[inject_in_bb];
index cc525a4d6b91ca1a1ab9e491b4086c57a6c46885..d13fa0729cd9562a0306ef1be170dd3a302fb3a4 100644 (file)
@@ -94,10 +94,9 @@ pub fn for_statement(
         stmt_index: usize,
     ) -> Self {
         let is_closure = match statement.kind {
-            StatementKind::Assign(box (_, Rvalue::Aggregate(box ref kind, _))) => match kind {
-                AggregateKind::Closure(_, _) | AggregateKind::Generator(_, _, _) => true,
-                _ => false,
-            },
+            StatementKind::Assign(box (_, Rvalue::Aggregate(box ref kind, _))) => {
+                matches!(kind, AggregateKind::Closure(_, _) | AggregateKind::Generator(_, _, _))
+            }
             _ => false,
         };
 
index 7b4eb4912cb366a99319ceb5a309131cad6db06f..6c423a2bb5756c79476adf6a8186781b61c29914 100644 (file)
@@ -11,7 +11,7 @@ impl<'tcx> MirPass<'tcx> for RevealAll {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         // This pass must run before inlining, since we insert callee bodies in RevealAll mode.
         // Do not apply this transformation to generators.
-        if (tcx.sess.mir_opt_level() >= 3 || !super::inline::is_enabled(tcx))
+        if (tcx.sess.mir_opt_level() >= 3 || super::inline::is_enabled(tcx))
             && body.generator.is_none()
         {
             let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
index baf381081ddab019de0e25c8ef10278fbf82f2cc..64cd6f56a9ffa0a15d254c302587bb0f4e9cccc6 100644 (file)
@@ -27,9 +27,8 @@ fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             // This is a temporary solution that handles possibly diverging asm statements.
             // Accompanying testcases: mir-opt/unreachable_asm.rs and mir-opt/unreachable_asm_2.rs
             let asm_stmt_in_block = || {
-                bb_data.statements.iter().any(|stmt: &Statement<'_>| match stmt.kind {
-                    StatementKind::LlvmInlineAsm(..) => true,
-                    _ => false,
+                bb_data.statements.iter().any(|stmt: &Statement<'_>| {
+                    matches!(stmt.kind, StatementKind::LlvmInlineAsm(..))
                 })
             };
 
index 5147408210ef538ef24b1166b3c759b3dc5edb93..59988e69b5d3a0d3af3dc8c516c459fd19391af0 100644 (file)
@@ -806,13 +806,22 @@ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Loc
                     }
                 }
             }
+            mir::TerminatorKind::Assert { ref msg, .. } => {
+                let lang_item = match msg {
+                    mir::AssertKind::BoundsCheck { .. } => LangItem::PanicBoundsCheck,
+                    _ => LangItem::Panic,
+                };
+                let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source)));
+                if should_codegen_locally(tcx, &instance) {
+                    self.output.push(create_fn_mono_item(tcx, instance, source));
+                }
+            }
             mir::TerminatorKind::Goto { .. }
             | mir::TerminatorKind::SwitchInt { .. }
             | mir::TerminatorKind::Resume
             | mir::TerminatorKind::Abort
             | mir::TerminatorKind::Return
-            | mir::TerminatorKind::Unreachable
-            | mir::TerminatorKind::Assert { .. } => {}
+            | mir::TerminatorKind::Unreachable => {}
             mir::TerminatorKind::GeneratorDrop
             | mir::TerminatorKind::Yield { .. }
             | mir::TerminatorKind::FalseEdge { .. }
index 799b4e18c240f24afedae9073453384356f2c5ad..4392c02f874d4da47001ca3f167f7baf37a85dda 100644 (file)
@@ -67,7 +67,7 @@
             src_file.prefer_local(),
             line_nos
         ) {
-            eprintln!("Error writting to file {}", e.to_string())
+            eprintln!("Error writing to file {}", e)
         }
     }
 }
index 1decaaa955f023075367e523b4e801eec49a2cb1..a823607ab0ec2191c86a3630fd2488d0c9198fb2 100644 (file)
@@ -18,3 +18,4 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_ast = { path = "../rustc_ast" }
 unicode-normalization = "0.1.11"
+unicode-width = "0.1.4"
index 1e65cc27154a818bd19889f40810dbef788acecc..cf35c3cd53b2fb146abf8d69f28d1423dca85db6 100644 (file)
@@ -1,10 +1,13 @@
 use rustc_ast::ast::{self, AttrStyle};
 use rustc_ast::token::{self, CommentKind, Token, TokenKind};
 use rustc_ast::tokenstream::{Spacing, TokenStream};
+use rustc_ast::util::unicode::contains_text_flow_control_chars;
 use rustc_errors::{error_code, Applicability, DiagnosticBuilder, FatalError, PResult};
 use rustc_lexer::unescape::{self, Mode};
 use rustc_lexer::{Base, DocStyle, RawStrError};
-use rustc_session::lint::builtin::RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX;
+use rustc_session::lint::builtin::{
+    RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
+};
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::{sym, Symbol};
@@ -129,6 +132,24 @@ fn struct_fatal_span_char(
             .struct_span_fatal(self.mk_sp(from_pos, to_pos), &format!("{}: {}", m, escaped_char(c)))
     }
 
+    /// Detect usages of Unicode codepoints changing the direction of the text on screen and loudly
+    /// complain about it.
+    fn lint_unicode_text_flow(&self, start: BytePos) {
+        // Opening delimiter of the length 2 is not included into the comment text.
+        let content_start = start + BytePos(2);
+        let content = self.str_from(content_start);
+        if contains_text_flow_control_chars(content) {
+            let span = self.mk_sp(start, self.pos);
+            self.sess.buffer_lint_with_diagnostic(
+                &TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
+                span,
+                ast::CRATE_NODE_ID,
+                "unicode codepoint changing visible direction of text present in comment",
+                BuiltinLintDiagnostics::UnicodeTextFlow(span, content.to_string()),
+            );
+        }
+    }
+
     /// Turns simple `rustc_lexer::TokenKind` enum into a rich
     /// `rustc_ast::TokenKind`. This turns strings into interned
     /// symbols and runs additional validation.
@@ -136,7 +157,12 @@ fn cook_lexer_token(&self, token: rustc_lexer::TokenKind, start: BytePos) -> Opt
         Some(match token {
             rustc_lexer::TokenKind::LineComment { doc_style } => {
                 // Skip non-doc comments
-                let doc_style = doc_style?;
+                let doc_style = if let Some(doc_style) = doc_style {
+                    doc_style
+                } else {
+                    self.lint_unicode_text_flow(start);
+                    return None;
+                };
 
                 // Opening delimiter of the length 3 is not included into the symbol.
                 let content_start = start + BytePos(3);
@@ -158,7 +184,12 @@ fn cook_lexer_token(&self, token: rustc_lexer::TokenKind, start: BytePos) -> Opt
                 }
 
                 // Skip non-doc comments
-                let doc_style = doc_style?;
+                let doc_style = if let Some(doc_style) = doc_style {
+                    doc_style
+                } else {
+                    self.lint_unicode_text_flow(start);
+                    return None;
+                };
 
                 // Opening delimiter of the length 3 and closing delimiter of the length 2
                 // are not included into the symbol.
index cef5b3a226bff81a65f1fa69da5bdfc227e06a77..569f186a72766f45aed97f560400a3cc91c5f6e7 100644 (file)
@@ -187,12 +187,17 @@ pub(crate) fn emit_unescape_error(
             assert!(mode.is_bytes());
             let (c, span) = last_char();
             let mut err = handler.struct_span_err(span, "non-ASCII character in byte constant");
-            err.span_label(span, "byte constant must be ASCII");
+            let postfix = if unicode_width::UnicodeWidthChar::width(c).unwrap_or(1) == 0 {
+                format!(" but is {:?}", c)
+            } else {
+                String::new()
+            };
+            err.span_label(span, &format!("byte constant must be ASCII{}", postfix));
             if (c as u32) <= 0xFF {
                 err.span_suggestion(
                     span,
                     &format!(
-                        "if you meant to use the unicode code point for '{}', use a \\xHH escape",
+                        "if you meant to use the unicode code point for {:?}, use a \\xHH escape",
                         c
                     ),
                     format!("\\x{:X}", c as u32),
@@ -206,7 +211,7 @@ pub(crate) fn emit_unescape_error(
                 err.span_suggestion(
                     span,
                     &format!(
-                        "if you meant to use the UTF-8 encoding of '{}', use \\xHH escapes",
+                        "if you meant to use the UTF-8 encoding of {:?}, use \\xHH escapes",
                         c
                     ),
                     utf8.as_bytes()
@@ -220,10 +225,15 @@ pub(crate) fn emit_unescape_error(
         }
         EscapeError::NonAsciiCharInByteString => {
             assert!(mode.is_bytes());
-            let (_c, span) = last_char();
+            let (c, span) = last_char();
+            let postfix = if unicode_width::UnicodeWidthChar::width(c).unwrap_or(1) == 0 {
+                format!(" but is {:?}", c)
+            } else {
+                String::new()
+            };
             handler
                 .struct_span_err(span, "raw byte string must be ASCII")
-                .span_label(span, "must be ASCII")
+                .span_label(span, &format!("must be ASCII{}", postfix))
                 .emit();
         }
         EscapeError::OutOfRangeHexEscape => {
index d2167c7a5db0c8f642f61c047f5b3b54b39372eb..73ca809ab1d3a53f72523025251250e2bd842f18 100644 (file)
@@ -220,7 +220,7 @@ fn parse_item_kind(
         } else if self.check_fn_front_matter(def_final) {
             // FUNCTION ITEM
             let (ident, sig, generics, body) = self.parse_fn(attrs, req_name, lo)?;
-            (ident, ItemKind::Fn(Box::new(FnKind(def(), sig, generics, body))))
+            (ident, ItemKind::Fn(Box::new(Fn { defaultness: def(), sig, generics, body })))
         } else if self.eat_keyword(kw::Extern) {
             if self.eat_keyword(kw::Crate) {
                 // EXTERN CRATE
@@ -560,7 +560,7 @@ fn parse_item_impl(
                 };
                 let trait_ref = TraitRef { path, ref_id: ty_first.id };
 
-                ItemKind::Impl(Box::new(ImplKind {
+                ItemKind::Impl(Box::new(Impl {
                     unsafety,
                     polarity,
                     defaultness,
@@ -573,7 +573,7 @@ fn parse_item_impl(
             }
             None => {
                 // impl Type
-                ItemKind::Impl(Box::new(ImplKind {
+                ItemKind::Impl(Box::new(Impl {
                     unsafety,
                     polarity,
                     defaultness,
@@ -682,7 +682,7 @@ fn parse_item_trait(&mut self, attrs: &mut Vec<Attribute>, lo: Span) -> PResult<
 
         self.expect_keyword(kw::Trait)?;
         let ident = self.parse_ident()?;
-        let mut tps = self.parse_generics()?;
+        let mut generics = self.parse_generics()?;
 
         // Parse optional colon and supertrait bounds.
         let had_colon = self.eat(&token::Colon);
@@ -702,7 +702,7 @@ fn parse_item_trait(&mut self, attrs: &mut Vec<Attribute>, lo: Span) -> PResult<
             }
 
             let bounds = self.parse_generic_bounds(None)?;
-            tps.where_clause = self.parse_where_clause()?;
+            generics.where_clause = self.parse_where_clause()?;
             self.expect_semi()?;
 
             let whole_span = lo.to(self.prev_token.span);
@@ -717,12 +717,15 @@ fn parse_item_trait(&mut self, attrs: &mut Vec<Attribute>, lo: Span) -> PResult<
 
             self.sess.gated_spans.gate(sym::trait_alias, whole_span);
 
-            Ok((ident, ItemKind::TraitAlias(tps, bounds)))
+            Ok((ident, ItemKind::TraitAlias(generics, bounds)))
         } else {
             // It's a normal trait.
-            tps.where_clause = self.parse_where_clause()?;
+            generics.where_clause = self.parse_where_clause()?;
             let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
-            Ok((ident, ItemKind::Trait(Box::new(TraitKind(is_auto, unsafety, tps, bounds, items)))))
+            Ok((
+                ident,
+                ItemKind::Trait(Box::new(Trait { is_auto, unsafety, generics, bounds, items })),
+            ))
         }
     }
 
@@ -769,7 +772,7 @@ fn parse_assoc_item(
     /// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
     /// ```
     /// The `"type"` has already been eaten.
-    fn parse_type_alias(&mut self, def: Defaultness) -> PResult<'a, ItemInfo> {
+    fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemInfo> {
         let ident = self.parse_ident()?;
         let mut generics = self.parse_generics()?;
 
@@ -778,10 +781,10 @@ fn parse_type_alias(&mut self, def: Defaultness) -> PResult<'a, ItemInfo> {
             if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
         generics.where_clause = self.parse_where_clause()?;
 
-        let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
+        let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
         self.expect_semi()?;
 
-        Ok((ident, ItemKind::TyAlias(Box::new(TyAliasKind(def, generics, bounds, default)))))
+        Ok((ident, ItemKind::TyAlias(Box::new(TyAlias { defaultness, generics, bounds, ty }))))
     }
 
     /// Parses a `UseTree`.
@@ -1039,9 +1042,7 @@ fn recover_const_impl(
         };
 
         match impl_info.1 {
-            ItemKind::Impl(box ImplKind {
-                of_trait: Some(ref trai), ref mut constness, ..
-            }) => {
+            ItemKind::Impl(box Impl { of_trait: Some(ref trai), ref mut constness, .. }) => {
                 *constness = Const::Yes(const_span);
 
                 let before_trait = trai.path.span.shrink_to_lo();
index a0ceb567f25a6f8d13b6d04bc860153e86a3c478..82486a6a5f2e277a75b639edd84c5127e1af0750 100644 (file)
@@ -210,10 +210,10 @@ fn const_check_violated(&self, expr: NonConstExpr, span: Span) {
             required_gates.iter().copied().filter(|&g| !features.enabled(g)).collect();
 
         match missing_gates.as_slice() {
-            &[] => struct_span_err!(tcx.sess, span, E0744, "{}", msg).emit(),
+            [] => struct_span_err!(tcx.sess, span, E0744, "{}", msg).emit(),
 
-            &[missing_primary, ref missing_secondary @ ..] => {
-                let mut err = feature_err(&tcx.sess.parse_sess, missing_primary, span, &msg);
+            [missing_primary, ref missing_secondary @ ..] => {
+                let mut err = feature_err(&tcx.sess.parse_sess, *missing_primary, span, &msg);
 
                 // If multiple feature gates would be required to enable this expression, include
                 // them as help messages. Don't emit a separate error for each missing feature gate.
index 238b92a61342b451ce842a09e46a8fc925a00de2..9703f0c3d9605269089498686272447cc188bb9e 100644 (file)
@@ -518,9 +518,22 @@ fn try_load_from_disk_and_cache_in_memory<CTX, K, V>(
         prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
         if let Some(result) = result {
+            let prev_fingerprint = tcx
+                .dep_context()
+                .dep_graph()
+                .prev_fingerprint_of(dep_node)
+                .unwrap_or(Fingerprint::ZERO);
             // If `-Zincremental-verify-ich` is specified, re-hash results from
             // the cache and make sure that they have the expected fingerprint.
-            if unlikely!(tcx.dep_context().sess().opts.debugging_opts.incremental_verify_ich) {
+            //
+            // If not, we still seek to verify a subset of fingerprints loaded
+            // from disk. Re-hashing results is fairly expensive, so we can't
+            // currently afford to verify every hash. This subset should still
+            // give us some coverage of potential bugs though.
+            let try_verify = prev_fingerprint.as_value().1 % 32 == 0;
+            if unlikely!(
+                try_verify || tcx.dep_context().sess().opts.debugging_opts.incremental_verify_ich
+            ) {
                 incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query);
             }
 
index 33af9884cbb6686ced37c2729251fdb5094491e1..d77a70e5327994dee768eadc67e7ac6dbdc7c440 100644 (file)
@@ -15,7 +15,7 @@
 
 use rustc_ast::visit::{self, AssocCtxt, Visitor};
 use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind};
-use rustc_ast::{Block, FnKind, ForeignItem, ForeignItemKind, ImplKind, Item, ItemKind, NodeId};
+use rustc_ast::{Block, Fn, ForeignItem, ForeignItemKind, Impl, Item, ItemKind, NodeId};
 use rustc_ast_lowering::ResolverAstLowering;
 use rustc_attr as attr;
 use rustc_data_structures::sync::Lrc;
@@ -880,7 +880,7 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
             }
 
             // These items do not add names to modules.
-            ItemKind::Impl(box ImplKind { of_trait: Some(..), .. }) => {
+            ItemKind::Impl(box Impl { of_trait: Some(..), .. }) => {
                 self.r.trait_impl_items.insert(local_def_id);
             }
             ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
@@ -1380,7 +1380,7 @@ fn visit_assoc_item(&mut self, item: &'b AssocItem, ctxt: AssocCtxt) {
         if ctxt == AssocCtxt::Trait {
             let (def_kind, ns) = match item.kind {
                 AssocItemKind::Const(..) => (DefKind::AssocConst, ValueNS),
-                AssocItemKind::Fn(box FnKind(_, ref sig, _, _)) => {
+                AssocItemKind::Fn(box Fn { ref sig, .. }) => {
                     if sig.decl.has_self() {
                         self.r.has_self.insert(def_id);
                     }
index 163acebcceacffe792a1238f13a014e71a6858c5..ff0d76e94fdf5c231a8b8f193e034c4a0d4201f1 100644 (file)
@@ -420,6 +420,10 @@ impl<'a> Resolver<'a> {
                 err.span_label(span, label);
 
                 if let Some((suggestions, msg, applicability)) = suggestion {
+                    if suggestions.is_empty() {
+                        err.help(&msg);
+                        return err;
+                    }
                     err.multipart_suggestion(&msg, suggestions, applicability);
                 }
 
index 0a24e00ee4bf5137b88eadef81b20a09266b4ebb..e67f7f03516803c0a7cb7ca7acfb57b9f05f4846 100644 (file)
@@ -498,8 +498,8 @@ fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef, m: &'ast TraitBound
     }
     fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
         match foreign_item.kind {
-            ForeignItemKind::Fn(box FnKind(_, _, ref generics, _))
-            | ForeignItemKind::TyAlias(box TyAliasKind(_, ref generics, ..)) => {
+            ForeignItemKind::Fn(box Fn { ref generics, .. })
+            | ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
                 self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
                     visit::walk_foreign_item(this, foreign_item);
                 });
@@ -953,8 +953,8 @@ fn resolve_item(&mut self, item: &'ast Item) {
         debug!("(resolving item) resolving {} ({:?})", name, item.kind);
 
         match item.kind {
-            ItemKind::TyAlias(box TyAliasKind(_, ref generics, _, _))
-            | ItemKind::Fn(box FnKind(_, _, ref generics, _)) => {
+            ItemKind::TyAlias(box TyAlias { ref generics, .. })
+            | ItemKind::Fn(box Fn { ref generics, .. }) => {
                 self.compute_num_lifetime_params(item.id, generics);
                 self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
                     visit::walk_item(this, item)
@@ -968,7 +968,7 @@ fn resolve_item(&mut self, item: &'ast Item) {
                 self.resolve_adt(item, generics);
             }
 
-            ItemKind::Impl(box ImplKind {
+            ItemKind::Impl(box Impl {
                 ref generics,
                 ref of_trait,
                 ref self_ty,
@@ -979,7 +979,7 @@ fn resolve_item(&mut self, item: &'ast Item) {
                 self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items);
             }
 
-            ItemKind::Trait(box TraitKind(.., ref generics, ref bounds, ref trait_items)) => {
+            ItemKind::Trait(box Trait { ref generics, ref bounds, ref items, .. }) => {
                 self.compute_num_lifetime_params(item.id, generics);
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
@@ -994,8 +994,8 @@ fn resolve_item(&mut self, item: &'ast Item) {
                             });
                         };
 
-                        this.with_trait_items(trait_items, |this| {
-                            for item in trait_items {
+                        this.with_trait_items(items, |this| {
+                            for item in items {
                                 match &item.kind {
                                     AssocItemKind::Const(_, ty, default) => {
                                         this.visit_ty(ty);
@@ -1015,10 +1015,10 @@ fn resolve_item(&mut self, item: &'ast Item) {
                                             );
                                         }
                                     }
-                                    AssocItemKind::Fn(box FnKind(_, _, generics, _)) => {
+                                    AssocItemKind::Fn(box Fn { generics, .. }) => {
                                         walk_assoc_item(this, generics, item);
                                     }
-                                    AssocItemKind::TyAlias(box TyAliasKind(_, generics, _, _)) => {
+                                    AssocItemKind::TyAlias(box TyAlias { generics, .. }) => {
                                         walk_assoc_item(this, generics, item);
                                     }
                                     AssocItemKind::MacCall(_) => {
@@ -1338,7 +1338,7 @@ fn resolve_implementation(
                                                 },
                                             );
                                         }
-                                        AssocItemKind::Fn(box FnKind(.., generics, _)) => {
+                                        AssocItemKind::Fn(box Fn { generics, .. }) => {
                                             debug!("resolve_implementation AssocItemKind::Fn");
                                             // We also need a new scope for the impl item type parameters.
                                             this.with_generic_param_rib(
@@ -1363,12 +1363,9 @@ fn resolve_implementation(
                                                 },
                                             );
                                         }
-                                        AssocItemKind::TyAlias(box TyAliasKind(
-                                            _,
-                                            generics,
-                                            _,
-                                            _,
-                                        )) => {
+                                        AssocItemKind::TyAlias(box TyAlias {
+                                            generics, ..
+                                        }) => {
                                             debug!("resolve_implementation AssocItemKind::TyAlias");
                                             // We also need a new scope for the impl item type parameters.
                                             this.with_generic_param_rib(
index 5f90fcdfa64e2cc205525adfa782b98bdb29484b..4acbb11b13f76295a290e49519088776416e605b 100644 (file)
@@ -333,7 +333,7 @@ pub(crate) fn smart_resolve_report_errors(
         let candidates = self
             .r
             .lookup_import_candidates(ident, ns, &self.parent_scope, is_expected)
-            .drain(..)
+            .into_iter()
             .filter(|ImportSuggestion { did, .. }| {
                 match (did, res.and_then(|res| res.opt_def_id())) {
                     (Some(suggestion_did), Some(actual_did)) => *suggestion_did != actual_did,
@@ -1235,9 +1235,7 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> {
                 if assoc_item.ident == ident {
                     return Some(match &assoc_item.kind {
                         ast::AssocItemKind::Const(..) => AssocSuggestion::AssocConst,
-                        ast::AssocItemKind::Fn(box ast::FnKind(_, sig, ..))
-                            if sig.decl.has_self() =>
-                        {
+                        ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) if sig.decl.has_self() => {
                             AssocSuggestion::MethodWithSelf
                         }
                         ast::AssocItemKind::Fn(..) => AssocSuggestion::AssocFn,
@@ -1346,12 +1344,10 @@ fn lookup_typo_candidate(
         } else {
             // Search in module.
             let mod_path = &path[..path.len() - 1];
-            if let PathResult::Module(module) =
+            if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
                 self.resolve_path(mod_path, Some(TypeNS), false, span, CrateLint::No)
             {
-                if let ModuleOrUniformRoot::Module(module) = module {
-                    self.r.add_module_candidates(module, &mut names, &filter_fn);
-                }
+                self.r.add_module_candidates(module, &mut names, &filter_fn);
             }
         }
 
@@ -1554,7 +1550,7 @@ fn suggest_using_enum_variant(
         if suggest_only_tuple_variants {
             // Suggest only tuple variants regardless of whether they have fields and do not
             // suggest path with added parentheses.
-            let mut suggestable_variants = variants
+            let suggestable_variants = variants
                 .iter()
                 .filter(|(.., kind)| *kind == CtorKind::Fn)
                 .map(|(variant, ..)| path_names_to_string(variant))
@@ -1580,7 +1576,7 @@ fn suggest_using_enum_variant(
                 err.span_suggestions(
                     span,
                     &msg,
-                    suggestable_variants.drain(..),
+                    suggestable_variants.into_iter(),
                     Applicability::MaybeIncorrect,
                 );
             }
@@ -1638,7 +1634,7 @@ fn suggest_using_enum_variant(
                 );
             }
 
-            let mut suggestable_variants_with_placeholders = variants
+            let suggestable_variants_with_placeholders = variants
                 .iter()
                 .filter(|(_, def_id, kind)| needs_placeholder(*def_id, *kind))
                 .map(|(variant, _, kind)| (path_names_to_string(variant), kind))
@@ -1663,7 +1659,7 @@ fn suggest_using_enum_variant(
                 err.span_suggestions(
                     span,
                     msg,
-                    suggestable_variants_with_placeholders.drain(..),
+                    suggestable_variants_with_placeholders.into_iter(),
                     Applicability::HasPlaceholders,
                 );
             }
index 94563400a8b53580578424ca2251b4169e3c4391..55931d29f6db0ceb5e8ccfd3d548f0db04f3c19b 100644 (file)
@@ -1931,20 +1931,18 @@ fn suggest_eliding_single_use_lifetime(
                             break;
                         }
                     }
-                    hir::TyKind::Path(ref qpath) => {
-                        if let QPath::Resolved(_, path) = qpath {
-                            let last_segment = &path.segments[path.segments.len() - 1];
-                            let generics = last_segment.args();
-                            for arg in generics.args.iter() {
-                                if let GenericArg::Lifetime(lt) = arg {
-                                    if lt.name.ident() == name {
-                                        elide_use = Some(lt.span);
-                                        break;
-                                    }
+                    hir::TyKind::Path(QPath::Resolved(_, path)) => {
+                        let last_segment = &path.segments[path.segments.len() - 1];
+                        let generics = last_segment.args();
+                        for arg in generics.args.iter() {
+                            if let GenericArg::Lifetime(lt) = arg {
+                                if lt.name.ident() == name {
+                                    elide_use = Some(lt.span);
+                                    break;
                                 }
                             }
-                            break;
                         }
+                        break;
                     }
                     _ => {}
                 }
index 23eb2d1aebb7ce9be13f8f2720b50cc0969f69d2..5f3620b247e26e1885a7361d282316268b84b1fb 100644 (file)
@@ -2523,19 +2523,29 @@ enum FindBindingResult<'a> {
                         } else {
                             (
                                 format!("use of undeclared crate or module `{}`", ident),
-                                self.find_similarly_named_module_or_crate(
-                                    ident.name,
-                                    &parent_scope.module,
-                                )
-                                .map(|sugg| {
-                                    (
-                                        vec![(ident.span, sugg.to_string())],
+                                if ident.name == sym::alloc {
+                                    Some((
+                                        vec![],
                                         String::from(
-                                            "there is a crate or module with a similar name",
+                                            "add `extern crate alloc` to use the `alloc` crate",
                                         ),
                                         Applicability::MaybeIncorrect,
+                                    ))
+                                } else {
+                                    self.find_similarly_named_module_or_crate(
+                                        ident.name,
+                                        &parent_scope.module,
                                     )
-                                }),
+                                    .map(|sugg| {
+                                        (
+                                            vec![(ident.span, sugg.to_string())],
+                                            String::from(
+                                                "there is a crate or module with a similar name",
+                                            ),
+                                            Applicability::MaybeIncorrect,
+                                        )
+                                    })
+                                },
                             )
                         }
                     } else {
index f4567b334836ae476984386399dafba9f1d10a48..f1a5282b08871323aa2b0a18be0103481ae1fffd 100644 (file)
@@ -236,7 +236,7 @@ fn process_formals(&mut self, formals: &'tcx [hir::Param<'tcx>], qualname: &str)
                             id,
                             span,
                             name: ident.to_string(),
-                            qualname: format!("{}::{}", qualname, ident.to_string()),
+                            qualname: format!("{}::{}", qualname, ident),
                             value: typ,
                             parent: None,
                             children: vec![],
@@ -889,7 +889,7 @@ fn process_var_decl(&mut self, pat: &'tcx hir::Pat<'tcx>) {
 
                     // Rust uses the id of the pattern for var lookups, so we'll use it too.
                     if !self.span.filter_generated(ident.span) {
-                        let qualname = format!("{}${}", ident.to_string(), hir_id);
+                        let qualname = format!("{}${}", ident, hir_id);
                         let id = id_from_hir_id(hir_id, &self.save_ctxt);
                         let span = self.span_from_span(ident.span);
 
index 299dfed9d5dcea7845f2898b3cb612e1ddc96d80..8a9e8739d037cef48304a5cbd443cbd38918b37f 100644 (file)
@@ -914,7 +914,7 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
 pub(super) fn build_target_config(
     opts: &Options,
     target_override: Option<Target>,
-    sysroot: &PathBuf,
+    sysroot: &Path,
 ) -> Target {
     let target_result = target_override.map_or_else(
         || Target::search(&opts.target_triple, sysroot),
index e894e46a301424615848d78db424d789691e16f2..71464ad97145bafe9e4266ee91ec8284be129c24 100644 (file)
@@ -881,7 +881,7 @@ mod parse {
         match v {
             Some(s) => {
                 if !slot.is_empty() {
-                    slot.push_str(",");
+                    slot.push(',');
                 }
                 slot.push_str(s);
                 true
@@ -1193,7 +1193,7 @@ mod parse {
     move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
         "the size at which the `large_assignments` lint starts to be emitted"),
     mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
-        "emit noalias metadata for mutable references (default: yes for LLVM >= 12, otherwise no)"),
+        "emit noalias metadata for mutable references (default: yes)"),
     new_llvm_pass_manager: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "use new LLVM pass manager (default: no)"),
     nll_facts: bool = (false, parse_bool, [UNTRACKED],
index 032ae73bbf3c61fe503de4442584f5fc658a0e2b..dfc64f37e4c46b84c7e1ee9a02ee1282a6feba67 100644 (file)
@@ -194,10 +194,8 @@ fn encode(&self, encoder: &mut S) -> Result<(), S::Error> {
         encoder.emit_enum(|encoder| match *self {
             RealFileName::LocalPath(ref local_path) => {
                 encoder.emit_enum_variant("LocalPath", 0, 1, |encoder| {
-                    Ok({
-                        encoder
-                            .emit_enum_variant_arg(true, |encoder| local_path.encode(encoder))?;
-                    })
+                    encoder.emit_enum_variant_arg(true, |encoder| local_path.encode(encoder))?;
+                    Ok(())
                 })
             }
 
@@ -206,12 +204,9 @@ fn encode(&self, encoder: &mut S) -> Result<(), S::Error> {
                     // For privacy and build reproducibility, we must not embed host-dependant path in artifacts
                     // if they have been remapped by --remap-path-prefix
                     assert!(local_path.is_none());
-                    Ok({
-                        encoder
-                            .emit_enum_variant_arg(true, |encoder| local_path.encode(encoder))?;
-                        encoder
-                            .emit_enum_variant_arg(false, |encoder| virtual_name.encode(encoder))?;
-                    })
+                    encoder.emit_enum_variant_arg(true, |encoder| local_path.encode(encoder))?;
+                    encoder.emit_enum_variant_arg(false, |encoder| virtual_name.encode(encoder))?;
+                    Ok(())
                 }),
         })
     }
index 1b4315896321f9fc77b2302c8432dfc985a65254..b9730a1e420bc87dcaa8345a1cba882f7ee72446 100644 (file)
         as_ptr,
         as_str,
         asm,
+        asm_const,
+        asm_experimental_arch,
+        asm_sym,
         assert,
         assert_inhabited,
         assert_macro,
         div_assign,
         doc,
         doc_alias,
+        doc_auto_cfg,
         doc_cfg,
         doc_cfg_hide,
         doc_keyword,
         rustc_partition_reused,
         rustc_peek,
         rustc_peek_definite_init,
-        rustc_peek_indirectly_mutable,
         rustc_peek_liveness,
         rustc_peek_maybe_init,
         rustc_peek_maybe_uninit,
index d9eb299e2fd350781725927aade13b5bfad1166c..4768c9e2db5e109ddca539d463d9b8fb381968ed 100644 (file)
@@ -68,8 +68,10 @@ pub struct ArgAttribute: u16 {
             const NonNull   = 1 << 3;
             const ReadOnly  = 1 << 4;
             const InReg     = 1 << 5;
-            // NoAlias on &mut arguments can only be used with LLVM >= 12 due to miscompiles
-            // in earlier versions. FIXME: Remove this distinction once possible.
+            // Due to past miscompiles in LLVM, we use a separate attribute for
+            // &mut arguments, so that the codegen backend can decide whether
+            // or not to actually emit the attribute. It can also be controlled
+            // with the `-Zmutable-noalias` debugging option.
             const NoAliasMutRef = 1 << 6;
         }
     }
index 2c71fb8afeedeb54cb3339e22169e71a7c3c7f1d..ca3550e9278d10426b2a7902e695c01849f60157 100644 (file)
@@ -2,7 +2,7 @@
 
 pub fn target() -> Target {
     let mut base = super::apple_base::opts("macos");
-    base.cpu = "apple-a12".to_string();
+    base.cpu = "apple-a14".to_string();
     base.max_atomic_width = Some(128);
 
     // FIXME: The leak sanitizer currently fails the tests, see #88132.
index 71ee6deb07f903b5c64b9b46d8e5ec59e9c6c1bd..a393858879bfe725ab4c239e6da04dbec1622cb5 100644 (file)
@@ -8,6 +8,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
         options: TargetOptions {
+            features: "+outline-atomics".to_string(),
             max_atomic_width: Some(128),
             mcount: "\u{1}_mcount".to_string(),
             endian: Endian::Big,
index e05360ea45c6c5b677f07ace67752a0a11f3a31b..e75100f1435115300f61dd274db7b86988d5ed17 100644 (file)
@@ -12,6 +12,7 @@ pub fn target() -> Target {
         arch: "aarch64".to_string(),
         options: TargetOptions {
             abi: "ilp32".to_string(),
+            features: "+outline-atomics".to_string(),
             mcount: "\u{1}_mcount".to_string(),
             endian: Endian::Big,
             ..base
index c8d46adbfd92ba17b8358aad26430538dffa1005..850381f7fb073e6fb12c3dd1dc736cc7cdcb2dc5 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
         options: TargetOptions {
+            features: "+outline-atomics".to_string(),
             mcount: "\u{1}_mcount".to_string(),
             max_atomic_width: Some(128),
             supported_sanitizers: SanitizerSet::ADDRESS
index 8522405f61feb50fbb2972a9990f72994b6816f6..1c931d5a705f0df3b95f75363f15ffb93bedf7c4 100644 (file)
@@ -8,6 +8,7 @@ pub fn target() -> Target {
         arch: "aarch64".to_string(),
         options: TargetOptions {
             abi: "ilp32".to_string(),
+            features: "+outline-atomics".to_string(),
             max_atomic_width: Some(128),
             mcount: "\u{1}_mcount".to_string(),
             ..super::linux_gnu_base::opts()
index 6a16b4ce419647f0569220f47e35f6f68540b0c1..0770f3496c2792bc87fbed8dc393fa6c4e9e385d 100644 (file)
@@ -9,6 +9,10 @@ pub fn target() -> Target {
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions { mcount: "\u{1}_mcount".to_string(), ..base },
+        options: TargetOptions {
+            features: "+outline-atomics".to_string(),
+            mcount: "\u{1}_mcount".to_string(),
+            ..base
+        },
     }
 }
index 484593dcf4d785073feb7427d64f22c47b900714..69b90bf10fe6a131d3c96e6da2b27d1db190ffe1 100644 (file)
@@ -957,6 +957,8 @@ fn $module() {
     ("armv6k-nintendo-3ds", armv6k_nintendo_3ds),
 
     ("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf),
+
+    ("x86_64-unknown-none", x86_64_unknown_none),
 }
 
 /// Warnings encountered when parsing the target `json`.
@@ -2069,7 +2071,7 @@ macro_rules! key {
     /// JSON decoding.
     pub fn search(
         target_triple: &TargetTriple,
-        sysroot: &PathBuf,
+        sysroot: &Path,
     ) -> Result<(Target, TargetWarnings), String> {
         use rustc_serialize::json;
         use std::env;
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs
new file mode 100644 (file)
index 0000000..722409d
--- /dev/null
@@ -0,0 +1,41 @@
+// Generic x86-64 target for bare-metal code - Floating point disabled
+//
+// Can be used in conjunction with the `target-feature` and
+// `target-cpu` compiler flags to opt-in more hardware-specific
+// features.
+
+use super::{
+    CodeModel, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, RelroLevel, StackProbeType,
+    Target, TargetOptions,
+};
+
+pub fn target() -> Target {
+    let opts = TargetOptions {
+        cpu: "x86-64".to_string(),
+        max_atomic_width: Some(64),
+        // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
+        stack_probes: StackProbeType::Call,
+        position_independent_executables: true,
+        static_position_independent_executables: true,
+        relro_level: RelroLevel::Full,
+        relocation_model: RelocModel::Pic,
+        linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
+        linker: Some("rust-lld".to_owned()),
+        features:
+            "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float"
+                .to_string(),
+        executables: true,
+        disable_redzone: true,
+        panic_strategy: PanicStrategy::Abort,
+        code_model: Some(CodeModel::Kernel),
+        ..Default::default()
+    };
+    Target {
+        llvm_target: "x86_64-unknown-none-elf".to_string(),
+        pointer_width: 64,
+        data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+            .to_string(),
+        arch: "x86_64".to_string(),
+        options: opts,
+    }
+}
index 5d17693dc0820dd9336aa803167cee7243e42089..0b88eb7572ad0fd3f240113bc9171fd3aa87c599 100644 (file)
@@ -1838,7 +1838,7 @@ fn annotate_source_of_ambiguity(
                 post.iter().map(|p| format!("- {}", p)).take(4).collect::<Vec<_>>().join("\n"),
                 post.len() - 4,
             )
-        } else if post.len() > 1 || (post.len() == 1 && post[0].contains("\n")) {
+        } else if post.len() > 1 || (post.len() == 1 && post[0].contains('\n')) {
             format!(":\n{}", post.iter().map(|p| format!("- {}", p)).collect::<Vec<_>>().join("\n"),)
         } else if post.len() == 1 {
             format!(": `{}`", post[0])
@@ -2000,19 +2000,14 @@ fn maybe_suggest_unsized_generics(
         let sized_trait = self.tcx.lang_items().sized_trait();
         debug!("maybe_suggest_unsized_generics: generics.params={:?}", generics.params);
         debug!("maybe_suggest_unsized_generics: generics.where_clause={:?}", generics.where_clause);
-        let param = generics
-            .params
-            .iter()
-            .filter(|param| param.span == span)
-            .filter(|param| {
-                // Check that none of the explicit trait bounds is `Sized`. Assume that an explicit
-                // `Sized` bound is there intentionally and we don't need to suggest relaxing it.
-                param
-                    .bounds
-                    .iter()
-                    .all(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) != sized_trait)
-            })
-            .next();
+        let param = generics.params.iter().filter(|param| param.span == span).find(|param| {
+            // Check that none of the explicit trait bounds is `Sized`. Assume that an explicit
+            // `Sized` bound is there intentionally and we don't need to suggest relaxing it.
+            param
+                .bounds
+                .iter()
+                .all(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) != sized_trait)
+        });
         let param = match param {
             Some(param) => param,
             _ => return,
index 428873b8d3dda8ae2676f93c3527f030deb8bbad..8f247184e880873d6f1d4a1419ee959c2753b16e 100644 (file)
@@ -748,6 +748,9 @@ fn vtable_trait_first_method_offset<'tcx>(
 ) -> usize {
     let (trait_to_be_found, trait_owning_vtable) = key;
 
+    // #90177
+    let trait_to_be_found_erased = tcx.erase_regions(trait_to_be_found);
+
     let vtable_segment_callback = {
         let mut vtable_base = 0;
 
@@ -757,7 +760,7 @@ fn vtable_trait_first_method_offset<'tcx>(
                     vtable_base += COMMON_VTABLE_ENTRIES.len();
                 }
                 VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
-                    if trait_ref == trait_to_be_found {
+                    if tcx.erase_regions(trait_ref) == trait_to_be_found_erased {
                         return ControlFlow::Break(vtable_base);
                     }
                     vtable_base += util::count_own_vtable_entries(tcx, trait_ref);
index db8a6d962049540f9e257c8e50b1e6a136697dfe..b8c66931cbe52ef093ce8cfb2629d29f72ec7268 100644 (file)
@@ -1734,7 +1734,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
         ty: ret_type,
     });
 
-    confirm_param_env_candidate(selcx, obligation, predicate, false)
+    confirm_param_env_candidate(selcx, obligation, predicate, true)
 }
 
 fn confirm_param_env_candidate<'cx, 'tcx>(
@@ -1754,8 +1754,18 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
     );
 
     let cache_projection = cache_entry.projection_ty;
-    let obligation_projection = obligation.predicate;
     let mut nested_obligations = Vec::new();
+    let obligation_projection = obligation.predicate;
+    let obligation_projection = ensure_sufficient_stack(|| {
+        normalize_with_depth_to(
+            selcx,
+            obligation.param_env,
+            obligation.cause.clone(),
+            obligation.recursion_depth + 1,
+            obligation_projection,
+            &mut nested_obligations,
+        )
+    });
     let cache_projection = if potentially_unnormalized_candidate {
         ensure_sufficient_stack(|| {
             normalize_with_depth_to(
@@ -1771,6 +1781,8 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
         cache_projection
     };
 
+    debug!(?cache_projection, ?obligation_projection);
+
     match infcx.at(cause, param_env).eq(cache_projection, obligation_projection) {
         Ok(InferOk { value: _, obligations }) => {
             nested_obligations.extend(obligations);
index 84721922c8dd738493f79e10186638894a32c9a4..2f1f7971a7926aa433352e92bfe306c48d26d8b0 100644 (file)
@@ -620,23 +620,37 @@ fn confirm_closure_candidate(
             _ => bug!("closure candidate for non-closure {:?}", obligation),
         };
 
+        let obligation_predicate = obligation.predicate.to_poly_trait_ref();
+        let Normalized { value: obligation_predicate, mut obligations } =
+            ensure_sufficient_stack(|| {
+                normalize_with_depth(
+                    self,
+                    obligation.param_env,
+                    obligation.cause.clone(),
+                    obligation.recursion_depth + 1,
+                    obligation_predicate,
+                )
+            });
+
         let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
-        let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
-            normalize_with_depth(
-                self,
-                obligation.param_env,
-                obligation.cause.clone(),
-                obligation.recursion_depth + 1,
-                trait_ref,
-            )
-        });
+        let Normalized { value: trait_ref, obligations: trait_ref_obligations } =
+            ensure_sufficient_stack(|| {
+                normalize_with_depth(
+                    self,
+                    obligation.param_env,
+                    obligation.cause.clone(),
+                    obligation.recursion_depth + 1,
+                    trait_ref,
+                )
+            });
 
         debug!(?closure_def_id, ?trait_ref, ?obligations, "confirm closure candidate obligations");
 
+        obligations.extend(trait_ref_obligations);
         obligations.extend(self.confirm_poly_trait_refs(
             obligation.cause.clone(),
             obligation.param_env,
-            obligation.predicate.to_poly_trait_ref(),
+            obligation_predicate,
             trait_ref,
         )?);
 
@@ -948,52 +962,24 @@ fn confirm_builtin_unsize_candidate(
                 let tail_field_ty = tcx.type_of(tail_field.did);
 
                 let mut unsizing_params = GrowableBitSet::new_empty();
-                if tcx.features().relaxed_struct_unsize {
-                    for arg in tail_field_ty.walk(tcx) {
-                        if let Some(i) = maybe_unsizing_param_idx(arg) {
-                            unsizing_params.insert(i);
-                        }
-                    }
-
-                    // Ensure none of the other fields mention the parameters used
-                    // in unsizing.
-                    for field in prefix_fields {
-                        for arg in tcx.type_of(field.did).walk(tcx) {
-                            if let Some(i) = maybe_unsizing_param_idx(arg) {
-                                unsizing_params.remove(i);
-                            }
-                        }
+                for arg in tail_field_ty.walk(tcx) {
+                    if let Some(i) = maybe_unsizing_param_idx(arg) {
+                        unsizing_params.insert(i);
                     }
+                }
 
-                    if unsizing_params.is_empty() {
-                        return Err(Unimplemented);
-                    }
-                } else {
-                    let mut found = false;
-                    for arg in tail_field_ty.walk(tcx) {
+                // Ensure none of the other fields mention the parameters used
+                // in unsizing.
+                for field in prefix_fields {
+                    for arg in tcx.type_of(field.did).walk(tcx) {
                         if let Some(i) = maybe_unsizing_param_idx(arg) {
-                            unsizing_params.insert(i);
-                            found = true;
+                            unsizing_params.remove(i);
                         }
                     }
-                    if !found {
-                        return Err(Unimplemented);
-                    }
+                }
 
-                    // Ensure none of the other fields mention the parameters used
-                    // in unsizing.
-                    // FIXME(eddyb) cache this (including computing `unsizing_params`)
-                    // by putting it in a query; it would only need the `DefId` as it
-                    // looks at declared field types, not anything substituted.
-                    for field in prefix_fields {
-                        for arg in tcx.type_of(field.did).walk(tcx) {
-                            if let Some(i) = maybe_unsizing_param_idx(arg) {
-                                if unsizing_params.contains(i) {
-                                    return Err(Unimplemented);
-                                }
-                            }
-                        }
-                    }
+                if unsizing_params.is_empty() {
+                    return Err(Unimplemented);
                 }
 
                 // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
index 60676ad3f4f606b9cec87aec869d4083b539f098..481bfa4a26b36f6c79b1ce3db2833bebdcd8f085 100644 (file)
@@ -320,10 +320,7 @@ pub fn is_intercrate(&self) -> bool {
 
     /// Returns `true` if the trait predicate is considerd `const` to this selection context.
     pub fn is_trait_predicate_const(&self, pred: ty::TraitPredicate<'_>) -> bool {
-        match pred.constness {
-            ty::BoundConstness::ConstIfConst if self.is_in_const_context => true,
-            _ => false,
-        }
+        matches!(pred.constness, ty::BoundConstness::ConstIfConst) && self.is_in_const_context
     }
 
     /// Returns `true` if the predicate is considered `const` to
index 5befe44802f54a1341e140109ffb92625fffd426..84327a2880e18c6499eb4eaa82c41beaae735124 100644 (file)
@@ -344,7 +344,7 @@ pub fn create_substs_for_generic_args<'a>(
                                             "reorder the arguments: {}: `<{}>`",
                                             param_types_present
                                                 .into_iter()
-                                                .map(|ord| format!("{}s", ord.to_string()))
+                                                .map(|ord| format!("{}s", ord))
                                                 .collect::<Vec<String>>()
                                                 .join(", then "),
                                             ordered_params
index 78849b276d6bfb80f610c574a021f4b7efb91d3a..511a2d7ddacf96e42f453690267c1094f0e995ef 100644 (file)
@@ -436,11 +436,8 @@ fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError) {
                     // Very crude check to see whether the expression must be wrapped
                     // in parentheses for the suggestion to work (issue #89497).
                     // Can/should be extended in the future.
-                    let needs_parens = !has_parens
-                        && match self.expr.kind {
-                            hir::ExprKind::Cast(..) => true,
-                            _ => false,
-                        };
+                    let needs_parens =
+                        !has_parens && matches!(self.expr.kind, hir::ExprKind::Cast(..));
 
                     let mut suggestion = vec![(self.expr.span.shrink_to_lo(), sugg)];
                     if needs_parens {
index d5b631df058aef9c12428677dbfa52f7aec344d3..7c262dcf723390fbe58ef980b862666e536d2986 100644 (file)
@@ -453,6 +453,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
     Ok(())
 }
 
+#[instrument(level = "debug", skip(infcx))]
 fn extract_spans_for_error_reporting<'a, 'tcx>(
     infcx: &infer::InferCtxt<'a, 'tcx>,
     terr: &TypeError<'_>,
index 2b3672211e4f582e951922e2ff2c555c4b36866f..9bbe52591472885655471958f9bf7632c42385b4 100644 (file)
@@ -29,6 +29,7 @@ pub fn emit_coerce_suggestions(
         expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
     ) {
         self.annotate_expected_due_to_let_ty(err, expr);
+        self.suggest_box_deref(err, expr, expected, expr_ty);
         self.suggest_compatible_variants(err, expr, expected, expr_ty);
         self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr);
         if self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) {
@@ -167,6 +168,23 @@ fn annotate_expected_due_to_let_ty(
         }
     }
 
+    fn suggest_box_deref(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        expr: &hir::Expr<'_>,
+        expected: Ty<'tcx>,
+        expr_ty: Ty<'tcx>,
+    ) {
+        if expr_ty.is_box() && expr_ty.boxed_ty() == expected {
+            err.span_suggestion_verbose(
+                expr.span.shrink_to_lo(),
+                "try dereferencing the `Box`",
+                "*".to_string(),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+
     /// If the expected type is an enum (Issue #55250) with any variants whose
     /// sole field is of the found type, suggest such variants. (Issue #42764)
     fn suggest_compatible_variants(
@@ -428,7 +446,7 @@ pub fn check_ref(
                 (&ty::Str, &ty::Array(arr, _) | &ty::Slice(arr)) if arr == self.tcx.types.u8 => {
                     if let hir::ExprKind::Lit(_) = expr.kind {
                         if let Ok(src) = sm.span_to_snippet(sp) {
-                            if let Some(_) = replace_prefix(&src, "b\"", "\"") {
+                            if replace_prefix(&src, "b\"", "\"").is_some() {
                                 let pos = sp.lo() + BytePos(1);
                                 return Some((
                                     sp.with_hi(pos),
@@ -444,7 +462,7 @@ pub fn check_ref(
                 (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => {
                     if let hir::ExprKind::Lit(_) = expr.kind {
                         if let Ok(src) = sm.span_to_snippet(sp) {
-                            if let Some(_) = replace_prefix(&src, "\"", "b\"") {
+                            if replace_prefix(&src, "\"", "b\"").is_some() {
                                 return Some((
                                     sp.shrink_to_lo(),
                                     "consider adding a leading `b`",
index 3846aad2cfc103e2447cb27de49bea72afb9a23d..3cba7991ccaf308f5657233e1b00426d52700c11 100644 (file)
@@ -1698,15 +1698,15 @@ fn check_field(
                         // Save the index of all fields regardless of their visibility in case
                         // of error recovery.
                         self.write_field_index(expr.hir_id, index);
+                        let adjustments = self.adjust_steps(&autoderef);
                         if field.vis.is_accessible_from(def_scope, self.tcx) {
-                            let adjustments = self.adjust_steps(&autoderef);
                             self.apply_adjustments(base, adjustments);
                             self.register_predicates(autoderef.into_obligations());
 
                             self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
                             return field_ty;
                         }
-                        private_candidate = Some((base_def.did, field_ty));
+                        private_candidate = Some((adjustments, base_def.did, field_ty));
                     }
                 }
                 ty::Tuple(tys) => {
@@ -1729,7 +1729,10 @@ fn check_field(
         }
         self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
 
-        if let Some((did, field_ty)) = private_candidate {
+        if let Some((adjustments, did, field_ty)) = private_candidate {
+            // (#90483) apply adjustments to avoid ExprUseVisitor from
+            // creating erroneous projection.
+            self.apply_adjustments(base, adjustments);
             self.ban_private_field_access(expr, expr_t, field, did);
             return field_ty;
         }
@@ -2055,8 +2058,7 @@ fn get_field_candidates(
     ) -> Option<(&Vec<ty::FieldDef>, SubstsRef<'tcx>)> {
         debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_t);
 
-        let mut autoderef = self.autoderef(span, base_t);
-        while let Some((base_t, _)) = autoderef.next() {
+        for (base_t, _) in self.autoderef(span, base_t) {
             match base_t.kind() {
                 ty::Adt(base_def, substs) if !base_def.is_enum() => {
                     let fields = &base_def.non_enum_variant().fields;
index 296e45337ed1035b3ed1868396f371ba6b045c86..e5da33d113e7c48e95ab6e626d4e0dc8ff0711f8 100644 (file)
@@ -176,7 +176,7 @@ fn fallback_opaque_type_vars(&self, ty: Ty<'tcx>) -> bool {
             .type_var_origin(ty)
             .map(|origin| origin.span)
             .unwrap_or(rustc_span::DUMMY_SP);
-        let oty = self.inner.borrow().opaque_types_vars.get(ty).map(|v| *v);
+        let oty = self.inner.borrow().opaque_types_vars.get(ty).copied();
         if let Some(opaque_ty) = oty {
             debug!(
                 "fallback_opaque_type_vars(ty={:?}): falling back to opaque type {:?}",
index b3e18dab363692e303e13e4977355579d1967c68..7d9483201f6a547c5e3ae407e473a8ad19f7e729 100644 (file)
@@ -1045,34 +1045,32 @@ fn point_at_type_arg_instead_of_call_if_possible(
         call_expr: &'tcx hir::Expr<'tcx>,
     ) {
         if let hir::ExprKind::Call(path, _) = &call_expr.kind {
-            if let hir::ExprKind::Path(qpath) = &path.kind {
-                if let hir::QPath::Resolved(_, path) = &qpath {
-                    for error in errors {
-                        if let ty::PredicateKind::Trait(predicate) =
-                            error.obligation.predicate.kind().skip_binder()
+            if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind {
+                for error in errors {
+                    if let ty::PredicateKind::Trait(predicate) =
+                        error.obligation.predicate.kind().skip_binder()
+                    {
+                        // If any of the type arguments in this path segment caused the
+                        // `FulfillmentError`, point at its span (#61860).
+                        for arg in path
+                            .segments
+                            .iter()
+                            .filter_map(|seg| seg.args.as_ref())
+                            .flat_map(|a| a.args.iter())
                         {
-                            // If any of the type arguments in this path segment caused the
-                            // `FulfillmentError`, point at its span (#61860).
-                            for arg in path
-                                .segments
-                                .iter()
-                                .filter_map(|seg| seg.args.as_ref())
-                                .flat_map(|a| a.args.iter())
-                            {
-                                if let hir::GenericArg::Type(hir_ty) = &arg {
-                                    if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
-                                        &hir_ty.kind
-                                    {
-                                        // Avoid ICE with associated types. As this is best
-                                        // effort only, it's ok to ignore the case. It
-                                        // would trigger in `is_send::<T::AssocType>();`
-                                        // from `typeck-default-trait-impl-assoc-type.rs`.
-                                    } else {
-                                        let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, hir_ty);
-                                        let ty = self.resolve_vars_if_possible(ty);
-                                        if ty == predicate.self_ty() {
-                                            error.obligation.cause.make_mut().span = hir_ty.span;
-                                        }
+                            if let hir::GenericArg::Type(hir_ty) = &arg {
+                                if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
+                                    &hir_ty.kind
+                                {
+                                    // Avoid ICE with associated types. As this is best
+                                    // effort only, it's ok to ignore the case. It
+                                    // would trigger in `is_send::<T::AssocType>();`
+                                    // from `typeck-default-trait-impl-assoc-type.rs`.
+                                } else {
+                                    let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, hir_ty);
+                                    let ty = self.resolve_vars_if_possible(ty);
+                                    if ty == predicate.self_ty() {
+                                        error.obligation.cause.make_mut().span = hir_ty.span;
                                     }
                                 }
                             }
index 8007b9f23776a169f141afa3d63ca7f61617839a..13f475cd9e02681073e542c3e961e3f373e5e6f5 100644 (file)
@@ -1208,7 +1208,7 @@ fn suggest_valid_traits(
             let edition_fix = candidates
                 .iter()
                 .find(|did| self.tcx.is_diagnostic_item(sym::TryInto, **did))
-                .map(|&d| d);
+                .copied();
 
             err.help("items from traits can only be used if the trait is in scope");
             let msg = format!(
index aea1bcd95df21a63504981b9e25075a54882d89f..dd09474533119d90e12108dfc05bfb3f44702a77 100644 (file)
@@ -399,12 +399,9 @@ fn check_overloaded_binop(
                     }
                 };
                 if let Ref(_, rty, _) = lhs_ty.kind() {
-                    if {
-                        self.infcx.type_is_copy_modulo_regions(self.param_env, rty, lhs_expr.span)
-                            && self
-                                .lookup_op_method(rty, &[rhs_ty], Op::Binary(op, is_assign))
-                                .is_ok()
-                    } {
+                    if self.infcx.type_is_copy_modulo_regions(self.param_env, rty, lhs_expr.span)
+                        && self.lookup_op_method(rty, &[rhs_ty], Op::Binary(op, is_assign)).is_ok()
+                    {
                         if let Ok(lstring) = source_map.span_to_snippet(lhs_expr.span) {
                             let msg = &format!(
                                 "`{}{}` can be used on `{}`, you can dereference `{}`",
index 230a576046a479c9dcf5d296bd7209789bd6d753..86d4e4d2b115b5857959bd115066bc850a5a8543 100644 (file)
@@ -103,7 +103,7 @@ macro_rules! ignore_err {
     };
 }
 
-trait OutlivesEnvironmentExt<'tcx> {
+pub(crate) trait OutlivesEnvironmentExt<'tcx> {
     fn add_implied_bounds(
         &mut self,
         infcx: &InferCtxt<'a, 'tcx>,
index 9c7b0b2cacb062e397ed86fedc7b8fa8f518b4bb..774d8078e52ca31171213b8070848902040aae07 100644 (file)
@@ -86,18 +86,55 @@ pub fn closure_analyze(&self, body: &'tcx hir::Body<'tcx>) {
 /// Intermediate format to store the hir_id pointing to the use that resulted in the
 /// corresponding place being captured and a String which contains the captured value's
 /// name (i.e: a.b.c)
-type CapturesInfo = (Option<hir::HirId>, String);
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+enum UpvarMigrationInfo {
+    /// We previously captured all of `x`, but now we capture some sub-path.
+    CapturingPrecise { source_expr: Option<hir::HirId>, var_name: String },
+    CapturingNothing {
+        // where the variable appears in the closure (but is not captured)
+        use_span: Span,
+    },
+}
+
+/// Reasons that we might issue a migration warning.
+#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
+struct MigrationWarningReason {
+    /// When we used to capture `x` in its entirety, we implemented the auto-trait(s)
+    /// in this vec, but now we don't.
+    auto_traits: Vec<&'static str>,
+
+    /// When we used to capture `x` in its entirety, we would execute some destructors
+    /// at a different time.
+    drop_order: bool,
+}
+
+impl MigrationWarningReason {
+    fn migration_message(&self) -> String {
+        let base = "changes to closure capture in Rust 2021 will affect";
+        if !self.auto_traits.is_empty() && self.drop_order {
+            format!("{} drop order and which traits the closure implements", base)
+        } else if self.drop_order {
+            format!("{} drop order", base)
+        } else {
+            format!("{} which traits the closure implements", base)
+        }
+    }
+}
 
-/// Intermediate format to store information needed to generate migration lint. The tuple
-/// contains the hir_id pointing to the use that resulted in the
-/// corresponding place being captured, a String which contains the captured value's
-/// name (i.e: a.b.c) and a String which contains the reason why migration is needed for that
-/// capture
-type MigrationNeededForCapture = (Option<hir::HirId>, String, String);
+/// Intermediate format to store information needed to generate a note in the migration lint.
+struct MigrationLintNote {
+    captures_info: UpvarMigrationInfo,
+
+    /// reasons why migration is needed for this capture
+    reason: MigrationWarningReason,
+}
 
 /// Intermediate format to store the hir id of the root variable and a HashSet containing
 /// information on why the root variable should be fully captured
-type MigrationDiagnosticInfo = (hir::HirId, Vec<MigrationNeededForCapture>);
+struct NeededMigration {
+    var_hir_id: hir::HirId,
+    diagnostics_info: Vec<MigrationLintNote>,
+}
 
 struct InferBorrowKindVisitor<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
@@ -707,47 +744,66 @@ fn perform_2229_migration_anaysis(
                  closure_head_span,
                 |lint| {
                     let mut diagnostics_builder = lint.build(
-                        format!(
-                            "changes to closure capture in Rust 2021 will affect {}",
-                            reasons
-                        )
-                        .as_str(),
+                        &reasons.migration_message(),
                     );
-                    for (var_hir_id, diagnostics_info) in need_migrations.iter() {
+                    for NeededMigration { var_hir_id, diagnostics_info } in &need_migrations {
                         // Labels all the usage of the captured variable and why they are responsible
                         // for migration being needed
-                        for (captured_hir_id, captured_name, reasons) in diagnostics_info.iter() {
-                            if let Some(captured_hir_id) = captured_hir_id {
-                                let cause_span = self.tcx.hir().span(*captured_hir_id);
-                                diagnostics_builder.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`",
-                                    self.tcx.hir().name(*var_hir_id),
-                                    captured_name,
-                                ));
+                        for lint_note in diagnostics_info.iter() {
+                            match &lint_note.captures_info {
+                                UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => {
+                                    let cause_span = self.tcx.hir().span(*capture_expr_id);
+                                    diagnostics_builder.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`",
+                                        self.tcx.hir().name(*var_hir_id),
+                                        captured_name,
+                                    ));
+                                }
+                                UpvarMigrationInfo::CapturingNothing { use_span } => {
+                                    diagnostics_builder.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect",
+                                        self.tcx.hir().name(*var_hir_id),
+                                    ));
+                                }
+
+                                _ => { }
                             }
 
                             // Add a label pointing to where a captured variable affected by drop order
                             // is dropped
-                            if reasons.contains("drop order") {
+                            if lint_note.reason.drop_order {
                                 let drop_location_span = drop_location_span(self.tcx, &closure_hir_id);
 
-                                diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure",
-                                    self.tcx.hir().name(*var_hir_id),
-                                    captured_name,
-                                ));
+                                match &lint_note.captures_info {
+                                    UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
+                                        diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure",
+                                            self.tcx.hir().name(*var_hir_id),
+                                            captured_name,
+                                        ));
+                                    }
+                                    UpvarMigrationInfo::CapturingNothing { use_span: _ } => {
+                                        diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure",
+                                            v = self.tcx.hir().name(*var_hir_id),
+                                        ));
+                                    }
+                                }
                             }
 
                             // Add a label explaining why a closure no longer implements a trait
-                            if reasons.contains("trait implementation") {
-                                let missing_trait = &reasons[..reasons.find("trait implementation").unwrap() - 1];
-
-                                diagnostics_builder.span_label(closure_head_span, format!("in Rust 2018, this closure implements {} as `{}` implements {}, but in Rust 2021, this closure will no longer implement {} as `{}` does not implement {}",
-                                    missing_trait,
-                                    self.tcx.hir().name(*var_hir_id),
-                                    missing_trait,
-                                    missing_trait,
-                                    captured_name,
-                                    missing_trait,
-                                ));
+                            for &missing_trait in &lint_note.reason.auto_traits {
+                                // not capturing something anymore cannot cause a trait to fail to be implemented:
+                                match &lint_note.captures_info {
+                                    UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
+                                        let var_name = self.tcx.hir().name(*var_hir_id);
+                                        diagnostics_builder.span_label(closure_head_span, format!("\
+                                        in Rust 2018, this closure implements {missing_trait} \
+                                        as `{var_name}` implements {missing_trait}, but in Rust 2021, \
+                                        this closure will no longer implement {missing_trait} \
+                                        because `{var_name}` is not fully captured \
+                                        and `{captured_name}` does not implement {missing_trait}"));
+                                    }
+
+                                    // Cannot happen: if we don't capture a variable, we impl strictly more traits
+                                    UpvarMigrationInfo::CapturingNothing { use_span } => span_bug!(*use_span, "missing trait from not capturing something"),
+                                }
                             }
                         }
                     }
@@ -840,25 +896,16 @@ fn perform_2229_migration_anaysis(
     /// Combines all the reasons for 2229 migrations
     fn compute_2229_migrations_reasons(
         &self,
-        auto_trait_reasons: FxHashSet<&str>,
-        drop_reason: bool,
-    ) -> String {
-        let mut reasons = String::new();
-
-        if !auto_trait_reasons.is_empty() {
-            reasons = format!(
-                "{} trait implementation for closure",
-                auto_trait_reasons.clone().into_iter().collect::<Vec<&str>>().join(", ")
-            );
-        }
+        auto_trait_reasons: FxHashSet<&'static str>,
+        drop_order: bool,
+    ) -> MigrationWarningReason {
+        let mut reasons = MigrationWarningReason::default();
 
-        if !auto_trait_reasons.is_empty() && drop_reason {
-            reasons = format!("{} and ", reasons);
+        for auto_trait in auto_trait_reasons {
+            reasons.auto_traits.push(auto_trait);
         }
 
-        if drop_reason {
-            reasons = format!("{}drop order", reasons);
-        }
+        reasons.drop_order = drop_order;
 
         reasons
     }
@@ -874,7 +921,7 @@ fn compute_2229_migrations_for_trait(
         min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
         var_hir_id: hir::HirId,
         closure_clause: hir::CaptureBy,
-    ) -> Option<FxHashMap<CapturesInfo, FxHashSet<&str>>> {
+    ) -> Option<FxHashMap<UpvarMigrationInfo, FxHashSet<&'static str>>> {
         let auto_traits_def_id = vec![
             self.tcx.lang_items().clone_trait(),
             self.tcx.lang_items().sync_trait(),
@@ -963,7 +1010,10 @@ fn compute_2229_migrations_for_trait(
 
             if !capture_problems.is_empty() {
                 problematic_captures.insert(
-                    (capture.info.path_expr_id, capture.to_string(self.tcx)),
+                    UpvarMigrationInfo::CapturingPrecise {
+                        source_expr: capture.info.path_expr_id,
+                        var_name: capture.to_string(self.tcx),
+                    },
                     capture_problems,
                 );
             }
@@ -986,6 +1036,7 @@ fn compute_2229_migrations_for_trait(
     ///
     /// This function only returns a HashSet of CapturesInfo for significant drops. If there
     /// are no significant drops than None is returned
+    #[instrument(level = "debug", skip(self))]
     fn compute_2229_migrations_for_drop(
         &self,
         closure_def_id: DefId,
@@ -993,25 +1044,41 @@ fn compute_2229_migrations_for_drop(
         min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
         closure_clause: hir::CaptureBy,
         var_hir_id: hir::HirId,
-    ) -> Option<FxHashSet<CapturesInfo>> {
+    ) -> Option<FxHashSet<UpvarMigrationInfo>> {
         let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
 
         if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) {
+            debug!("does not have significant drop");
             return None;
         }
 
         let Some(root_var_min_capture_list) = min_captures.and_then(|m| m.get(&var_hir_id)) else {
             // The upvar is mentioned within the closure but no path starting from it is
-            // used.
+            // used. This occurs when you have (e.g.)
+            //
+            // ```
+            // let x = move || {
+            //     let _ = y;
+            // });
+            // ```
+            debug!("no path starting from it is used");
+
 
             match closure_clause {
                 // Only migrate if closure is a move closure
-                hir::CaptureBy::Value => return Some(FxHashSet::default()),
+                hir::CaptureBy::Value => {
+                    let mut diagnostics_info = FxHashSet::default();
+                    let upvars = self.tcx.upvars_mentioned(closure_def_id).expect("must be an upvar");
+                    let upvar = upvars[&var_hir_id];
+                    diagnostics_info.insert(UpvarMigrationInfo::CapturingNothing { use_span: upvar.span });
+                    return Some(diagnostics_info);
+                }
                 hir::CaptureBy::Ref => {}
             }
 
             return None;
         };
+        debug!(?root_var_min_capture_list);
 
         let mut projections_list = Vec::new();
         let mut diagnostics_info = FxHashSet::default();
@@ -1021,19 +1088,24 @@ fn compute_2229_migrations_for_drop(
                 // Only care about captures that are moved into the closure
                 ty::UpvarCapture::ByValue(..) => {
                     projections_list.push(captured_place.place.projections.as_slice());
-                    diagnostics_info.insert((
-                        captured_place.info.path_expr_id,
-                        captured_place.to_string(self.tcx),
-                    ));
+                    diagnostics_info.insert(UpvarMigrationInfo::CapturingPrecise {
+                        source_expr: captured_place.info.path_expr_id,
+                        var_name: captured_place.to_string(self.tcx),
+                    });
                 }
                 ty::UpvarCapture::ByRef(..) => {}
             }
         }
 
+        debug!(?projections_list);
+        debug!(?diagnostics_info);
+
         let is_moved = !projections_list.is_empty();
+        debug!(?is_moved);
 
         let is_not_completely_captured =
             root_var_min_capture_list.iter().any(|capture| !capture.place.projections.is_empty());
+        debug!(?is_not_completely_captured);
 
         if is_moved
             && is_not_completely_captured
@@ -1066,15 +1138,16 @@ fn compute_2229_migrations_for_drop(
     /// Returns a tuple containing a vector of MigrationDiagnosticInfo, as well as a String
     /// containing the reason why root variables whose HirId is contained in the vector should
     /// be captured
+    #[instrument(level = "debug", skip(self))]
     fn compute_2229_migrations(
         &self,
         closure_def_id: DefId,
         closure_span: Span,
         closure_clause: hir::CaptureBy,
         min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
-    ) -> (Vec<MigrationDiagnosticInfo>, String) {
+    ) -> (Vec<NeededMigration>, MigrationWarningReason) {
         let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) else {
-            return (Vec::new(), String::new());
+            return (Vec::new(), MigrationWarningReason::default());
         };
 
         let mut need_migrations = Vec::new();
@@ -1083,7 +1156,7 @@ fn compute_2229_migrations(
 
         // Perform auto-trait analysis
         for (&var_hir_id, _) in upvars.iter() {
-            let mut responsible_captured_hir_ids = Vec::new();
+            let mut diagnostics_info = Vec::new();
 
             let auto_trait_diagnostic = if let Some(diagnostics_info) =
                 self.compute_2229_migrations_for_trait(min_captures, var_hir_id, closure_clause)
@@ -1115,34 +1188,33 @@ fn compute_2229_migrations(
 
             let mut capture_diagnostic = capture_diagnostic.into_iter().collect::<Vec<_>>();
             capture_diagnostic.sort();
-            for captured_info in capture_diagnostic.iter() {
+            for captures_info in capture_diagnostic {
                 // Get the auto trait reasons of why migration is needed because of that capture, if there are any
                 let capture_trait_reasons =
-                    if let Some(reasons) = auto_trait_diagnostic.get(captured_info) {
+                    if let Some(reasons) = auto_trait_diagnostic.get(&captures_info) {
                         reasons.clone()
                     } else {
                         FxHashSet::default()
                     };
 
                 // Check if migration is needed because of drop reorder as a result of that capture
-                let capture_drop_reorder_reason = drop_reorder_diagnostic.contains(captured_info);
+                let capture_drop_reorder_reason = drop_reorder_diagnostic.contains(&captures_info);
 
                 // Combine all the reasons of why the root variable should be captured as a result of
                 // auto trait implementation issues
                 auto_trait_migration_reasons.extend(capture_trait_reasons.clone());
 
-                responsible_captured_hir_ids.push((
-                    captured_info.0,
-                    captured_info.1.clone(),
-                    self.compute_2229_migrations_reasons(
+                diagnostics_info.push(MigrationLintNote {
+                    captures_info,
+                    reason: self.compute_2229_migrations_reasons(
                         capture_trait_reasons,
                         capture_drop_reorder_reason,
                     ),
-                ));
+                });
             }
 
-            if !capture_diagnostic.is_empty() {
-                need_migrations.push((var_hir_id, responsible_captured_hir_ids));
+            if !diagnostics_info.is_empty() {
+                need_migrations.push(NeededMigration { var_hir_id, diagnostics_info });
             }
         }
         (
@@ -2087,6 +2159,7 @@ fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol {
     tcx.hir().name(var_hir_id)
 }
 
+#[instrument(level = "debug", skip(tcx))]
 fn should_do_rust_2021_incompatible_closure_captures_analysis(
     tcx: TyCtxt<'_>,
     closure_id: hir::HirId,
@@ -2102,10 +2175,12 @@ fn should_do_rust_2021_incompatible_closure_captures_analysis(
 /// - s2: Comma separated names of the variables being migrated.
 fn migration_suggestion_for_2229(
     tcx: TyCtxt<'_>,
-    need_migrations: &Vec<MigrationDiagnosticInfo>,
+    need_migrations: &Vec<NeededMigration>,
 ) -> (String, String) {
-    let need_migrations_variables =
-        need_migrations.iter().map(|(v, _)| var_name(tcx, *v)).collect::<Vec<_>>();
+    let need_migrations_variables = need_migrations
+        .iter()
+        .map(|NeededMigration { var_hir_id: v, .. }| var_name(tcx, *v))
+        .collect::<Vec<_>>();
 
     let migration_ref_concat =
         need_migrations_variables.iter().map(|v| format!("&{}", v)).collect::<Vec<_>>().join(", ");
index 30aab38b1eb8522cd41e8689ca86e6f0ec4280d0..c1adc2894ccfcd365541de28932c886fb71ae4f5 100644 (file)
@@ -1,3 +1,4 @@
+use crate::check::regionck::OutlivesEnvironmentExt;
 use crate::check::{FnCtxt, Inherited};
 use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
 
 use rustc_hir::itemlikevisit::ParItemLikeVisitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::ItemKind;
+use rustc_infer::infer::outlives::env::OutlivesEnvironment;
+use rustc_infer::infer::outlives::obligations::TypeOutlives;
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::infer::{self, RegionckMode, SubregionOrigin};
 use rustc_middle::hir::map as hir_map;
-use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
 use rustc_middle::ty::{
-    self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+    self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitor,
+    WithConstness,
 };
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{sym, Ident, Symbol};
-use rustc_span::Span;
-use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
+use rustc_span::{Span, DUMMY_SP};
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, WellFormedLoc};
 
 use std::convert::TryInto;
@@ -253,6 +259,362 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                 .emit();
         }
     }
+
+    check_gat_where_clauses(tcx, trait_item, encl_trait_def_id);
+}
+
+/// Require that the user writes where clauses on GATs for the implicit
+/// outlives bounds involving trait parameters in trait functions and
+/// lifetimes passed as GAT substs. See `self-outlives-lint` test.
+///
+/// This trait will be our running example. We are currently WF checking the `Item` item...
+///
+/// ```rust
+/// trait LendingIterator {
+///   type Item<'me>; // <-- WF checking this trait item
+///
+///   fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
+/// }
+/// ```
+fn check_gat_where_clauses(
+    tcx: TyCtxt<'_>,
+    trait_item: &hir::TraitItem<'_>,
+    encl_trait_def_id: DefId,
+) {
+    let item = tcx.associated_item(trait_item.def_id);
+    // If the current trait item isn't a type, it isn't a GAT
+    if !matches!(item.kind, ty::AssocKind::Type) {
+        return;
+    }
+    let generics: &ty::Generics = tcx.generics_of(trait_item.def_id);
+    // If the current associated type doesn't have any (own) params, it's not a GAT
+    // FIXME(jackh726): we can also warn in the more general case
+    if generics.params.len() == 0 {
+        return;
+    }
+    let associated_items: &ty::AssocItems<'_> = tcx.associated_items(encl_trait_def_id);
+    let mut clauses: Option<FxHashSet<ty::Predicate<'_>>> = None;
+    // For every function in this trait...
+    // In our example, this would be the `next` method
+    for item in
+        associated_items.in_definition_order().filter(|item| matches!(item.kind, ty::AssocKind::Fn))
+    {
+        // The clauses we that we would require from this function
+        let mut function_clauses = FxHashSet::default();
+
+        let id = hir::HirId::make_owner(item.def_id.expect_local());
+        let param_env = tcx.param_env(item.def_id.expect_local());
+
+        let sig = tcx.fn_sig(item.def_id);
+        // Get the signature using placeholders. In our example, this would
+        // convert the late-bound 'a into a free region.
+        let sig = tcx.liberate_late_bound_regions(item.def_id, sig);
+        // Collect the arguments that are given to this GAT in the return type
+        // of  the function signature. In our example, the GAT in the return
+        // type is `<Self as LendingIterator>::Item<'a>`, so 'a and Self are arguments.
+        let (regions, types) =
+            GATSubstCollector::visit(tcx, trait_item.def_id.to_def_id(), sig.output());
+
+        // If both regions and types are empty, then this GAT isn't in the
+        // return type, and we shouldn't try to do clause analysis
+        // (particularly, doing so would end up with an empty set of clauses,
+        // since the current method would require none, and we take the
+        // intersection of requirements of all methods)
+        if types.is_empty() && regions.is_empty() {
+            continue;
+        }
+
+        // The types we can assume to be well-formed. In our example, this
+        // would be &'a mut Self, from the first argument.
+        let mut wf_tys = FxHashSet::default();
+        wf_tys.extend(sig.inputs());
+
+        // For each region argument (e.g., 'a in our example), check for a
+        // relationship to the type arguments (e.g., Self). If there is an
+        // outlives relationship (`Self: 'a`), then we want to ensure that is
+        // reflected in a where clause on the GAT itself.
+        for (region, region_idx) in &regions {
+            for (ty, ty_idx) in &types {
+                // In our example, requires that Self: 'a
+                if ty_known_to_outlive(tcx, id, param_env, &wf_tys, *ty, *region) {
+                    debug!(?ty_idx, ?region_idx);
+                    debug!("required clause: {} must outlive {}", ty, region);
+                    // Translate into the generic parameters of the GAT. In
+                    // our example, the type was Self, which will also be
+                    // Self in the GAT.
+                    let ty_param = generics.param_at(*ty_idx, tcx);
+                    let ty_param = tcx.mk_ty(ty::Param(ty::ParamTy {
+                        index: ty_param.index,
+                        name: ty_param.name,
+                    }));
+                    // Same for the region. In our example, 'a corresponds
+                    // to the 'me parameter.
+                    let region_param = generics.param_at(*region_idx, tcx);
+                    let region_param =
+                        tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
+                            def_id: region_param.def_id,
+                            index: region_param.index,
+                            name: region_param.name,
+                        }));
+                    // The predicate we expect to see. (In our example,
+                    // `Self: 'me`.)
+                    let clause = ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
+                        ty_param,
+                        region_param,
+                    ));
+                    let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
+                    function_clauses.insert(clause);
+                }
+            }
+        }
+
+        // For each region argument (e.g., 'a in our example), also check for a
+        // relationship to the other region arguments. If there is an
+        // outlives relationship, then we want to ensure that is
+        // reflected in a where clause on the GAT itself.
+        for (region_a, region_a_idx) in &regions {
+            for (region_b, region_b_idx) in &regions {
+                if region_a == region_b {
+                    continue;
+                }
+
+                if region_known_to_outlive(tcx, id, param_env, &wf_tys, *region_a, *region_b) {
+                    debug!(?region_a_idx, ?region_b_idx);
+                    debug!("required clause: {} must outlive {}", region_a, region_b);
+                    // Translate into the generic parameters of the GAT.
+                    let region_a_param = generics.param_at(*region_a_idx, tcx);
+                    let region_a_param =
+                        tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
+                            def_id: region_a_param.def_id,
+                            index: region_a_param.index,
+                            name: region_a_param.name,
+                        }));
+                    // Same for the region.
+                    let region_b_param = generics.param_at(*region_b_idx, tcx);
+                    let region_b_param =
+                        tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
+                            def_id: region_b_param.def_id,
+                            index: region_b_param.index,
+                            name: region_b_param.name,
+                        }));
+                    // The predicate we expect to see.
+                    let clause = ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(
+                        region_a_param,
+                        region_b_param,
+                    ));
+                    let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
+                    function_clauses.insert(clause);
+                }
+            }
+        }
+
+        // Imagine we have:
+        // ```
+        // trait Foo {
+        //   type Bar<'me>;
+        //   fn gimme(&self) -> Self::Bar<'_>;
+        //   fn gimme_default(&self) -> Self::Bar<'static>;
+        // }
+        // ```
+        // We only want to require clauses on `Bar` that we can prove from *all* functions (in this
+        // case, `'me` can be `static` from `gimme_default`)
+        match clauses.as_mut() {
+            Some(clauses) => {
+                clauses.drain_filter(|p| !function_clauses.contains(p));
+            }
+            None => {
+                clauses = Some(function_clauses);
+            }
+        }
+    }
+
+    // If there are any missing clauses, emit an error
+    let mut clauses = clauses.unwrap_or_default();
+    debug!(?clauses);
+    if !clauses.is_empty() {
+        let written_predicates: ty::GenericPredicates<'_> =
+            tcx.explicit_predicates_of(trait_item.def_id);
+        let mut clauses: Vec<_> = clauses
+            .drain_filter(|clause| !written_predicates.predicates.iter().any(|p| &p.0 == clause))
+            .map(|clause| format!("{}", clause))
+            .collect();
+        // We sort so that order is predictable
+        clauses.sort();
+        if !clauses.is_empty() {
+            let mut err = tcx.sess.struct_span_err(
+                trait_item.span,
+                &format!("Missing required bounds on {}", trait_item.ident),
+            );
+
+            let suggestion = format!(
+                "{} {}",
+                if !trait_item.generics.where_clause.predicates.is_empty() {
+                    ","
+                } else {
+                    " where"
+                },
+                clauses.join(", "),
+            );
+            err.span_suggestion(
+                trait_item.generics.where_clause.tail_span_for_suggestion(),
+                "add the required where clauses",
+                suggestion,
+                Applicability::MachineApplicable,
+            );
+
+            err.emit()
+        }
+    }
+}
+
+// FIXME(jackh726): refactor some of the shared logic between the two functions below
+
+/// Given a known `param_env` and a set of well formed types, can we prove that
+/// `ty` outlives `region`.
+fn ty_known_to_outlive<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    id: hir::HirId,
+    param_env: ty::ParamEnv<'tcx>,
+    wf_tys: &FxHashSet<Ty<'tcx>>,
+    ty: Ty<'tcx>,
+    region: ty::Region<'tcx>,
+) -> bool {
+    // Unfortunately, we have to use a new `InferCtxt` each call, because
+    // region constraints get added and solved there and we need to test each
+    // call individually.
+    tcx.infer_ctxt().enter(|infcx| {
+        let mut outlives_environment = OutlivesEnvironment::new(param_env);
+        outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id, DUMMY_SP);
+        outlives_environment.save_implied_bounds(id);
+        let region_bound_pairs = outlives_environment.region_bound_pairs_map().get(&id).unwrap();
+
+        let cause = ObligationCause::new(DUMMY_SP, id, ObligationCauseCode::MiscObligation);
+
+        let sup_type = ty;
+        let sub_region = region;
+
+        let origin = SubregionOrigin::from_obligation_cause(&cause, || {
+            infer::RelateParamBound(cause.span, sup_type, None)
+        });
+
+        let outlives = &mut TypeOutlives::new(
+            &infcx,
+            tcx,
+            &region_bound_pairs,
+            Some(infcx.tcx.lifetimes.re_root_empty),
+            param_env,
+        );
+        outlives.type_must_outlive(origin, sup_type, sub_region);
+
+        let errors = infcx.resolve_regions(
+            id.expect_owner().to_def_id(),
+            &outlives_environment,
+            RegionckMode::default(),
+        );
+
+        debug!(?errors, "errors");
+
+        // If we were able to prove that the type outlives the region without
+        // an error, it must be because of the implied or explicit bounds...
+        errors.is_empty()
+    })
+}
+
+fn region_known_to_outlive<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    id: hir::HirId,
+    param_env: ty::ParamEnv<'tcx>,
+    wf_tys: &FxHashSet<Ty<'tcx>>,
+    region_a: ty::Region<'tcx>,
+    region_b: ty::Region<'tcx>,
+) -> bool {
+    // Unfortunately, we have to use a new `InferCtxt` each call, because
+    // region constraints get added and solved there and we need to test each
+    // call individually.
+    tcx.infer_ctxt().enter(|infcx| {
+        let mut outlives_environment = OutlivesEnvironment::new(param_env);
+        outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id, DUMMY_SP);
+        outlives_environment.save_implied_bounds(id);
+
+        let cause = ObligationCause::new(DUMMY_SP, id, ObligationCauseCode::MiscObligation);
+
+        let origin = SubregionOrigin::from_obligation_cause(&cause, || {
+            infer::RelateRegionParamBound(cause.span)
+        });
+
+        use rustc_infer::infer::outlives::obligations::TypeOutlivesDelegate;
+        (&infcx).push_sub_region_constraint(origin, region_a, region_b);
+
+        let errors = infcx.resolve_regions(
+            id.expect_owner().to_def_id(),
+            &outlives_environment,
+            RegionckMode::default(),
+        );
+
+        debug!(?errors, "errors");
+
+        // If we were able to prove that the type outlives the region without
+        // an error, it must be because of the implied or explicit bounds...
+        errors.is_empty()
+    })
+}
+
+/// TypeVisitor that looks for uses of GATs like
+/// `<P0 as Trait<P1..Pn>>::GAT<Pn..Pm>` and adds the arguments `P0..Pm` into
+/// the two vectors, `regions` and `types` (depending on their kind). For each
+/// parameter `Pi` also track the index `i`.
+struct GATSubstCollector<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    gat: DefId,
+    // Which region appears and which parameter index its subsituted for
+    regions: FxHashSet<(ty::Region<'tcx>, usize)>,
+    // Which params appears and which parameter index its subsituted for
+    types: FxHashSet<(Ty<'tcx>, usize)>,
+}
+
+impl<'tcx> GATSubstCollector<'tcx> {
+    fn visit<T: TypeFoldable<'tcx>>(
+        tcx: TyCtxt<'tcx>,
+        gat: DefId,
+        t: T,
+    ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
+        let mut visitor = GATSubstCollector {
+            tcx,
+            gat,
+            regions: FxHashSet::default(),
+            types: FxHashSet::default(),
+        };
+        t.visit_with(&mut visitor);
+        (visitor.regions, visitor.types)
+    }
+}
+
+impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
+    type BreakTy = !;
+
+    fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+        match t.kind() {
+            ty::Projection(p) if p.item_def_id == self.gat => {
+                for (idx, subst) in p.substs.iter().enumerate() {
+                    match subst.unpack() {
+                        GenericArgKind::Lifetime(lt) => {
+                            self.regions.insert((lt, idx));
+                        }
+                        GenericArgKind::Type(t) => {
+                            self.types.insert((t, idx));
+                        }
+                        _ => {}
+                    }
+                }
+            }
+            _ => {}
+        }
+        t.super_visit_with(self)
+    }
+
+    fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
+        Some(self.tcx)
+    }
 }
 
 fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
index 96211be8cdcf7576984a2791ef08a50bfc8e3004..a6ea8abdf3fa6af554918f4a4aeceb51101a1d9d 100644 (file)
@@ -772,7 +772,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 } else {
                     err.span_note(
                         tcx.hir().body(body_id).value.span,
-                        &format!("however, the inferred type `{}` cannot be named", ty.to_string()),
+                        &format!("however, the inferred type `{}` cannot be named", ty),
                     );
                 }
             }
@@ -796,7 +796,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 } else {
                     diag.span_note(
                         tcx.hir().body(body_id).value.span,
-                        &format!("however, the inferred type `{}` cannot be named", ty.to_string()),
+                        &format!("however, the inferred type `{}` cannot be named", ty),
                     );
                 }
             }
index 017e7ad8ca74a83f6620b2f31a2df6b43c3471b3..f90cfb8849160055ab7fce45bd5f7ddfd4867123 100644 (file)
@@ -70,6 +70,7 @@
 #![feature(never_type)]
 #![feature(slice_partition_dedup)]
 #![feature(control_flow_enum)]
+#![feature(hash_drain_filter)]
 #![recursion_limit = "256"]
 
 #[macro_use]
index 8d3862ffc8f01c027907081f5a19ca71d0094c9d..a1c2945770920c1f73dfa6743523e6ebfaa87148 100644 (file)
@@ -300,7 +300,7 @@ fn get_type_or_const_args_suggestions_from_param_names(
                     hir::TyKind::Path(hir::QPath::Resolved(
                         None,
                         hir::Path { res: hir::def::Res::Def(_, id), .. },
-                    )) if *id == def_id => true,
+                    )) => *id == def_id,
                     _ => false,
                 })
             })
index 34d2cfc8e2c5b778c200ccbd661173d192028ded..5dda7bfa37c71ea94aabb6a68bd95f6781472fbd 100644 (file)
 #![feature(extend_one)]
 #![feature(fmt_internals)]
 #![feature(fn_traits)]
+#![feature(inherent_ascii_escape)]
 #![feature(inplace_iteration)]
 #![feature(iter_advance_by)]
 #![feature(iter_zip)]
index c0ca068de9c21f955791dbe918157b80bfb30499..4fb2f0c8530d7e983aad7e7dc57c8071d5589f30 100644 (file)
@@ -318,6 +318,8 @@ impl<T: ?Sized> !marker::Sync for Rc<T> {}
 
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
+#[stable(feature = "rc_ref_unwind_safe", since = "1.58.0")]
+impl<T: RefUnwindSafe + ?Sized> RefUnwindSafe for Rc<T> {}
 
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
index 860f21085f32542ffc1854ba2dfe55bea5ee2106..ae730be0d25a57155e6e2cc8cf99bec1e9d902ae 100644 (file)
 pub use core::slice::ArrayChunksMut;
 #[unstable(feature = "array_windows", issue = "75027")]
 pub use core::slice::ArrayWindows;
+#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
+pub use core::slice::EscapeAscii;
 #[stable(feature = "slice_get_slice", since = "1.28.0")]
 pub use core::slice::SliceIndex;
 #[stable(feature = "from_ref", since = "1.28.0")]
 pub use core::slice::{RSplit, RSplitMut};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{RSplitN, RSplitNMut, SplitN, SplitNMut};
+#[stable(feature = "split_inclusive", since = "1.51.0")]
+pub use core::slice::{SplitInclusive, SplitInclusiveMut};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Basic slice extension methods
index 3b875477df3b86f2e21509d64755e6662033b5e9..104f5556566f4e5370c6dde8d0c9654b6bffc406 100644 (file)
@@ -46,7 +46,7 @@
 pub use core::str::EncodeUtf16;
 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
 pub use core::str::SplitAsciiWhitespace;
-#[stable(feature = "split_inclusive", since = "1.53.0")]
+#[stable(feature = "split_inclusive", since = "1.51.0")]
 pub use core::str::SplitInclusive;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::str::SplitWhitespace;
index 5f44087cabbbc7e5eec8cc57eacca8543280c306..4b16a269f2d738c2a93b4811525c88d8cc9cd965 100644 (file)
 #![feature(try_blocks)]
 #![feature(unboxed_closures)]
 #![feature(unsized_fn_params)]
+#![cfg_attr(not(bootstrap), feature(asm_const))]
 //
 // Target features:
 #![feature(aarch64_target_feature)]
index 18ebf1cbb1063e51fe3a9970612054d075f2f390..0c00db5fdf37aa38142116eeb970919bb320fda3 100644 (file)
@@ -94,7 +94,13 @@ macro_rules! usize_isize_from_xe_bytes_doc {
 }
 
 macro_rules! widening_impl {
-    ($SelfT:ty, $WideT:ty, $BITS:literal) => {
+    ($SelfT:ty, $WideT:ty, $BITS:literal, unsigned) => {
+        widening_impl!($SelfT, $WideT, $BITS, "");
+    };
+    ($SelfT:ty, $WideT:ty, $BITS:literal, signed) => {
+        widening_impl!($SelfT, $WideT, $BITS, "# //");
+    };
+    ($SelfT:ty, $WideT:ty, $BITS:literal, $AdaptiveTestPrefix:literal) => {
         /// Calculates the complete product `self * rhs` without the possibility to overflow.
         ///
         /// This returns the low-order (wrapping) bits and the high-order (overflow) bits
@@ -148,6 +154,33 @@ pub const fn widening_mul(self, rhs: Self) -> (Self, Self) {
         /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0));
         /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2));
         /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2));
+        #[doc = concat!($AdaptiveTestPrefix, "assert_eq!(",
+            stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ",
+            "(0, ", stringify!($SelfT), "::MAX));"
+        )]
+        /// ```
+        ///
+        /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul),
+        /// except that it gives the value of the overflow instead of just whether one happened:
+        ///
+        /// ```
+        /// #![feature(bigint_helper_methods)]
+        /// let r = u8::carrying_mul(7, 13, 0);
+        /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13));
+        /// let r = u8::carrying_mul(13, 42, 0);
+        /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(13, 42));
+        /// ```
+        ///
+        /// The value of the first field in the returned tuple matches what you'd get
+        /// by combining the [`wrapping_mul`](Self::wrapping_mul) and
+        /// [`wrapping_add`](Self::wrapping_add) methods:
+        ///
+        /// ```
+        /// #![feature(bigint_helper_methods)]
+        /// assert_eq!(
+        ///     789_u16.carrying_mul(456, 123).0,
+        ///     789_u16.wrapping_mul(456).wrapping_add(123),
+        /// );
         /// ```
         #[unstable(feature = "bigint_helper_methods", issue = "85532")]
         #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
@@ -168,33 +201,33 @@ pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
 
 #[lang = "i8"]
 impl i8 {
-    widening_impl! { i8, i16, 8 }
     int_impl! { i8, i8, u8, 8, 7, -128, 127, 2, "-0x7e", "0xa", "0x12", "0x12", "0x48",
     "[0x12]", "[0x12]", "", "" }
+    widening_impl! { i8, i16, 8, signed }
 }
 
 #[lang = "i16"]
 impl i16 {
-    widening_impl! { i16, i32, 16 }
     int_impl! { i16, i16, u16, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234", "0x3412",
     "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
+    widening_impl! { i16, i32, 16, signed }
 }
 
 #[lang = "i32"]
 impl i32 {
-    widening_impl! { i32, i64, 32 }
     int_impl! { i32, i32, u32, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78]", "", "" }
+    widening_impl! { i32, i64, 32, signed }
 }
 
 #[lang = "i64"]
 impl i64 {
-    widening_impl! { i64, i128, 64 }
     int_impl! { i64, i64, u64, 64, 63, -9223372036854775808, 9223372036854775807, 12,
     "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412",
     "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", "", "" }
+    widening_impl! { i64, i128, 64, signed }
 }
 
 #[lang = "i128"]
@@ -212,31 +245,31 @@ impl i128 {
 #[cfg(target_pointer_width = "16")]
 #[lang = "isize"]
 impl isize {
-    widening_impl! { isize, i32, 16 }
     int_impl! { isize, i16, usize, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234",
     "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]",
     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
+    widening_impl! { isize, i32, 16, signed }
 }
 
 #[cfg(target_pointer_width = "32")]
 #[lang = "isize"]
 impl isize {
-    widening_impl! { isize, i64, 32 }
     int_impl! { isize, i32, usize, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78]",
     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
+    widening_impl! { isize, i64, 32, signed }
 }
 
 #[cfg(target_pointer_width = "64")]
 #[lang = "isize"]
 impl isize {
-    widening_impl! { isize, i128, 64 }
     int_impl! { isize, i64, usize, 64, 63, -9223372036854775808, 9223372036854775807,
     12, "0xaa00000000006e1", "0x6e10aa",  "0x1234567890123456", "0x5634129078563412",
-     "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
-     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
+    "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
+    "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
+    usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
+    widening_impl! { isize, i128, 64, signed }
 }
 
 /// If 6th bit set ascii is upper case.
@@ -244,9 +277,9 @@ impl isize {
 
 #[lang = "u8"]
 impl u8 {
-    widening_impl! { u8, u16, 8 }
     uint_impl! { u8, u8, i8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
     "[0x12]", "", "" }
+    widening_impl! { u8, u16, 8, unsigned }
 
     /// Checks if the value is within the ASCII range.
     ///
@@ -793,26 +826,26 @@ pub fn escape_ascii(&self) -> ascii::EscapeDefault {
 
 #[lang = "u16"]
 impl u16 {
-    widening_impl! { u16, u32, 16 }
     uint_impl! { u16, u16, i16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
     "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
+    widening_impl! { u16, u32, 16, unsigned }
 }
 
 #[lang = "u32"]
 impl u32 {
-    widening_impl! { u32, u64, 32 }
     uint_impl! { u32, u32, i32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "" }
+    widening_impl! { u32, u64, 32, unsigned }
 }
 
 #[lang = "u64"]
 impl u64 {
-    widening_impl! { u64, u128, 64 }
     uint_impl! { u64, u64, i64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
     "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
     "", ""}
+    widening_impl! { u64, u128, 64, unsigned }
 }
 
 #[lang = "u128"]
@@ -830,29 +863,29 @@ impl u128 {
 #[cfg(target_pointer_width = "16")]
 #[lang = "usize"]
 impl usize {
-    widening_impl! { usize, u32, 16 }
     uint_impl! { usize, u16, isize, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
     "[0x34, 0x12]", "[0x12, 0x34]",
     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
+    widening_impl! { usize, u32, 16, unsigned }
 }
 #[cfg(target_pointer_width = "32")]
 #[lang = "usize"]
 impl usize {
-    widening_impl! { usize, u64, 32 }
     uint_impl! { usize, u32, isize, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]",
     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
+    widening_impl! { usize, u64, 32, unsigned }
 }
 
 #[cfg(target_pointer_width = "64")]
 #[lang = "usize"]
 impl usize {
-    widening_impl! { usize, u128, 64 }
     uint_impl! { usize, u64, isize, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
     "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
+    "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
+    widening_impl! { usize, u128, 64, unsigned }
 }
 
 /// A classification of floating point numbers.
index 691d0891b144888dc0f8d11a44f9930848977f2a..a15eabf7966d8ab2fd7cdc18ea7c6a535b7c7354 100644 (file)
@@ -1504,6 +1504,8 @@ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
         /// additional bit of overflow. This allows for chaining together multiple additions
         /// to create "big integers" which represent larger values.
         ///
+        #[doc = concat!("This can be thought of as a ", stringify!($BITS), "-bit \"full adder\", in the electronics sense.")]
+        ///
         /// # Examples
         ///
         /// Basic usage
@@ -1513,7 +1515,20 @@ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, false), (7, false));")]
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, true), (8, false));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), (0, true));")]
+        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(0, true), (0, true));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, true), (1, true));")]
+        #[doc = concat!("assert_eq!(",
+            stringify!($SelfT), "::MAX.carrying_add(", stringify!($SelfT), "::MAX, true), ",
+            "(", stringify!($SelfT), "::MAX, true));"
+        )]
+        /// ```
+        ///
+        /// If `carry` is false, this method is equivalent to [`overflowing_add`](Self::overflowing_add):
+        ///
+        /// ```
+        /// #![feature(bigint_helper_methods)]
+        #[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".carrying_add(2, false), 5_", stringify!($SelfT), ".overflowing_add(2));")]
+        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), ", stringify!($SelfT), "::MAX.overflowing_add(1));")]
         /// ```
         #[unstable(feature = "bigint_helper_methods", issue = "85532")]
         #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]
index 55ac1aa765c1fabc0cdf6166a1d9dfabfb9c032e..031fb8e8b21fb8f853c859faf75b11ff801a438a 100644 (file)
@@ -22,6 +22,8 @@
 //! assert_eq!(s.find("you"), Some(4));
 //! // char pattern
 //! assert_eq!(s.find('n'), Some(2));
+//! // array of chars pattern
+//! assert_eq!(s.find(&['a', 'e', 'i', 'o', 'u']), Some(1));
 //! // slice of chars pattern
 //! assert_eq!(s.find(&['a', 'e', 'i', 'o', 'u'][..]), Some(1));
 //! // closure pattern
 /// assert_eq!("abaaa".find('b'), Some(1));
 /// assert_eq!("abaaa".find('c'), None);
 ///
+/// // &[char; N]
+/// assert_eq!("ab".find(&['b', 'a']), Some(0));
+/// assert_eq!("abaaa".find(&['a', 'z']), Some(0));
+/// assert_eq!("abaaa".find(&['c', 'd']), None);
+///
 /// // &[char]
 /// assert_eq!("ab".find(&['b', 'a'][..]), Some(0));
 /// assert_eq!("abaaa".find(&['a', 'z'][..]), Some(0));
@@ -601,6 +608,20 @@ fn matches(&mut self, c: char) -> bool {
     }
 }
 
+impl<const N: usize> MultiCharEq for [char; N] {
+    #[inline]
+    fn matches(&mut self, c: char) -> bool {
+        self.iter().any(|&m| m == c)
+    }
+}
+
+impl<const N: usize> MultiCharEq for &[char; N] {
+    #[inline]
+    fn matches(&mut self, c: char) -> bool {
+        self.iter().any(|&m| m == c)
+    }
+}
+
 impl MultiCharEq for &[char] {
     #[inline]
     fn matches(&mut self, c: char) -> bool {
@@ -752,6 +773,58 @@ fn next_reject_back(&mut self) -> Option<(usize, usize)> {
     };
 }
 
+/// Associated type for `<[char; N] as Pattern<'a>>::Searcher`.
+#[derive(Clone, Debug)]
+pub struct CharArraySearcher<'a, const N: usize>(
+    <MultiCharEqPattern<[char; N]> as Pattern<'a>>::Searcher,
+);
+
+/// Associated type for `<&[char; N] as Pattern<'a>>::Searcher`.
+#[derive(Clone, Debug)]
+pub struct CharArrayRefSearcher<'a, 'b, const N: usize>(
+    <MultiCharEqPattern<&'b [char; N]> as Pattern<'a>>::Searcher,
+);
+
+/// Searches for chars that are equal to any of the [`char`]s in the array.
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!("Hello world".find(['l', 'l']), Some(2));
+/// assert_eq!("Hello world".find(['l', 'l']), Some(2));
+/// ```
+impl<'a, const N: usize> Pattern<'a> for [char; N] {
+    pattern_methods!(CharArraySearcher<'a, N>, MultiCharEqPattern, CharArraySearcher);
+}
+
+unsafe impl<'a, const N: usize> Searcher<'a> for CharArraySearcher<'a, N> {
+    searcher_methods!(forward);
+}
+
+unsafe impl<'a, const N: usize> ReverseSearcher<'a> for CharArraySearcher<'a, N> {
+    searcher_methods!(reverse);
+}
+
+/// Searches for chars that are equal to any of the [`char`]s in the array.
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!("Hello world".find(&['l', 'l']), Some(2));
+/// assert_eq!("Hello world".find(&['l', 'l']), Some(2));
+/// ```
+impl<'a, 'b, const N: usize> Pattern<'a> for &'b [char; N] {
+    pattern_methods!(CharArrayRefSearcher<'a, 'b, N>, MultiCharEqPattern, CharArrayRefSearcher);
+}
+
+unsafe impl<'a, 'b, const N: usize> Searcher<'a> for CharArrayRefSearcher<'a, 'b, N> {
+    searcher_methods!(forward);
+}
+
+unsafe impl<'a, 'b, const N: usize> ReverseSearcher<'a> for CharArrayRefSearcher<'a, 'b, N> {
+    searcher_methods!(reverse);
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // Impl for &[char]
 /////////////////////////////////////////////////////////////////////////////
index 3a06cd04ab146345e3d3198a9521d60b7bcc3a98..9d673d69687191dfb4525339593a7e2979506e11 100644 (file)
@@ -1074,7 +1074,11 @@ pub fn f32_unsuffixed(n: f32) -> Literal {
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal(bridge::client::Literal::float(&n.to_string()))
+        let mut repr = n.to_string();
+        if !repr.contains('.') {
+            repr.push_str(".0");
+        }
+        Literal(bridge::client::Literal::float(&repr))
     }
 
     /// Creates a new suffixed floating-point literal.
@@ -1115,7 +1119,11 @@ pub fn f64_unsuffixed(n: f64) -> Literal {
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal(bridge::client::Literal::float(&n.to_string()))
+        let mut repr = n.to_string();
+        if !repr.contains('.') {
+            repr.push_str(".0");
+        }
+        Literal(bridge::client::Literal::float(&repr))
     }
 
     /// Creates a new suffixed floating-point literal.
index 6bc445c6f2b07b084ca4c110747bdcd84eba14ef..248ecdf4befcef742ae2cdd5235c532412c67437 100644 (file)
@@ -15,7 +15,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core" }
-libc = { version = "0.2.103", default-features = false, features = ['rustc-dep-of-std'] }
+libc = { version = "0.2.106", default-features = false, features = ['rustc-dep-of-std'] }
 compiler_builtins = { version = "0.1.44" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
index 140647128a937d934b31d0c831c91f4593fce512..da95fe21ac9af8706e3d371d8b63382c1268efa7 100644 (file)
@@ -878,12 +878,7 @@ pub const fn is_broadcast(&self) -> bool {
     #[must_use]
     #[inline]
     pub const fn is_documentation(&self) -> bool {
-        match self.octets() {
-            [192, 0, 2, _] => true,
-            [198, 51, 100, _] => true,
-            [203, 0, 113, _] => true,
-            _ => false,
-        }
+        matches!(self.octets(), [192, 0, 2, _] | [198, 51, 100, _] | [203, 0, 113, _])
     }
 
     /// Converts this address to an [IPv4-compatible] [`IPv6` address].
index 30eeac14b43f5dde525fa633c2a4db89023dcf79..01392ffab79cac81f03288b789efce77ce064de4 100644 (file)
@@ -165,7 +165,14 @@ macro_rules! type_alias {
 #[unstable(feature = "c_size_t", issue = "88345")]
 pub type c_size_t = usize;
 
-/// Equivalent to C's `ssize_t` type, from `stddef.h` (or `cstddef` for C++).
+/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
+///
+/// This type is currently always [`isize`], however in the future there may be
+/// platforms where this is not the case.
+#[unstable(feature = "c_size_t", issue = "88345")]
+pub type c_ptrdiff_t = isize;
+
+/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
 ///
 /// This type is currently always [`isize`], however in the future there may be
 /// platforms where this is not the case.
index 887f605993918da58f6c156882f96c27be843744..f450e41bfea1e539a0c7d0a2e476164b68dba909 100644 (file)
@@ -159,7 +159,7 @@ pub(super) fn from_parts(
     #[must_use]
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn is_unnamed(&self) -> bool {
-        if let AddressKind::Unnamed = self.address() { true } else { false }
+        matches!(self.address(), AddressKind::Unnamed)
     }
 
     /// Returns the contents of this address if it is a `pathname` address.
index 4feb9c5a6d74047155547994bab0c76fb931fa80..bb9fa54d02ea4174eb596c3df960b4a77540fafd 100644 (file)
@@ -347,6 +347,6 @@ unsafe fn terminate_and_delete_current_task() -> ! {
     unsafe { crate::hint::unreachable_unchecked() };
 }
 
-pub fn available_concurrency() -> io::Result<crate::num::NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<crate::num::NonZeroUsize> {
     super::unsupported()
 }
index 6f4863057aba431b0635eb11a4671e335e573913..b99eb2e553f08908effdf7385961767f75b30c88 100644 (file)
@@ -275,6 +275,14 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
             target_os = "solaris",
             target_os = "illumos",
         ))] {
+            #[cfg(any(target_os = "android", target_os = "linux"))]
+            {
+                let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
+                if unsafe { libc::sched_getaffinity(0, mem::size_of::<libc::cpu_set_t>(), &mut set) } == 0 {
+                    let count = unsafe { libc::CPU_COUNT(&set) };
+                    return Ok(unsafe { NonZeroUsize::new_unchecked(count as usize) });
+                }
+            }
             match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
                 -1 => Err(io::Error::last_os_error()),
                 0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")),
index 7be13bc4b2bc7cf7edb2653dfc929908af829a9c..25d1c6e8e87c2914908430fd4e92c17d11bb10aa 100644 (file)
@@ -1,4 +1,28 @@
+//! Implements thread-local destructors that are not associated with any
+//! particular data.
+
 #![unstable(feature = "thread_local_internals", issue = "none")]
 #![cfg(target_thread_local)]
 
-pub use crate::sys_common::thread_local_dtor::register_dtor_fallback as register_dtor;
+// Using a per-thread list avoids the problems in synchronizing global state.
+#[thread_local]
+static mut DESTRUCTORS: Vec<(*mut u8, unsafe extern "C" fn(*mut u8))> = Vec::new();
+
+pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
+    DESTRUCTORS.push((t, dtor));
+}
+
+/// Runs destructors. This should not be called until thread exit.
+pub unsafe fn run_keyless_dtors() {
+    // Drop all the destructors.
+    //
+    // Note: While this is potentially an infinite loop, it *should* be
+    // the case that this loop always terminates because we provide the
+    // guarantee that a TLS key cannot be set after it is flagged for
+    // destruction.
+    while let Some((ptr, dtor)) = DESTRUCTORS.pop() {
+        (dtor)(ptr);
+    }
+    // We're done so free the memory.
+    DESTRUCTORS = Vec::new();
+}
index 0bc511146654b790fbbd6807c29d7ba266e84aa9..ec670238e6f0eaa9ba65ec60687f173d0ebbab6d 100644 (file)
@@ -196,6 +196,8 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) {
 unsafe extern "system" fn on_tls_callback(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID) {
     if dwReason == c::DLL_THREAD_DETACH || dwReason == c::DLL_PROCESS_DETACH {
         run_dtors();
+        #[cfg(target_thread_local)]
+        super::thread_local_dtor::run_keyless_dtors();
     }
 
     // See comments above for what this is doing. Note that we don't need this
index e7944c715ed6fb7106afc88d8983d99ae7369561..2a155ce31173130d028af622c1944985ffb608d8 100644 (file)
@@ -1407,6 +1407,15 @@ pub fn thread(&self) -> &Thread {
     pub fn join(mut self) -> Result<T> {
         self.0.join()
     }
+
+    /// Checks if the the associated thread is still running its main function.
+    ///
+    /// This might return `false` for a brief moment after the thread's main
+    /// function has returned, but before the thread itself has stopped running.
+    #[unstable(feature = "thread_is_running", issue = "90470")]
+    pub fn is_running(&self) -> bool {
+        Arc::strong_count(&self.0.packet.0) > 1
+    }
 }
 
 impl<T> AsInner<imp::Thread> for JoinHandle<T> {
index 16ad366fc126a3ece82d309c2b36873273ac3228..ca0d88135a5d8ae43fe35edb7654507da6b34bd7 100644 (file)
@@ -2,9 +2,13 @@
 use crate::any::Any;
 use crate::mem;
 use crate::result;
-use crate::sync::mpsc::{channel, Sender};
+use crate::sync::{
+    mpsc::{channel, Sender},
+    Arc, Barrier,
+};
 use crate::thread::{self, ThreadId};
 use crate::time::Duration;
+use crate::time::Instant;
 
 // !!! These tests are dangerous. If something is buggy, they will hang, !!!
 // !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
@@ -46,6 +50,36 @@ fn test_run_basic() {
     rx.recv().unwrap();
 }
 
+#[test]
+fn test_is_running() {
+    let b = Arc::new(Barrier::new(2));
+    let t = thread::spawn({
+        let b = b.clone();
+        move || {
+            b.wait();
+            1234
+        }
+    });
+
+    // Thread is definitely running here, since it's still waiting for the barrier.
+    assert_eq!(t.is_running(), true);
+
+    // Unblock the barrier.
+    b.wait();
+
+    // Now check that t.is_running() becomes false within a reasonable time.
+    let start = Instant::now();
+    while t.is_running() {
+        assert!(start.elapsed() < Duration::from_secs(2));
+        thread::sleep(Duration::from_millis(15));
+    }
+
+    // Joining the thread should not block for a significant time now.
+    let join_time = Instant::now();
+    assert_eq!(t.join().unwrap(), 1234);
+    assert!(join_time.elapsed() < Duration::from_secs(2));
+}
+
 #[test]
 fn test_join_panic() {
     match thread::spawn(move || panic!()).join() {
index e2aebee916d0eae7bb4f1364fec83f62660141fa..fa23cf2689671c14d8b7da1e14225bd8334d19d1 100644 (file)
@@ -55,8 +55,8 @@ fn write_result(
         _stdout: &[u8],
         _state: &ConsoleTestState,
     ) -> io::Result<()> {
-        // Because the testsuit node holds some of the information as attributes, we can't write it
-        // until all of the tests has ran. Instead of writting every result as they come in, we add
+        // Because the testsuite node holds some of the information as attributes, we can't write it
+        // until all of the tests have finished. Instead of writing every result as they come in, we add
         // them to a Vec and write them all at once when run is complete.
         let duration = exec_time.map(|t| t.0).unwrap_or_default();
         self.results.push((desc.clone(), result.clone(), duration));
index 0c5a0cbc06eb9ae1571c4fe00f53ec4ec5c551b5..38d3c7aec4941f5bfe12c1c7957a9eb93f9d5044 100644 (file)
@@ -1026,7 +1026,15 @@ class RustBuild(object):
         if self.git_version >= distutils.version.LooseVersion("2.11.0"):
             update_args.append("--progress")
         update_args.append(module)
-        run(update_args, cwd=self.rust_root, verbose=self.verbose, exception=True)
+        try:
+            run(update_args, cwd=self.rust_root, verbose=self.verbose, exception=True)
+        except RuntimeError:
+            print("Failed updating submodule. This is probably due to uncommitted local changes.")
+            print('Either stash the changes by running "git stash" within the submodule\'s')
+            print('directory, reset them by running "git reset --hard", or commit them.')
+            print("To reset all submodules' changes run", end=" ")
+            print('"git submodule foreach --recursive git reset --hard".')
+            raise SystemExit(1)
 
         run(["git", "reset", "-q", "--hard"],
             cwd=module_path, verbose=self.verbose)
index d5656f0f37e0389f336276d4942016847e60bc3a..6ba1b1b6036eae55f1ae9d78095f0dedf89e3ee0 100644 (file)
@@ -482,6 +482,7 @@ macro_rules! describe {
                 doc::RustByExample,
                 doc::RustcBook,
                 doc::CargoBook,
+                doc::Clippy,
                 doc::EmbeddedBook,
                 doc::EditionGuide,
             ),
index e9cc7662e6397a9b8bd9c5b2a0392cd4f9115194..007ca9f7f5a92f6431d3025767576f58427b3b4f 100644 (file)
@@ -197,7 +197,7 @@ fn copy_self_contained_objects(
     t!(fs::create_dir_all(&libdir_self_contained));
     let mut target_deps = vec![];
 
-    // Copies the CRT objects.
+    // Copies the libc and CRT objects.
     //
     // rustc historically provides a more self-contained installation for musl targets
     // not requiring the presence of a native musl toolchain. For example, it can fall back
@@ -208,7 +208,7 @@ fn copy_self_contained_objects(
         let srcdir = builder.musl_libdir(target).unwrap_or_else(|| {
             panic!("Target {:?} does not have a \"musl-libdir\" key", target.triple)
         });
-        for &obj in &["crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] {
+        for &obj in &["libc.a", "crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] {
             copy_and_stamp(
                 builder,
                 &libdir_self_contained,
@@ -235,7 +235,7 @@ fn copy_self_contained_objects(
                 panic!("Target {:?} does not have a \"wasi-root\" key", target.triple)
             })
             .join("lib/wasm32-wasi");
-        for &obj in &["crt1-command.o", "crt1-reactor.o"] {
+        for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] {
             copy_and_stamp(
                 builder,
                 &libdir_self_contained,
index 6f2470b706a64ff8d16b979376181196ce976230..2804e7119fbc14e8418365082bb879b22861d299 100644 (file)
@@ -755,6 +755,7 @@ fn run(self, builder: &Builder<'_>) {
     "src/tools/rustfmt",
     ["rustfmt-nightly", "rustfmt-config_proc_macro"],
 );
+tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"]);
 
 #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct ErrorIndex {
index 63836654293f222908ada9a651c0f8f5b238129e..2b4b78e81350d5dd396e62e038781a837b3c308c 100644 (file)
@@ -1,3 +1,15 @@
+# We need recent curl, OpenSSL and CA certificates, so we can download further
+# dependencies in the debian:6 image. We use an ubuntu 20.04 image download
+# those.
+FROM ubuntu:20.04
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
+        curl \
+        ca-certificates
+WORKDIR /tmp
+COPY host-x86_64/dist-x86_64-linux/download-openssl-curl.sh /tmp/
+RUN ./download-openssl-curl.sh
+
 # We use Debian 6 (glibc 2.11, kernel 2.6.32) as a common base for other
 # distros that still need Rust support: RHEL 6 (glibc 2.12, kernel 2.6.32) and
 # SLES 11 SP4 (glibc 2.11, kernel 3.0).
@@ -14,8 +26,6 @@ RUN apt-get update && \
     apt-get install --allow-unauthenticated -y --no-install-recommends \
       automake \
       bzip2 \
-      ca-certificates \
-      curl \
       file \
       g++ \
       g++-multilib \
@@ -34,11 +44,6 @@ RUN apt-get update && \
       xz-utils \
       zlib1g-dev
 
-# Install new Let's Encrypt root CA certificate and remove the expired one.
-COPY host-x86_64/shared/ISRG_Root_X1.crt /usr/local/share/ca-certificates/ISRG_Root_X1.crt
-RUN sed -i '/mozilla\/DST_Root_CA_X3\.crt/d' /etc/ca-certificates.conf
-RUN /usr/sbin/update-ca-certificates
-
 ENV PATH=/rustroot/bin:$PATH
 ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib32:/rustroot/lib
 ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig
@@ -50,6 +55,7 @@ COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/
 # static.rust-lang.org. This'll be used to link into libcurl below (and used
 # later as well), so build a copy of OpenSSL with dynamic libraries into our
 # generic root.
+COPY --from=0 /tmp/openssl.tar.gz /tmp/openssl.tar.gz
 COPY host-x86_64/dist-x86_64-linux/build-openssl.sh /tmp/
 RUN ./build-openssl.sh
 
@@ -59,8 +65,13 @@ RUN ./build-openssl.sh
 #
 # Note that we also disable a bunch of optional features of curl that we don't
 # really need.
+COPY --from=0 /tmp/curl.tar.xz /tmp/curl.tar.xz
 COPY host-x86_64/dist-x86_64-linux/build-curl.sh /tmp/
-RUN ./build-curl.sh && apt-get remove -y curl
+RUN ./build-curl.sh
+
+# Use up-to-date curl CA bundle
+COPY --from=0 /tmp/cacert.pem /tmp/cacert.pem
+ENV CURL_CA_BUNDLE /tmp/cacert.pem
 
 # binutils < 2.22 has a bug where the 32-bit executables it generates
 # immediately segfault in Rust, so we need to install our own binutils.
index 7b560aaaaa68826af7441aab521281294b78d867..50452349931e84c9321a41512c283581859f9068 100644 (file)
@@ -1,3 +1,15 @@
+# We need recent curl, OpenSSL and CA certificates, so we can download further
+# dependencies in the debian:6 image. We use an ubuntu 20.04 image download
+# those.
+FROM ubuntu:20.04
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
+        curl \
+        ca-certificates
+WORKDIR /tmp
+COPY host-x86_64/dist-x86_64-linux/download-openssl-curl.sh /tmp/
+RUN ./download-openssl-curl.sh
+
 # We use Debian 6 (glibc 2.11, kernel 2.6.32) as a common base for other
 # distros that still need Rust support: RHEL 6 (glibc 2.12, kernel 2.6.32) and
 # SLES 11 SP4 (glibc 2.11, kernel 3.0).
@@ -14,8 +26,6 @@ RUN apt-get update && \
     apt-get install --allow-unauthenticated -y --no-install-recommends \
       automake \
       bzip2 \
-      ca-certificates \
-      curl \
       file \
       g++ \
       g++-multilib \
@@ -34,11 +44,6 @@ RUN apt-get update && \
       xz-utils \
       zlib1g-dev
 
-# Install new Let's Encrypt root CA certificate and remove the expired one.
-COPY host-x86_64/shared/ISRG_Root_X1.crt /usr/local/share/ca-certificates/ISRG_Root_X1.crt
-RUN sed -i '/mozilla\/DST_Root_CA_X3\.crt/d' /etc/ca-certificates.conf
-RUN /usr/sbin/update-ca-certificates
-
 ENV PATH=/rustroot/bin:$PATH
 ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib32:/rustroot/lib
 ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig
@@ -50,6 +55,7 @@ COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/
 # static.rust-lang.org. This'll be used to link into libcurl below (and used
 # later as well), so build a copy of OpenSSL with dynamic libraries into our
 # generic root.
+COPY --from=0 /tmp/openssl.tar.gz /tmp/openssl.tar.gz
 COPY host-x86_64/dist-x86_64-linux/build-openssl.sh /tmp/
 RUN ./build-openssl.sh
 
@@ -59,8 +65,13 @@ RUN ./build-openssl.sh
 #
 # Note that we also disable a bunch of optional features of curl that we don't
 # really need.
+COPY --from=0 /tmp/curl.tar.xz /tmp/curl.tar.xz
 COPY host-x86_64/dist-x86_64-linux/build-curl.sh /tmp/
-RUN ./build-curl.sh && apt-get remove -y curl
+RUN ./build-curl.sh
+
+# Use up-to-date curl CA bundle
+COPY --from=0 /tmp/cacert.pem /tmp/cacert.pem
+ENV CURL_CA_BUNDLE /tmp/cacert.pem
 
 # binutils < 2.22 has a bug where the 32-bit executables it generates
 # immediately segfault in Rust, so we need to install our own binutils.
index 6efa789756619fcaf3e318159da75bf2a1051c9b..88ee96eaa89b579c0a5e4ea56b7c594fb8a4482d 100755 (executable)
@@ -3,18 +3,11 @@
 set -ex
 source shared.sh
 
-VERSION=7.66.0
-
-# This needs to be downloaded directly from S3, it can't go through the CDN.
-# That's because the CDN is backed by CloudFront, which requires SNI and TLSv1
-# (without paying an absurd amount of money).
-curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/curl-$VERSION.tar.xz \
-  | xz --decompress \
-  | tar xf -
+tar xJf curl.tar.xz
 
 mkdir curl-build
 cd curl-build
-hide_output ../curl-$VERSION/configure \
+hide_output ../curl-*/configure \
       --prefix=/rustroot \
       --with-ssl=/rustroot \
       --disable-sspi \
@@ -35,4 +28,4 @@ hide_output make install
 
 cd ..
 rm -rf curl-build
-rm -rf curl-$VERSION
+rm -rf curl-*
index 34bbe19d2fac331cec92db088c24190512273174..b48b5c4c00aae59aa0a11917b46dd7daaf561cc4 100755 (executable)
@@ -3,21 +3,14 @@
 set -ex
 source shared.sh
 
-VERSION=1.0.2k
+tar xzf openssl.tar.gz
 
-# This needs to be downloaded directly from S3, it can't go through the CDN.
-# That's because the CDN is backed by CloudFront, which requires SNI and TLSv1
-# (without paying an absurd amount of money).
-URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/openssl-$VERSION.tar.gz
-
-curl $URL | tar xzf -
-
-cd openssl-$VERSION
+cd openssl-*
 hide_output ./config --prefix=/rustroot shared -fPIC
 hide_output make -j$(nproc)
 hide_output make install
 cd ..
-rm -rf openssl-$VERSION
+rm -rf openssl-*
 
 # Make the system cert collection available to the new install.
 ln -nsf /etc/pki/tls/cert.pem /rustroot/ssl/
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/download-openssl-curl.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/download-openssl-curl.sh
new file mode 100755 (executable)
index 0000000..ca40a8c
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+set -ex
+
+OPENSSL_VERSION=1.0.2k
+CURL_VERSION=7.66.0
+
+curl -f https://ci-mirrors.rust-lang.org/rustc/openssl-$OPENSSL_VERSION.tar.gz -o openssl.tar.gz
+curl -f https://ci-mirrors.rust-lang.org/rustc/curl-$CURL_VERSION.tar.xz -o curl.tar.xz
+curl -f https://curl.se/ca/cacert.pem -o cacert.pem
diff --git a/src/ci/docker/host-x86_64/shared/ISRG_Root_X1.crt b/src/ci/docker/host-x86_64/shared/ISRG_Root_X1.crt
deleted file mode 100644 (file)
index b85c803..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
-WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
-ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
-MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
-h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
-0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
-A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
-T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
-B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
-B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
-KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
-OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
-jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
-qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
-rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
-hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
-ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
-3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
-NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
-ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
-TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
-jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
-oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
-4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
-mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
-emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
------END CERTIFICATE-----
index b1dacf79d269598d593a3429f567c49b471e549c..93b4f435d4db777c66e38c1b8a5bf160dd4e2c28 100755 (executable)
@@ -50,7 +50,8 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
       # Look for all source files involves in the COPY command
       copied_files=/tmp/.docker-copied-files.txt
       rm -f "$copied_files"
-      for i in $(sed -n -e 's/^COPY \(.*\) .*$/\1/p' "$docker_dir/$image/Dockerfile"); do
+      for i in $(sed -n -e '/^COPY --from=/! s/^COPY \(.*\) .*$/\1/p' \
+          "$docker_dir/$image/Dockerfile"); do
         # List the file names
         find "$script_dir/$i" -type f >> $copied_files
       done
index 70c57e07fdeab7faa5b7f17b277c60f5280bc86c..de6b52a5e001c6265617be41fd0262e30b69df77 100755 (executable)
@@ -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; do
+for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat kvm; do
   files_to_extract=("${files_to_extract[@]}" "./usr/lib/lib${lib}.*")
 done
 
index 8c41835183797a7a11a3bc4f03a66fa7aee47eb5..c251425d1b7ad34a2d05a38dc03bf66d9fdbca28 100644 (file)
@@ -15,6 +15,7 @@
 - [Platform Support](platform-support.md)
     - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
+    - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
 - [Target Tier Policy](target-tier-policy.md)
 - [Targets](targets/index.md)
     - [Built-in Targets](targets/built-in.md)
index bbeab598f2292870baca8e070388fd632881b592..6b0c336b3c7994f47555de6327d7f7fcd4a89e81 100644 (file)
@@ -285,6 +285,7 @@ target | std | host | notes
 `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
 `x86_64-unknown-hermit` | ? |  |
 `x86_64-unknown-l4re-uclibc` | ? |  |
+[`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * |  | Freestanding/bare-metal x86_64, softfloat
 `x86_64-unknown-none-hermitkernel` | ? |  | HermitCore kernel
 `x86_64-unknown-none-linuxkernel` | * |  | Linux kernel modules
 `x86_64-unknown-openbsd` | ✓ | ✓ | 64-bit OpenBSD
diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-none.md
new file mode 100644 (file)
index 0000000..afcc480
--- /dev/null
@@ -0,0 +1,76 @@
+# `x86_64-unknown-none`
+
+**Tier: 3**
+
+Freestanding/bare-metal x86-64 binaries in ELF format: firmware, kernels, etc.
+
+## Target maintainers
+
+- Harald Hoyer `harald@profian.com`, https://github.com/haraldh
+- Mike Leany, https://github.com/mikeleany
+
+## Requirements
+
+This target is cross-compiled. There is no support for `std`. There is no
+default allocator, but it's possible to use `alloc` by supplying an allocator.
+
+By default, Rust code generated for this target does not use any vector or
+floating-point registers (e.g. SSE, AVX). This allows the generated code to run
+in environments, such as kernels, which may need to avoid the use of such
+registers or which may have special considerations about the use of such
+registers (e.g. saving and restoring them to avoid breaking userspace code
+using the same registers). You can change code generation to use additional CPU
+features via the `-C target-feature=` codegen options to rustc, or via the
+`#[target_feature]` mechanism within Rust code.
+
+By default, code generated with this target should run on any `x86_64`
+hardware; enabling additional target features may raise this baseline.
+
+Code generated with this target will use the `kernel` code model by default.
+You can change this using the `-C code-model=` option to rustc.
+
+On `x86_64-unknown-none`, `extern "C"` uses the [standard System V calling
+convention](https://gitlab.com/x86-psABIs/x86-64-ABI), without red zones.
+
+This target generated binaries in the ELF format. Any alternate formats or
+special considerations for binary layout will require linker options or linker
+scripts.
+
+## Building the target
+
+You can build Rust with support for the target by adding it to the `target`
+list in `config.toml`:
+
+```toml
+[build]
+build-stage = 1
+target = ["x86_64-unknown-none"]
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for
+this target, you will either need to build Rust with the target enabled (see
+"Building the target" above), or build your own copy of `core` by using
+`build-std` or similar.
+
+## Testing
+
+As `x86_64-unknown-none` supports a variety of different environments and does
+not support `std`, this target does not support running the Rust testsuite.
+
+## Cross-compilation toolchains and C code
+
+If you want to compile C code along with Rust (such as for Rust crates with C
+dependencies), you will need an appropriate `x86_64` toolchain.
+
+Rust *may* be able to use an `x86_64-linux-gnu-` toolchain with appropriate
+standalone flags to build for this toolchain (depending on the assumptions of
+that toolchain, see below), or you may wish to use a separate
+`x86_64-unknown-none` (or `x86_64-elf-`) toolchain.
+
+On some `x86_64` hosts that use ELF binaries, you *may* be able to use the host
+C toolchain, if it does not introduce assumptions about the host environment
+that don't match the expectations of a standalone environment. Otherwise, you
+may need a separate toolchain for standalone/freestanding development, just as
+when cross-compiling from a non-`x86_64` platform.
index 3fa91bb51f02fb7d8c0ee8d2a6fac50c6aa410da..eb18185945387cbaf5de34a8cfc6335ccfc89c9d 100644 (file)
@@ -1,6 +1,7 @@
 # The Rustdoc Book
 
 - [What is rustdoc?](what-is-rustdoc.md)
+- [How to read rustdoc output](how-to-read-rustdoc.md)
 - [How to write documentation](how-to-write-documentation.md)
 - [What to include (and exclude)](what-to-include.md)
 - [Command-line arguments](command-line-arguments.md)
diff --git a/src/doc/rustdoc/src/how-to-read-rustdoc.md b/src/doc/rustdoc/src/how-to-read-rustdoc.md
new file mode 100644 (file)
index 0000000..99724d8
--- /dev/null
@@ -0,0 +1,107 @@
+# How to read rustdoc output
+
+Rustdoc's HTML output includes a friendly and useful navigation interface which
+makes it easier for users to navigate and understand your code.
+This chapter covers the major features of that interface,
+and is a great starting point for documentation authors and users alike.
+
+## Structure
+
+The `rustdoc` output is divided into three sections.
+Along the left side of each page is a quick navigation bar,
+which shows contextual information about the current entry.
+The rest of the page is taken up by the search interface at the top
+and the documentation for the current item below that.
+
+## The Item Documentation
+
+The majority of the screen is taken up with the documentation text for the item
+currently being viewed.
+At the top is some at-a-glance info and controls:
+
+- the type and name of the item,
+  such as "Struct `std::time::Duration`",
+- a button to copy the item's path to the clipboard,
+  which is a clipboard item
+- a button to collapse or expand the top-level documentation for that item
+  (`[+]` or `[-]`),
+- a link to the source code (`[src]`),
+  if [configured](the-doc-attribute.html#html_no_source),
+  and present (the source may not be available if
+  the documentation was created with `cargo doc --no-deps`),
+- and the version in which the item became stable,
+  if it's a stable item in the standard library.
+
+Below this is the main documentation for the item,
+including a definition or function signature if appropriate,
+followed by a list of fields or variants for Rust types.
+Finally, the page lists associated functions and trait implementations,
+including automatic and blanket implementations that `rustdoc` knows about.
+
+### Navigation
+
+Subheadings, variants, fields, and many other things in this documentation
+are anchors and can be clicked on and deep-linked to,
+which is a great way to communicate exactly what you're talking about.
+The typograpical character "§" appears next to lines with anchors on them
+when hovered or given keyboard focus.
+
+## The Navigation Bar
+
+For example, when looking at documentation for the crate root,
+it shows all the crates documented in the documentation bundle,
+and quick links to the modules, structs, traits, functions, and macros available
+from the current crate.
+At the top, it displays a [configurable logo](the-doc-attribute.html#html_logo_url)
+alongside the current crate's name and version,
+or the current item whose documentation is being displayed.
+
+## The Theme Picker and Search Interface
+
+When viewing `rustdoc`'s output in a browser with JavaScript enabled,
+a dynamic interface appears at the top of the page.
+To the left is the theme picker, denoted with a paint-brush icon,
+and the search interface, help screen, and options appear to the right of that.
+
+### The Theme Picker
+
+Clicking on the theme picker provides a list of themes -
+by default `ayu`, `light`, and `dark` -
+which are available for viewing.
+
+### The Search Interface
+
+Typing in the search bar instantly searches the available documentation for
+the string entered with a fuzzy matching algorithm that is tolerant of minor
+typos.
+
+By default, the search results give are "In Names",
+meaning that the fuzzy match is made against the names of items.
+Matching names are shown on the left, and the first few words of their
+descriptions are given on the right.
+By clicking an item, you will navigate to its particular documentation.
+
+There are two other sets of results, shown as tabs in the search results pane.
+"In Parameters" shows matches for the string in the types of parameters to
+functions, and "In Return Types" shows matches in the return types of functions.
+Both are very useful when looking for a function whose name you can't quite
+bring to mind when you know the type you have or want.
+
+When typing in the search bar, you can prefix your search term with a type
+followed by a colon (such as `mod:`) to restrict the results to just that
+kind of item. (The available items are listed in the help popup.)
+
+### Shortcuts
+
+Pressing `S` while focused elsewhere on the page will move focus to the
+search bar, and pressing `?` shows the help screen,
+which includes all these shortcuts and more.
+Pressing `T` focuses the theme picker.
+
+When the search results are focused,
+the left and right arrows move between tabs and the up and down arrows move
+among the results.
+Pressing the enter or return key opens the highlighted result.
+
+When looking at the documentation for an item, the plus and minus keys expand
+and collapse all sections in the document.
index 51f365be922fa3225746cccbfa4e6c2723389819..b3b6422afab427cc26f749ca5d8b142c711518c7 100644 (file)
@@ -134,9 +134,27 @@ Book][unstable-masked] and [its tracking issue][issue-masked].
 
 ## Document primitives
 
+This is for Rust compiler internal use only.
+
 Since primitive types are defined in the compiler, there's no place to attach documentation
-attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way to generate
-documentation for primitive types, and requires `#![feature(doc_primitive)]` to enable.
+attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way
+to generate documentation for primitive types, and requires `#![feature(doc_primitive)]` to enable.
+
+## Document keywords
+
+This is for Rust compiler internal use only.
+
+Rust keywords are documented in the standard library (look for `match` for example).
+
+To do so, the `#[doc(keyword = "...")]` attribute is used. Example:
+
+```rust
+#![feature(doc_keyword)]
+
+/// Some documentation about the keyword.
+#[doc(keyword = "keyword")]
+mod empty_mod {}
+```
 
 ## Unstable command-line arguments
 
index bd7234522e1fec2f73d130aa6b8b1e7102de3a0c..84fc6dcc33979d1605ab373e13cb00aa9bd622eb 100644 (file)
@@ -257,7 +257,7 @@ unsafe {
 }
 
 println!(
-    "L1 Cache: {}",
+    "L0 Cache: {}",
     ((ebx >> 22) + 1) * (((ebx >> 12) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1)
 );
 ```
@@ -885,5 +885,7 @@ The compiler performs some additional checks on options:
     - You are responsible for switching any target-specific state (e.g. thread-local storage, stack bounds).
     - The set of memory locations that you may access is the intersection of those allowed by the `asm!` blocks you entered and exited.
 - You cannot assume that an `asm!` block will appear exactly once in the output binary. The compiler is allowed to instantiate multiple copies of the `asm!` block, for example when the function containing it is inlined in multiple places.
+- On x86, inline assembly must not end with an instruction prefix (such as `LOCK`) that would apply to instructions generated by the compiler.
+  - The compiler is currently unable to detect this due to the way inline assembly is compiled, but may catch and reject this in the future.
 
 > **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call.
index 146d17b4638c8357fcdac18ace09d2209836d299..3f8e165841d1421bb906720da5f8fc2171c4c26d 100644 (file)
@@ -75,7 +75,7 @@ are concatenated into one or assembled separately.
 constants defined in Rust to be used in assembly code:
 
 ```rust,no_run
-#![feature(global_asm)]
+#![feature(global_asm, asm_const)]
 # #[cfg(any(target_arch="x86", target_arch="x86_64"))]
 # mod x86 {
 const C: i32 = 1234;
@@ -96,7 +96,7 @@ override this by adding `options(att_syntax)` at the end of the macro
 arguments list:
 
 ```rust,no_run
-#![feature(global_asm)]
+#![feature(global_asm, asm_const)]
 # #[cfg(any(target_arch="x86", target_arch="x86_64"))]
 # mod x86 {
 global_asm!("movl ${}, %ecx", const 5, options(att_syntax));
index ba701f42c660ba7606ada806d4e32c56910f3ddc..2ccf17387d1c701febec22a676ea264bd07bb845 100644 (file)
@@ -76,17 +76,17 @@ fn generate_for_trait(
             new_generics
         });
 
-        let negative_polarity;
+        let polarity;
         let new_generics = match result {
             AutoTraitResult::PositiveImpl(new_generics) => {
-                negative_polarity = false;
+                polarity = ty::ImplPolarity::Positive;
                 if discard_positive_impl {
                     return None;
                 }
                 new_generics
             }
             AutoTraitResult::NegativeImpl => {
-                negative_polarity = true;
+                polarity = ty::ImplPolarity::Negative;
 
                 // For negative impls, we use the generic params, but *not* the predicates,
                 // from the original type. Otherwise, the displayed impl appears to be a
@@ -115,15 +115,13 @@ fn generate_for_trait(
             visibility: Inherited,
             def_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id },
             kind: box ImplItem(Impl {
-                span: Span::dummy(),
                 unsafety: hir::Unsafety::Normal,
                 generics: new_generics,
                 trait_: Some(trait_ref.clean(self.cx)),
                 for_: ty.clean(self.cx),
                 items: Vec::new(),
-                negative_polarity,
-                synthetic: true,
-                blanket_impl: None,
+                polarity,
+                kind: ImplKind::Auto,
             }),
             cfg: None,
         })
index 843dda324da7fb75842b6ca3457f17f1b69bdcdc..f44589f60675f5dbe8bb38c358121be812d540d1 100644 (file)
@@ -106,7 +106,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                     visibility: Inherited,
                     def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
                     kind: box ImplItem(Impl {
-                        span: Span::new(self.cx.tcx.def_span(impl_def_id)),
                         unsafety: hir::Unsafety::Normal,
                         generics: (
                             self.cx.tcx.generics_of(impl_def_id),
@@ -122,11 +121,10 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             .tcx
                             .associated_items(impl_def_id)
                             .in_definition_order()
-                            .collect::<Vec<_>>()
-                            .clean(self.cx),
-                        negative_polarity: false,
-                        synthetic: false,
-                        blanket_impl: Some(box trait_ref.self_ty().clean(self.cx)),
+                            .map(|x| x.clean(self.cx))
+                            .collect::<Vec<_>>(),
+                        polarity: ty::ImplPolarity::Positive,
+                        kind: ImplKind::Blanket(box trait_ref.self_ty().clean(self.cx)),
                     }),
                     cfg: None,
                 });
index cb70f465f62b13aaba04acc7dd9cf06f9fa46277..d670288270a403cfb4b4c2757a56b36a973ed9d0 100644 (file)
@@ -14,7 +14,9 @@
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Symbol};
 
-use crate::clean::{self, utils, Attributes, AttributesExt, ItemId, NestedAttributesExt, Type};
+use crate::clean::{
+    self, utils, Attributes, AttributesExt, ImplKind, ItemId, NestedAttributesExt, Type,
+};
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
 
@@ -242,7 +244,7 @@ fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
     clean::Enum {
         generics: (cx.tcx.generics_of(did), predicates).clean(cx),
         variants_stripped: false,
-        variants: cx.tcx.adt_def(did).variants.clean(cx),
+        variants: cx.tcx.adt_def(did).variants.iter().map(|v| v.clean(cx)).collect(),
     }
 }
 
@@ -253,7 +255,7 @@ fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct {
     clean::Struct {
         struct_type: variant.ctor_kind,
         generics: (cx.tcx.generics_of(did), predicates).clean(cx),
-        fields: variant.fields.clean(cx),
+        fields: variant.fields.iter().map(|x| x.clean(cx)).collect(),
         fields_stripped: false,
     }
 }
@@ -262,11 +264,9 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
     let predicates = cx.tcx.explicit_predicates_of(did);
     let variant = cx.tcx.adt_def(did).non_enum_variant();
 
-    clean::Union {
-        generics: (cx.tcx.generics_of(did), predicates).clean(cx),
-        fields: variant.fields.clean(cx),
-        fields_stripped: false,
-    }
+    let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
+    let fields = variant.fields.iter().map(|x| x.clean(cx)).collect();
+    clean::Union { generics, fields, fields_stripped: false }
 }
 
 fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef {
@@ -446,7 +446,7 @@ fn merge_attrs(
         ),
     };
     let polarity = tcx.impl_polarity(did);
-    let trait_ = associated_trait.clean(cx);
+    let trait_ = associated_trait.map(|t| t.clean(cx));
     if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
         super::build_deref_target_impls(cx, &trait_items, ret);
     }
@@ -490,15 +490,13 @@ fn merge_attrs(
         did,
         None,
         clean::ImplItem(clean::Impl {
-            span: clean::types::rustc_span(did, cx.tcx),
             unsafety: hir::Unsafety::Normal,
             generics,
             trait_,
             for_,
             items: trait_items,
-            negative_polarity: polarity.clean(cx),
-            synthetic: false,
-            blanket_impl: None,
+            polarity,
+            kind: ImplKind::Normal,
         }),
         box merged_attrs,
         cx,
index 93bce10a2d60601797071104c8b60efcbc505be4..3db0ef17fd81064aa52efd07d4a2ea656a4e3d1d 100644 (file)
@@ -16,7 +16,6 @@
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
-use rustc_index::vec::{Idx, IndexVec};
 use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
 use rustc_middle::middle::resolve_lifetime as rl;
 use rustc_middle::ty::fold::TypeFolder;
@@ -34,7 +33,6 @@
 use std::collections::hash_map::Entry;
 use std::default::Default;
 use std::hash::Hash;
-use std::rc::Rc;
 use std::{mem, vec};
 
 use crate::core::{self, DocContext, ImplTraitParam};
     fn clean(&self, cx: &mut DocContext<'_>) -> T;
 }
 
-impl<T: Clean<U>, U> Clean<Vec<U>> for [T] {
-    fn clean(&self, cx: &mut DocContext<'_>) -> Vec<U> {
-        self.iter().map(|x| x.clean(cx)).collect()
-    }
-}
-
-impl<T: Clean<U>, U, V: Idx> Clean<IndexVec<V, U>> for IndexVec<V, T> {
-    fn clean(&self, cx: &mut DocContext<'_>) -> IndexVec<V, U> {
-        self.iter().map(|x| x.clean(cx)).collect()
-    }
-}
-
-impl<T: Clean<U>, U> Clean<U> for &T {
-    fn clean(&self, cx: &mut DocContext<'_>) -> U {
-        (**self).clean(cx)
-    }
-}
-
-impl<T: Clean<U>, U> Clean<U> for Rc<T> {
-    fn clean(&self, cx: &mut DocContext<'_>) -> U {
-        (**self).clean(cx)
-    }
-}
-
-impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
-    fn clean(&self, cx: &mut DocContext<'_>) -> Option<U> {
-        self.as_ref().map(|v| v.clean(cx))
-    }
-}
-
 impl Clean<Item> for doctree::Module<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let mut items: Vec<Item> = vec![];
@@ -287,14 +255,14 @@ fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate {
                     .collect();
                 WherePredicate::BoundPredicate {
                     ty: wbp.bounded_ty.clean(cx),
-                    bounds: wbp.bounds.clean(cx),
+                    bounds: wbp.bounds.iter().map(|x| x.clean(cx)).collect(),
                     bound_params,
                 }
             }
 
             hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
                 lifetime: wrp.lifetime.clean(cx),
-                bounds: wrp.bounds.clean(cx),
+                bounds: wrp.bounds.iter().map(|x| x.clean(cx)).collect(),
             },
 
             hir::WherePredicate::EqPredicate(ref wrp) => {
@@ -459,8 +427,8 @@ fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef {
                 self.name.ident().name,
                 GenericParamDefKind::Type {
                     did: cx.tcx.hir().local_def_id(self.hir_id).to_def_id(),
-                    bounds: self.bounds.clean(cx),
-                    default: default.clean(cx).map(Box::new),
+                    bounds: self.bounds.iter().map(|x| x.clean(cx)).collect(),
+                    default: default.map(|t| t.clean(cx)).map(Box::new),
                     synthetic,
                 },
             ),
@@ -530,8 +498,10 @@ fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool {
         }
         params.extend(impl_trait_params);
 
-        let mut generics =
-            Generics { params, where_predicates: self.where_clause.predicates.clean(cx) };
+        let mut generics = Generics {
+            params,
+            where_predicates: self.where_clause.predicates.iter().map(|x| x.clean(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
@@ -900,7 +870,7 @@ impl Clean<PolyTrait> for hir::PolyTraitRef<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> PolyTrait {
         PolyTrait {
             trait_: self.trait_ref.clean(cx),
-            generic_params: self.bound_generic_params.clean(cx),
+            generic_params: self.bound_generic_params.iter().map(|x| x.clean(cx)).collect(),
         }
     }
 }
@@ -924,7 +894,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Item {
                 }
                 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => {
                     let (generics, decl) = enter_impl_trait(cx, |cx| {
-                        (self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx))
+                        (self.generics.clean(cx), (sig.decl, names).clean(cx))
                     });
                     let mut t = Function { header: sig.header, decl, generics };
                     if t.header.constness == hir::Constness::Const
@@ -935,7 +905,9 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Item {
                     TyMethodItem(t)
                 }
                 hir::TraitItemKind::Type(bounds, ref default) => {
-                    AssocTypeItem(bounds.clean(cx), default.clean(cx))
+                    let bounds = bounds.iter().map(|x| x.clean(cx)).collect();
+                    let default = default.map(|t| t.clean(cx));
+                    AssocTypeItem(bounds, default)
                 }
             };
             let what_rustc_thinks =
@@ -1127,7 +1099,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Item {
                         None
                     };
 
-                    AssocTypeItem(bounds, ty.clean(cx))
+                    AssocTypeItem(bounds, ty.map(|t| t.clean(cx)))
                 } else {
                     // FIXME: when could this happen? Associated items in inherent impls?
                     let type_ = tcx.type_of(self.def_id).clean(cx);
@@ -1183,7 +1155,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
             let trait_def = cx.tcx.associated_item(p.res.def_id()).container.id();
             let trait_ = self::Path {
                 res: Res::Def(DefKind::Trait, trait_def),
-                segments: trait_segments.clean(cx),
+                segments: trait_segments.iter().map(|x| x.clean(cx)).collect(),
             };
             register_res(cx, trait_.res);
             Type::QPath {
@@ -1337,11 +1309,11 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                 let length = print_const(cx, ct.eval(cx.tcx, param_env));
                 Array(box ty.clean(cx), length)
             }
-            TyKind::Tup(tys) => Tuple(tys.clean(cx)),
+            TyKind::Tup(tys) => Tuple(tys.iter().map(|x| x.clean(cx)).collect()),
             TyKind::OpaqueDef(item_id, _) => {
                 let item = cx.tcx.hir().item(item_id);
                 if let hir::ItemKind::OpaqueTy(ref ty) = item.kind {
-                    ImplTrait(ty.bounds.clean(cx))
+                    ImplTrait(ty.bounds.iter().map(|x| x.clean(cx)).collect())
                 } else {
                     unreachable!()
                 }
@@ -1481,7 +1453,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
 
                 DynTrait(bounds, lifetime)
             }
-            ty::Tuple(t) => Tuple(t.iter().map(|t| t.expect_ty()).collect::<Vec<_>>().clean(cx)),
+            ty::Tuple(t) => Tuple(t.iter().map(|t| t.expect_ty().clean(cx)).collect()),
 
             ty::Projection(ref data) => data.clean(cx),
 
@@ -1714,7 +1686,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Variant {
 
 impl Clean<Path> for hir::Path<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Path {
-        Path { res: self.res, segments: self.segments.clean(cx) }
+        Path { res: self.res, segments: self.segments.iter().map(|x| x.clean(cx)).collect() }
     }
 }
 
@@ -1724,24 +1696,24 @@ fn clean(&self, cx: &mut DocContext<'_>) -> GenericArgs {
             let output = self.bindings[0].ty().clean(cx);
             let output =
                 if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None };
-            GenericArgs::Parenthesized { inputs: self.inputs().clean(cx), output }
+            let inputs = self.inputs().iter().map(|x| x.clean(cx)).collect();
+            GenericArgs::Parenthesized { inputs, output }
         } else {
-            GenericArgs::AngleBracketed {
-                args: self
-                    .args
-                    .iter()
-                    .map(|arg| match arg {
-                        hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
-                            GenericArg::Lifetime(lt.clean(cx))
-                        }
-                        hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
-                        hir::GenericArg::Type(ty) => GenericArg::Type(ty.clean(cx)),
-                        hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(ct.clean(cx))),
-                        hir::GenericArg::Infer(_inf) => GenericArg::Infer,
-                    })
-                    .collect(),
-                bindings: self.bindings.clean(cx),
-            }
+            let args = self
+                .args
+                .iter()
+                .map(|arg| match arg {
+                    hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
+                        GenericArg::Lifetime(lt.clean(cx))
+                    }
+                    hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
+                    hir::GenericArg::Type(ty) => GenericArg::Type(ty.clean(cx)),
+                    hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(ct.clean(cx))),
+                    hir::GenericArg::Infer(_inf) => GenericArg::Infer,
+                })
+                .collect();
+            let bindings = self.bindings.iter().map(|x| x.clean(cx)).collect();
+            GenericArgs::AngleBracketed { args, bindings }
         }
     }
 }
@@ -1755,7 +1727,9 @@ fn clean(&self, cx: &mut DocContext<'_>) -> PathSegment {
 impl Clean<BareFunctionDecl> for hir::BareFnTy<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> BareFunctionDecl {
         let (generic_params, decl) = enter_impl_trait(cx, |cx| {
-            (self.generic_params.clean(cx), (&*self.decl, self.param_names).clean(cx))
+            let generic_params = self.generic_params.iter().map(|x| x.clean(cx)).collect();
+            let decl = (self.decl, self.param_names).clean(cx);
+            (generic_params, decl)
         });
         BareFunctionDecl { unsafety: self.unsafety, abi: self.abi, decl, generic_params }
     }
@@ -1778,7 +1752,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Vec<Item> {
                     kind: ConstantKind::Local { body: body_id, def_id },
                 }),
                 ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy {
-                    bounds: ty.bounds.clean(cx),
+                    bounds: ty.bounds.iter().map(|x| x.clean(cx)).collect(),
                     generics: ty.generics.clean(cx),
                 }),
                 ItemKind::TyAlias(hir_ty, ref generics) => {
@@ -1800,17 +1774,17 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Vec<Item> {
                 }),
                 ItemKind::TraitAlias(ref generics, bounds) => TraitAliasItem(TraitAlias {
                     generics: generics.clean(cx),
-                    bounds: bounds.clean(cx),
+                    bounds: bounds.iter().map(|x| x.clean(cx)).collect(),
                 }),
                 ItemKind::Union(ref variant_data, ref generics) => UnionItem(Union {
                     generics: generics.clean(cx),
-                    fields: variant_data.fields().clean(cx),
+                    fields: variant_data.fields().iter().map(|x| x.clean(cx)).collect(),
                     fields_stripped: false,
                 }),
                 ItemKind::Struct(ref variant_data, ref generics) => StructItem(Struct {
                     struct_type: CtorKind::from_hir(variant_data),
                     generics: generics.clean(cx),
-                    fields: variant_data.fields().clean(cx),
+                    fields: variant_data.fields().iter().map(|x| x.clean(cx)).collect(),
                     fields_stripped: false,
                 }),
                 ItemKind::Impl(ref impl_) => return clean_impl(impl_, item.hir_id(), cx),
@@ -1819,7 +1793,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Vec<Item> {
                     clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
                 }
                 ItemKind::Macro(ref macro_def) => MacroItem(Macro {
-                    source: display_macro_source(cx, name, macro_def, def_id, &item.vis),
+                    source: display_macro_source(cx, name, macro_def, def_id, item.vis),
                 }),
                 ItemKind::Trait(is_auto, unsafety, ref generics, bounds, item_ids) => {
                     let items = item_ids
@@ -1830,7 +1804,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Vec<Item> {
                         unsafety,
                         items,
                         generics: generics.clean(cx),
-                        bounds: bounds.clean(cx),
+                        bounds: bounds.iter().map(|x| x.clean(cx)).collect(),
                         is_auto: is_auto.clean(cx),
                     })
                 }
@@ -1858,22 +1832,10 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Item {
     }
 }
 
-impl Clean<bool> for ty::ImplPolarity {
-    /// Returns whether the impl has negative polarity.
-    fn clean(&self, _: &mut DocContext<'_>) -> bool {
-        match self {
-            &ty::ImplPolarity::Positive |
-            // FIXME: do we want to do something else here?
-            &ty::ImplPolarity::Reservation => false,
-            &ty::ImplPolarity::Negative => true,
-        }
-    }
-}
-
 fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>) -> Vec<Item> {
     let tcx = cx.tcx;
     let mut ret = Vec::new();
-    let trait_ = impl_.of_trait.clean(cx);
+    let trait_ = impl_.of_trait.as_ref().map(|t| t.clean(cx));
     let items =
         impl_.items.iter().map(|ii| tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>();
     let def_id = tcx.hir().local_def_id(hir_id);
@@ -1891,15 +1853,13 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>
     });
     let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
         let kind = ImplItem(Impl {
-            span: types::rustc_span(tcx.hir().local_def_id(hir_id).to_def_id(), tcx),
             unsafety: impl_.unsafety,
             generics: impl_.generics.clean(cx),
             trait_,
             for_,
             items,
-            negative_polarity: tcx.impl_polarity(def_id).clean(cx),
-            synthetic: false,
-            blanket_impl: None,
+            polarity: tcx.impl_polarity(def_id),
+            kind: ImplKind::Normal,
         });
         Item::from_hir_id_and_parts(hir_id, None, kind, cx)
     };
@@ -2065,9 +2025,8 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Item {
             let kind = match item.kind {
                 hir::ForeignItemKind::Fn(decl, names, ref generics) => {
                     let abi = cx.tcx.hir().get_foreign_abi(item.hir_id());
-                    let (generics, decl) = enter_impl_trait(cx, |cx| {
-                        (generics.clean(cx), (&*decl, &names[..]).clean(cx))
-                    });
+                    let (generics, decl) =
+                        enter_impl_trait(cx, |cx| (generics.clean(cx), (decl, names).clean(cx)));
                     ForeignFunctionItem(Function {
                         decl,
                         generics,
index e91d0aa839d957996d06d33b53c752cef89ebefa..fd4d620c9591e12ab03359b7e5fe6c0177abd807 100644 (file)
@@ -391,12 +391,19 @@ impl Item {
             ItemKind::StrippedItem(k) => k,
             _ => &*self.kind,
         };
-        if let ItemKind::ModuleItem(Module { span, .. }) | ItemKind::ImplItem(Impl { span, .. }) =
-            kind
-        {
-            *span
-        } else {
-            self.def_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy)
+        match kind {
+            ItemKind::ModuleItem(Module { span, .. }) => *span,
+            ItemKind::ImplItem(Impl { kind: ImplKind::Auto, .. }) => Span::dummy(),
+            ItemKind::ImplItem(Impl { kind: ImplKind::Blanket(_), .. }) => {
+                if let ItemId::Blanket { impl_id, .. } = self.def_id {
+                    rustc_span(impl_id, tcx)
+                } else {
+                    panic!("blanket impl item has non-blanket ID")
+                }
+            }
+            _ => {
+                self.def_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy)
+            }
         }
     }
 
@@ -789,6 +796,7 @@ fn other_attrs(&self) -> Vec<ast::Attribute> {
     fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>> {
         let sess = tcx.sess;
         let doc_cfg_active = tcx.features().doc_cfg;
+        let doc_auto_cfg_active = tcx.features().doc_auto_cfg;
 
         fn single<T: IntoIterator>(it: T) -> Option<T::Item> {
             let mut iter = it.into_iter();
@@ -799,24 +807,26 @@ fn single<T: IntoIterator>(it: T) -> Option<T::Item> {
             Some(item)
         }
 
-        let mut cfg = if doc_cfg_active {
+        let mut cfg = if doc_cfg_active || doc_auto_cfg_active {
             let mut doc_cfg = self
                 .iter()
                 .filter(|attr| attr.has_name(sym::doc))
                 .flat_map(|attr| attr.meta_item_list().unwrap_or_else(Vec::new))
                 .filter(|attr| attr.has_name(sym::cfg))
                 .peekable();
-            if doc_cfg.peek().is_some() {
+            if doc_cfg.peek().is_some() && doc_cfg_active {
                 doc_cfg
                     .filter_map(|attr| Cfg::parse(attr.meta_item()?).ok())
                     .fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
-            } else {
+            } else if doc_auto_cfg_active {
                 self.iter()
                     .filter(|attr| attr.has_name(sym::cfg))
                     .filter_map(|attr| single(attr.meta_item_list()?))
                     .filter_map(|attr| Cfg::parse(attr.meta_item()?).ok())
                     .filter(|cfg| !hidden_cfg.contains(cfg))
                     .fold(Cfg::True, |cfg, new_cfg| cfg & new_cfg)
+            } else {
+                Cfg::True
             }
         } else {
             Cfg::True
@@ -2162,15 +2172,13 @@ impl Constant {
 
 #[derive(Clone, Debug)]
 crate struct Impl {
-    crate span: Span,
     crate unsafety: hir::Unsafety,
     crate generics: Generics,
     crate trait_: Option<Path>,
     crate for_: Type,
     crate items: Vec<Item>,
-    crate negative_polarity: bool,
-    crate synthetic: bool,
-    crate blanket_impl: Option<Box<Type>>,
+    crate polarity: ty::ImplPolarity,
+    crate kind: ImplKind,
 }
 
 impl Impl {
@@ -2183,6 +2191,30 @@ impl Impl {
     }
 }
 
+#[derive(Clone, Debug)]
+crate enum ImplKind {
+    Normal,
+    Auto,
+    Blanket(Box<Type>),
+}
+
+impl ImplKind {
+    crate fn is_auto(&self) -> bool {
+        matches!(self, ImplKind::Auto)
+    }
+
+    crate fn is_blanket(&self) -> bool {
+        matches!(self, ImplKind::Blanket(_))
+    }
+
+    crate fn as_blanket_ty(&self) -> Option<&Type> {
+        match self {
+            ImplKind::Blanket(ty) => Some(ty),
+            _ => None,
+        }
+    }
+}
+
 #[derive(Clone, Debug)]
 crate struct Import {
     crate kind: ImportKind,
index f84850c0fe1f1c1531ccd4b59d06698fa516cebb..cd0f44e5696fec3e2038dcb5d5a76f24b8fbfbb5 100644 (file)
@@ -20,22 +20,28 @@ fn fold_inner_recur(&mut self, kind: ItemKind) -> ItemKind {
             StructItem(mut i) => {
                 let num_fields = i.fields.len();
                 i.fields = i.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
-                i.fields_stripped |=
-                    num_fields != i.fields.len() || i.fields.iter().any(|f| f.is_stripped());
+                if !i.fields_stripped {
+                    i.fields_stripped =
+                        num_fields != i.fields.len() || i.fields.iter().any(|f| f.is_stripped());
+                }
                 StructItem(i)
             }
             UnionItem(mut i) => {
                 let num_fields = i.fields.len();
                 i.fields = i.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
-                i.fields_stripped |=
-                    num_fields != i.fields.len() || i.fields.iter().any(|f| f.is_stripped());
+                if !i.fields_stripped {
+                    i.fields_stripped =
+                        num_fields != i.fields.len() || i.fields.iter().any(|f| f.is_stripped());
+                }
                 UnionItem(i)
             }
             EnumItem(mut i) => {
                 let num_variants = i.variants.len();
                 i.variants = i.variants.into_iter().filter_map(|x| self.fold_item(x)).collect();
-                i.variants_stripped |=
-                    num_variants != i.variants.len() || i.variants.iter().any(|f| f.is_stripped());
+                if !i.variants_stripped {
+                    i.variants_stripped = num_variants != i.variants.len()
+                        || i.variants.iter().any(|f| f.is_stripped());
+                }
                 EnumItem(i)
             }
             TraitItem(mut i) => {
@@ -46,24 +52,42 @@ fn fold_inner_recur(&mut self, kind: ItemKind) -> ItemKind {
                 i.items = i.items.into_iter().filter_map(|x| self.fold_item(x)).collect();
                 ImplItem(i)
             }
-            VariantItem(i) => {
-                let i2 = i.clone(); // this clone is small
-                match i {
-                    Variant::Struct(mut j) => {
-                        let num_fields = j.fields.len();
-                        j.fields = j.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
-                        j.fields_stripped |= num_fields != j.fields.len()
+            VariantItem(i) => match i {
+                Variant::Struct(mut j) => {
+                    let num_fields = j.fields.len();
+                    j.fields = j.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
+                    if !j.fields_stripped {
+                        j.fields_stripped = num_fields != j.fields.len()
                             || j.fields.iter().any(|f| f.is_stripped());
-                        VariantItem(Variant::Struct(j))
-                    }
-                    Variant::Tuple(fields) => {
-                        let fields = fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
-                        VariantItem(Variant::Tuple(fields))
                     }
-                    _ => VariantItem(i2),
+                    VariantItem(Variant::Struct(j))
                 }
-            }
-            x => x,
+                Variant::Tuple(fields) => {
+                    let fields = fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
+                    VariantItem(Variant::Tuple(fields))
+                }
+                Variant::CLike => VariantItem(Variant::CLike),
+            },
+            ExternCrateItem { src: _ }
+            | ImportItem(_)
+            | FunctionItem(_)
+            | TypedefItem(_, _)
+            | OpaqueTyItem(_)
+            | StaticItem(_)
+            | ConstantItem(_)
+            | TraitAliasItem(_)
+            | TyMethodItem(_)
+            | MethodItem(_, _)
+            | StructFieldItem(_)
+            | ForeignFunctionItem(_)
+            | ForeignStaticItem(_)
+            | ForeignTypeItem
+            | MacroItem(_)
+            | ProcMacroItem(_)
+            | PrimitiveItem(_)
+            | AssocConstItem(_, _)
+            | AssocTypeItem(_, _)
+            | KeywordItem(_) => kind,
         }
     }
 
@@ -86,14 +110,12 @@ fn fold_mod(&mut self, m: Module) -> Module {
     fn fold_crate(&mut self, mut c: Crate) -> Crate {
         c.module = self.fold_item(c.module).unwrap();
 
-        {
-            let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) };
-            for (k, mut v) in external_traits {
-                v.trait_.items =
-                    v.trait_.items.into_iter().filter_map(|i| self.fold_item(i)).collect();
-                c.external_traits.borrow_mut().insert(k, v);
-            }
+        let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) };
+        for (k, mut v) in external_traits {
+            v.trait_.items = v.trait_.items.into_iter().filter_map(|i| self.fold_item(i)).collect();
+            c.external_traits.borrow_mut().insert(k, v);
         }
+
         c
     }
 }
index 6b9c9a9669b1a4a4284e9ff6877f0b9e37221d5d..a929cd094f8c3bcb6417d1f35c937786540c4888 100644 (file)
@@ -228,7 +228,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
         // Collect all the implementors of traits.
         if let clean::ImplItem(ref i) = *item.kind {
             if let Some(trait_) = &i.trait_ {
-                if i.blanket_impl.is_none() {
+                if !i.kind.is_blanket() {
                     self.cache
                         .implementors
                         .entry(trait_.def_id())
index c51bda60b73853b1142e2766aa156159fe1c85b6..4f2049132046d8a534a9c8e9069a15d836d5be84 100644 (file)
@@ -14,6 +14,7 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::CRATE_DEF_INDEX;
 use rustc_target::spec::abi::Abi;
@@ -990,14 +991,15 @@ impl clean::Impl {
             }
 
             if let Some(ref ty) = self.trait_ {
-                if self.negative_polarity {
-                    write!(f, "!")?;
+                match self.polarity {
+                    ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => {}
+                    ty::ImplPolarity::Negative => write!(f, "!")?,
                 }
                 fmt::Display::fmt(&ty.print(cx), f)?;
                 write!(f, " for ")?;
             }
 
-            if let Some(ref ty) = self.blanket_impl {
+            if let Some(ref ty) = self.kind.as_blanket_ty() {
                 fmt_type(ty, f, use_absolute, cx)?;
             } else {
                 fmt_type(&self.for_, f, use_absolute, cx)?;
index a33bb3479cea7603a4a7c8e2d95a1030d55dfe9f..e177a11303643d645ef0a9aac29cfaff9bc54047 100644 (file)
@@ -270,12 +270,18 @@ struct Decorations {
 
 impl Decorations {
     fn new(info: DecorationInfo) -> Self {
-        let (starts, ends) = info
+        // Extract tuples (start, end, kind) into separate sequences of (start, kind) and (end).
+        let (mut starts, mut ends): (Vec<_>, Vec<_>) = info
             .0
             .into_iter()
             .map(|(kind, ranges)| ranges.into_iter().map(move |(lo, hi)| ((lo, kind), hi)))
             .flatten()
             .unzip();
+
+        // Sort the sequences in document order.
+        starts.sort_by_key(|(lo, _)| *lo);
+        ends.sort();
+
         Decorations { starts, ends }
     }
 }
index 76e46fa0aa35483ebef4d569960f4650e1083a35..069862efde6409a0a49891cd32263b08b836a5c7 100644 (file)
@@ -461,9 +461,9 @@ fn init(
             }
         }
 
-        let (mut krate, local_sources, matches) = collect_spans_and_sources(
+        let (local_sources, matches) = collect_spans_and_sources(
             tcx,
-            krate,
+            &krate,
             &src_root,
             include_sources,
             generate_link_to_definition,
@@ -522,7 +522,7 @@ fn init(
         };
 
         if emit_crate {
-            krate = sources::render(&mut cx, krate)?;
+            sources::render(&mut cx, &krate)?;
         }
 
         // Build our search index
index f78129050d7ec6124b67e97374c5e7501ab96f0c..fdadc68998dc663f98609c190841b75d3f09f5f8 100644 (file)
@@ -34,8 +34,8 @@
 mod templates;
 mod write_shared;
 
-crate use context::*;
-crate use span_map::{collect_spans_and_sources, LinkFromSrc};
+crate use self::context::*;
+crate use self::span_map::{collect_spans_and_sources, LinkFromSrc};
 
 use std::collections::VecDeque;
 use std::default::Default;
@@ -54,6 +54,7 @@
 use rustc_hir::def_id::DefId;
 use rustc_hir::Mutability;
 use rustc_middle::middle::stability;
+use rustc_middle::ty;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::{
     symbol::{kw, sym, Symbol},
@@ -76,7 +77,7 @@
 use crate::html::highlight;
 use crate::html::markdown::{HeadingOffset, Markdown, MarkdownHtml, MarkdownSummaryLine};
 use crate::html::sources;
-use crate::scrape_examples::CallData;
+use crate::scrape_examples::{CallData, CallLocation};
 use crate::try_none;
 
 /// A pair of name and its optional document.
@@ -1147,9 +1148,9 @@ fn render_assoc_items_inner(
         }
 
         let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
-            traits.iter().partition(|t| t.inner_impl().synthetic);
+            traits.iter().partition(|t| t.inner_impl().kind.is_auto());
         let (blanket_impl, concrete): (Vec<&&Impl>, _) =
-            concrete.into_iter().partition(|t| t.inner_impl().blanket_impl.is_some());
+            concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket());
 
         let mut impls = Buffer::empty_from(w);
         render_impls(cx, &mut impls, &concrete, containing_item);
@@ -2033,12 +2034,12 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
                             let i_display = format!("{:#}", i.print(cx));
                             let out = Escape(&i_display);
                             let encoded = small_url_encode(format!("{:#}", i.print(cx)));
-                            let generated = format!(
-                                "<a href=\"#impl-{}\">{}{}</a>",
-                                encoded,
-                                if it.inner_impl().negative_polarity { "!" } else { "" },
-                                out
-                            );
+                            let prefix = match it.inner_impl().polarity {
+                                ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
+                                ty::ImplPolarity::Negative => "!",
+                            };
+                            let generated =
+                                format!("<a href=\"#impl-{}\">{}{}</a>", encoded, prefix, out);
                             if links.insert(generated.clone()) { Some(generated) } else { None }
                         } else {
                             None
@@ -2058,10 +2059,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
             };
 
             let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
-                v.iter().partition::<Vec<_>, _>(|i| i.inner_impl().synthetic);
-            let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) = concrete
-                .into_iter()
-                .partition::<Vec<_>, _>(|i| i.inner_impl().blanket_impl.is_some());
+                v.iter().partition::<Vec<_>, _>(|i| i.inner_impl().kind.is_auto());
+            let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) =
+                concrete.into_iter().partition::<Vec<_>, _>(|i| i.inner_impl().kind.is_blanket());
 
             let concrete_format = format_impls(concrete);
             let synthetic_format = format_impls(synthetic);
@@ -2594,6 +2594,21 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
         id = id
     );
 
+    // Create a URL to a particular location in a reverse-dependency's source file
+    let link_to_loc = |call_data: &CallData, loc: &CallLocation| -> (String, String) {
+        let (line_lo, line_hi) = loc.call_expr.line_span;
+        let (anchor, title) = if line_lo == line_hi {
+            ((line_lo + 1).to_string(), format!("line {}", line_lo + 1))
+        } else {
+            (
+                format!("{}-{}", line_lo + 1, line_hi + 1),
+                format!("lines {}-{}", line_lo + 1, line_hi + 1),
+            )
+        };
+        let url = format!("{}{}#{}", cx.root_path(), call_data.url, anchor);
+        (url, title)
+    };
+
     // Generate the HTML for a single example, being the title and code block
     let write_example = |w: &mut Buffer, (path, call_data): (&PathBuf, &CallData)| -> bool {
         let contents = match fs::read_to_string(&path) {
@@ -2631,15 +2646,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
                 let (line_lo, line_hi) = loc.call_expr.line_span;
                 let byte_range = (byte_lo - byte_min, byte_hi - byte_min);
                 let line_range = (line_lo - line_min, line_hi - line_min);
-                let (anchor, line_title) = if line_lo == line_hi {
-                    (format!("{}", line_lo + 1), format!("line {}", line_lo + 1))
-                } else {
-                    (
-                        format!("{}-{}", line_lo + 1, line_hi + 1),
-                        format!("lines {}-{}", line_lo + 1, line_hi + 1),
-                    )
-                };
-                let line_url = format!("{}{}#{}", cx.root_path(), call_data.url, anchor);
+                let (line_url, line_title) = link_to_loc(call_data, loc);
 
                 (byte_range, (line_range, line_url, line_title))
             })
@@ -2768,11 +2775,11 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
         if it.peek().is_some() {
             write!(w, r#"<div class="example-links">Additional examples can be found in:<br><ul>"#);
             it.for_each(|(_, call_data)| {
+                let (url, _) = link_to_loc(&call_data, &call_data.locations[0]);
                 write!(
                     w,
-                    r#"<li><a href="{root}{url}">{name}</a></li>"#,
-                    root = cx.root_path(),
-                    url = call_data.url,
+                    r#"<li><a href="{url}">{name}</a></li>"#,
+                    url = url,
                     name = call_data.display_name
                 );
             });
index d07ef6db4c6b0127e230d267e2d9e2f06be85bcd..7ef773fe5ff29dde2338ef963426cb4d5b2b419f 100644 (file)
@@ -746,7 +746,7 @@ fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item
         });
 
         let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) =
-            local.iter().partition(|i| i.inner_impl().synthetic);
+            local.iter().partition(|i| i.inner_impl().kind.is_auto());
 
         synthetic.sort_by(|a, b| compare_impl(a, b, cx));
         concrete.sort_by(|a, b| compare_impl(a, b, cx));
index 1a8562d05eab7cb3b13cac8b7d964aedcd220151..7803a779727c5b09e8ef033f6ecc343dd41b6c90 100644 (file)
 /// only keep the `lo` and `hi`.
 crate fn collect_spans_and_sources(
     tcx: TyCtxt<'_>,
-    krate: clean::Crate,
+    krate: &clean::Crate,
     src_root: &Path,
     include_sources: bool,
     generate_link_to_definition: bool,
-) -> (clean::Crate, FxHashMap<PathBuf, String>, FxHashMap<Span, LinkFromSrc>) {
+) -> (FxHashMap<PathBuf, String>, FxHashMap<Span, LinkFromSrc>) {
     let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };
 
     if include_sources {
         if generate_link_to_definition {
             tcx.hir().walk_toplevel_module(&mut visitor);
         }
-        let (krate, sources) = sources::collect_local_sources(tcx, src_root, krate);
-        (krate, sources, visitor.matches)
+        let sources = sources::collect_local_sources(tcx, src_root, &krate);
+        (sources, visitor.matches)
     } else {
-        (krate, Default::default(), Default::default())
+        (Default::default(), Default::default())
     }
 }
 
index 978701746b75b135acde7172be31087d7e1c4fc9..2d3b2490677e9b3e029cbad752a3a58368f6a965 100644 (file)
@@ -585,7 +585,7 @@ struct Implementor {
                 } else {
                     Some(Implementor {
                         text: imp.inner_impl().print(false, cx).to_string(),
-                        synthetic: imp.inner_impl().synthetic,
+                        synthetic: imp.inner_impl().kind.is_auto(),
                         types: collect_paths_for_type(imp.inner_impl().for_.clone(), cache),
                     })
                 }
index 9422f84f99775ce270269a885462b4c0cfcb475a..c8e93374e63ccd7abf8827a15c5e03cf31ef363d 100644 (file)
@@ -1,11 +1,11 @@
 use crate::clean;
 use crate::docfs::PathError;
 use crate::error::Error;
-use crate::fold::DocFolder;
 use crate::html::format::Buffer;
 use crate::html::highlight;
 use crate::html::layout;
 use crate::html::render::{Context, BASIC_KEYWORDS};
+use crate::visit::DocVisitor;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::ty::TyCtxt;
 use std::fs;
 use std::path::{Component, Path, PathBuf};
 
-crate fn render(cx: &mut Context<'_>, krate: clean::Crate) -> Result<clean::Crate, Error> {
+crate fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), Error> {
     info!("emitting source files");
+
     let dst = cx.dst.join("src").join(&*krate.name(cx.tcx()).as_str());
     cx.shared.ensure_dir(&dst)?;
-    let mut folder = SourceCollector { dst, cx, emitted_local_sources: FxHashSet::default() };
-    Ok(folder.fold_crate(krate))
+
+    let mut collector = SourceCollector { dst, cx, emitted_local_sources: FxHashSet::default() };
+    collector.visit_crate(krate);
+    Ok(())
 }
 
 crate fn collect_local_sources<'tcx>(
     tcx: TyCtxt<'tcx>,
     src_root: &Path,
-    krate: clean::Crate,
-) -> (clean::Crate, FxHashMap<PathBuf, String>) {
+    krate: &clean::Crate,
+) -> FxHashMap<PathBuf, String> {
     let mut lsc = LocalSourcesCollector { tcx, local_sources: FxHashMap::default(), src_root };
-
-    let krate = lsc.fold_crate(krate);
-    (krate, lsc.local_sources)
+    lsc.visit_crate(krate);
+    lsc.local_sources
 }
 
 struct LocalSourcesCollector<'a, 'tcx> {
@@ -42,7 +44,7 @@ struct LocalSourcesCollector<'a, 'tcx> {
 }
 
 fn is_real_and_local(span: clean::Span, sess: &Session) -> bool {
-    span.filename(sess).is_real() && span.cnum(sess) == LOCAL_CRATE
+    span.cnum(sess) == LOCAL_CRATE && span.filename(sess).is_real()
 }
 
 impl LocalSourcesCollector<'_, '_> {
@@ -54,12 +56,13 @@ fn add_local_source(&mut self, item: &clean::Item) {
             return;
         }
         let filename = span.filename(sess);
-        let p = match filename {
-            FileName::Real(ref file) => match file.local_path() {
-                Some(p) => p.to_path_buf(),
-                _ => return,
-            },
-            _ => return,
+        let p = if let FileName::Real(file) = filename {
+            match file.into_local_path() {
+                Some(p) => p,
+                None => return,
+            }
+        } else {
+            return;
         };
         if self.local_sources.contains_key(&*p) {
             // We've already emitted this source
@@ -79,13 +82,11 @@ fn add_local_source(&mut self, item: &clean::Item) {
     }
 }
 
-impl DocFolder for LocalSourcesCollector<'_, '_> {
-    fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
-        self.add_local_source(&item);
+impl DocVisitor for LocalSourcesCollector<'_, '_> {
+    fn visit_item(&mut self, item: &clean::Item) {
+        self.add_local_source(item);
 
-        // FIXME: if `include_sources` isn't set and DocFolder didn't require consuming the crate by value,
-        // we could return None here without having to walk the rest of the crate.
-        Some(self.fold_item_recur(item))
+        self.visit_item_recur(item)
     }
 }
 
@@ -98,8 +99,12 @@ struct SourceCollector<'a, 'tcx> {
     emitted_local_sources: FxHashSet<PathBuf>,
 }
 
-impl DocFolder for SourceCollector<'_, '_> {
-    fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
+impl DocVisitor for SourceCollector<'_, '_> {
+    fn visit_item(&mut self, item: &clean::Item) {
+        if !self.cx.include_sources {
+            return;
+        }
+
         let tcx = self.cx.tcx();
         let span = item.span(tcx);
         let sess = tcx.sess;
@@ -107,7 +112,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
         // If we're not rendering sources, there's nothing to do.
         // If we're including source files, and we haven't seen this file yet,
         // then we need to render it out to the filesystem.
-        if self.cx.include_sources && is_real_and_local(span, sess) {
+        if is_real_and_local(span, sess) {
             let filename = span.filename(sess);
             let span = span.inner();
             let pos = sess.source_map().lookup_source_file(span.lo());
@@ -132,9 +137,8 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                 }
             };
         }
-        // FIXME: if `include_sources` isn't set and DocFolder didn't require consuming the crate by value,
-        // we could return None here without having to walk the rest of the crate.
-        Some(self.fold_item_recur(item))
+
+        self.visit_item_recur(item)
     }
 }
 
index 0a196edd53b1dd063900a27a45a598e8e49be2f8..37ea7b000339f0de6d57ed9b62afc5298eaa6f5d 100644 (file)
@@ -13,3 +13,12 @@ rules.
        /* It requires JS to work so no need to display it in this case. */
        display: none;
 }
+
+.sub {
+       /* The search bar and related controls don't work without JS */
+       display: none;
+}
+
+#theme-picker {
+       display: none;
+}
index 93cbc0debb945378213a53e68a42b68fa61d7054..89a763ef6d707fbf79a7117e261c4f4102230e74 100644 (file)
@@ -156,7 +156,8 @@ h1.fqn > .in-band > a:hover {
        section hierarchies. */
 h2,
 .top-doc h3,
-.top-doc h4 {
+.top-doc h4,
+.sidebar .others h3 {
        border-bottom: 1px solid;
 }
 h3.code-header {
index f9c84dc3e318dc9e5023131c8c76e39143eb65b3..ba7fb3b5456a55425d76939bab0e56775f9da13e 100644 (file)
@@ -255,10 +255,6 @@ details.undocumented > summary::before {
        box-shadow: 0 0 0 1px #148099,0 0 0 2px transparent;
 }
 
-.search-input:disabled {
-       background-color: #3e3e3e;
-}
-
 .module-item .stab,
 .import-item .stab {
        color: #000;
index 9a38277d55905ca7a56e8b79b4d134c0059da7a8..77ac217e6f41dd9f76efc9b9c298ab4bc38d2889 100644 (file)
@@ -219,10 +219,6 @@ details.undocumented > summary::before {
        border-color: #008dfd;
 }
 
-.search-input:disabled {
-       background-color: #c5c4c4;
-}
-
 #crate-search + .search-input:focus {
        box-shadow: 0 0 8px 4px #078dd8;
 }
index fba8231caac31188420629851af0a03176b03768..6df137e39141508a88674a94a53c516efc79d9f1 100644 (file)
@@ -209,10 +209,6 @@ details.undocumented > summary::before {
        border-color: #66afe9;
 }
 
-.search-input:disabled {
-       background-color: #e6e6e6;
-}
-
 #crate-search + .search-input:focus {
        box-shadow: 0 0 8px #078dd8;
 }
index e396fd9d288db1cc34da37279113f4a65683b0c7..4b55a0a69b66358c2987337484c50e9e76cfd338 100644 (file)
@@ -263,7 +263,9 @@ function hideThemeButtonState() {
                 search_input.placeholder = searchState.input.origPlaceholder;
             });
 
-            search_input.removeAttribute('disabled');
+            if (search_input.value != '') {
+                loadSearch();
+            }
 
             // `crates{version}.js` should always be loaded before this script, so we can use it
             // safely.
@@ -564,6 +566,7 @@ function hideThemeButtonState() {
     // delayed sidebar rendering.
     window.initSidebarItems = function(items) {
         var sidebar = document.getElementsByClassName("sidebar-elems")[0];
+        var others;
         var current = window.sidebarCurrent;
 
         function addSidebarCrates(crates) {
@@ -592,7 +595,7 @@ function hideThemeButtonState() {
                 li.appendChild(link);
                 ul.appendChild(li);
             }
-            sidebar.appendChild(div);
+            others.appendChild(div);
         }
 
         function block(shortty, longty) {
@@ -633,10 +636,14 @@ function hideThemeButtonState() {
                 ul.appendChild(li);
             }
             div.appendChild(ul);
-            sidebar.appendChild(div);
+            others.appendChild(div);
         }
 
         if (sidebar) {
+            others = document.createElement("div");
+            others.className = "others";
+            sidebar.appendChild(others);
+
             var isModule = hasClass(document.body, "mod");
             if (!isModule) {
                 block("primitive", "Primitive Types");
index b0174d59a7be21463e999fccd92f968c8a9c066d..9fafea6914524ad3f8cb6ab503f179a5fbf797d6 100644 (file)
@@ -85,7 +85,6 @@
                     <input {# -#}
                         class="search-input" {# -#}
                         name="search" {# -#}
-                        disabled {# -#}
                         autocomplete="off" {# -#}
                         spellcheck="false" {# -#}
                         placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
          data-search-js="{{static_root_path | safe}}search{{page.resource_suffix}}.js"> {#- -#}
     </div>
     <script src="{{static_root_path | safe}}main{{page.resource_suffix}}.js"></script> {#- -#}
-    {%- if layout.scrape_examples_extension -%}
-    <script src="{{static_root_path | safe}}scrape-examples{{page.resource_suffix}}.js"></script> {#- -#}
-    {%- endif -%}
     {%- for script in page.static_extra_scripts -%}
     <script src="{{static_root_path | safe}}{{script}}.js"></script> {#- -#}
     {% endfor %}
+    {%- if layout.scrape_examples_extension -%}
+    <script src="{{page.root_path | safe}}scrape-examples{{page.resource_suffix}}.js"></script> {#- -#}
+    {%- endif -%}
     {%- for script in page.extra_scripts -%}
     <script src="{{page.root_path | safe}}{{script}}.js"></script> {#- -#}
     {% endfor %}
index f740ecdbded74a9a2ed9cdfe01ca99f2f6b5fce4..a46518ef489aa1b3bc1a53d38ad358800826b1ce 100644 (file)
@@ -9,7 +9,7 @@
 
 use rustc_ast::ast;
 use rustc_hir::{def::CtorKind, def_id::DefId};
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::def_id::CRATE_DEF_INDEX;
 use rustc_span::Pos;
 
@@ -500,22 +500,22 @@ fn from_tcx(trait_: clean::Trait, tcx: TyCtxt<'_>) -> Self {
 impl FromWithTcx<clean::Impl> for Impl {
     fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
         let provided_trait_methods = impl_.provided_trait_methods(tcx);
-        let clean::Impl {
-            unsafety,
-            generics,
-            trait_,
-            for_,
-            items,
-            negative_polarity,
-            synthetic,
-            blanket_impl,
-            span: _span,
-        } = impl_;
+        let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_;
         // FIXME: should `trait_` be a clean::Path equivalent in JSON?
         let trait_ = trait_.map(|path| {
             let did = path.def_id();
             clean::ResolvedPath { path, did }.into_tcx(tcx)
         });
+        // FIXME: use something like ImplKind in JSON?
+        let (synthetic, blanket_impl) = match kind {
+            clean::ImplKind::Normal => (false, None),
+            clean::ImplKind::Auto => (true, None),
+            clean::ImplKind::Blanket(ty) => (false, Some(*ty)),
+        };
+        let negative_polarity = match polarity {
+            ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => false,
+            ty::ImplPolarity::Negative => true,
+        };
         Impl {
             is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe,
             generics: generics.into_tcx(tcx),
@@ -528,7 +528,7 @@ fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
             items: ids(items),
             negative: negative_polarity,
             synthetic,
-            blanket_impl: blanket_impl.map(|x| (*x).into_tcx(tcx)),
+            blanket_impl: blanket_impl.map(|x| x.into_tcx(tcx)),
         }
     }
 }
index 8dceb2ec92a27929c068204f5f9ab87c5b5c3d67..938a0c507a524978be95cab939e7eaac453dab90 100644 (file)
@@ -122,6 +122,7 @@ macro_rules! map {
 mod passes;
 mod scrape_examples;
 mod theme;
+mod visit;
 mod visit_ast;
 mod visit_lib;
 
index 4501914fe0c07e178ab681bbc00ce852ff4f888e..4e146a07d154a64b3f8d99eedd4b419d8f61d3db 100644 (file)
@@ -1,8 +1,8 @@
 use super::Pass;
 use crate::clean::*;
 use crate::core::DocContext;
-use crate::fold::DocFolder;
 use crate::html::markdown::main_body_opts;
+use crate::visit::DocVisitor;
 use core::ops::Range;
 use pulldown_cmark::{Event, Parser, Tag};
 use regex::Regex;
@@ -53,16 +53,17 @@ fn find_raw_urls(
 }
 
 crate fn check_bare_urls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
-    BareUrlsLinter { cx }.fold_crate(krate)
+    BareUrlsLinter { cx }.visit_crate(&krate);
+    krate
 }
 
-impl<'a, 'tcx> DocFolder for BareUrlsLinter<'a, 'tcx> {
-    fn fold_item(&mut self, item: Item) -> Option<Item> {
+impl<'a, 'tcx> DocVisitor for BareUrlsLinter<'a, 'tcx> {
+    fn visit_item(&mut self, item: &Item) {
         let hir_id = match DocContext::as_local_hir_id(self.cx.tcx, item.def_id) {
             Some(hir_id) => hir_id,
             None => {
                 // If non-local, no need to check anything.
-                return Some(self.fold_item_recur(item));
+                return;
             }
         };
         let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
@@ -106,6 +107,6 @@ fn fold_item(&mut self, item: Item) -> Option<Item> {
             }
         }
 
-        Some(self.fold_item_recur(item))
+        self.visit_item_recur(item)
     }
 }
index 5e3bd41b85c7e060c89d94eb829a30f717f7b1c6..85542ebd9ac559f4c5ddcfc546bdc34b893bcac8 100644 (file)
@@ -1,9 +1,9 @@
 use crate::clean;
 use crate::core::DocContext;
-use crate::fold::{self, DocFolder};
 use crate::html::markdown::{find_testable_code, ErrorCodes};
 use crate::passes::check_doc_test_visibility::{should_have_doc_example, Tests};
 use crate::passes::Pass;
+use crate::visit::DocVisitor;
 use rustc_hir as hir;
 use rustc_lint::builtin::MISSING_DOCS;
 use rustc_middle::lint::LintLevelSource;
@@ -23,7 +23,7 @@
 
 fn calculate_doc_coverage(krate: clean::Crate, ctx: &mut DocContext<'_>) -> clean::Crate {
     let mut calc = CoverageCalculator { items: Default::default(), ctx };
-    let krate = calc.fold_crate(krate);
+    calc.visit_crate(&krate);
 
     calc.print_results();
 
@@ -182,17 +182,18 @@ fn print_table_record(
     }
 }
 
-impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
-    fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> {
+impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> {
+    fn visit_item(&mut self, i: &clean::Item) {
+        if !i.def_id.is_local() {
+            // non-local items are skipped because they can be out of the users control,
+            // especially in the case of trait impls, which rustdoc eagerly inlines
+            return;
+        }
+
         match *i.kind {
-            _ if !i.def_id.is_local() => {
-                // non-local items are skipped because they can be out of the users control,
-                // especially in the case of trait impls, which rustdoc eagerly inlines
-                return Some(i);
-            }
             clean::StrippedItem(..) => {
                 // don't count items in stripped modules
-                return Some(i);
+                return;
             }
             // docs on `use` and `extern crate` statements are not displayed, so they're not
             // worth counting
@@ -269,6 +270,6 @@ fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> {
             }
         }
 
-        Some(self.fold_item_recur(i))
+        self.visit_item_recur(i)
     }
 }
index b18208d26e2c478d3088c04288e8e90ff502828a..fd2ab0dc97cb2230373a3cfb9832eb6400170336 100644 (file)
@@ -8,9 +8,9 @@
 
 use crate::clean;
 use crate::core::DocContext;
-use crate::fold::DocFolder;
 use crate::html::markdown::{self, RustCodeBlock};
 use crate::passes::Pass;
+use crate::visit::DocVisitor;
 
 crate const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass {
     name: "check-code-block-syntax",
@@ -19,7 +19,8 @@
 };
 
 crate fn check_code_block_syntax(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
-    SyntaxChecker { cx }.fold_crate(krate)
+    SyntaxChecker { cx }.visit_crate(&krate);
+    krate
 }
 
 struct SyntaxChecker<'a, 'tcx> {
@@ -141,8 +142,8 @@ fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeB
     }
 }
 
-impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> {
-    fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
+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(
@@ -155,7 +156,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
             }
         }
 
-        Some(self.fold_item_recur(item))
+        self.visit_item_recur(item)
     }
 }
 
index 69a526d461810e99c421c27047a8e21b677a6d70..7d3010cf3325b327c03f2b67b93d2c7190de34eb 100644 (file)
@@ -7,8 +7,8 @@
 use crate::clean;
 use crate::clean::*;
 use crate::core::DocContext;
-use crate::fold::DocFolder;
 use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString};
+use crate::visit::DocVisitor;
 use crate::visit_ast::inherits_doc_hidden;
 use rustc_hir as hir;
 use rustc_middle::lint::LintLevelSource;
@@ -27,17 +27,17 @@ struct DocTestVisibilityLinter<'a, 'tcx> {
 
 crate fn check_doc_test_visibility(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
     let mut coll = DocTestVisibilityLinter { cx };
-
-    coll.fold_crate(krate)
+    coll.visit_crate(&krate);
+    krate
 }
 
-impl<'a, 'tcx> DocFolder for DocTestVisibilityLinter<'a, 'tcx> {
-    fn fold_item(&mut self, item: Item) -> Option<Item> {
+impl<'a, 'tcx> DocVisitor for DocTestVisibilityLinter<'a, 'tcx> {
+    fn visit_item(&mut self, item: &Item) {
         let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new);
 
         look_for_tests(self.cx, &dox, &item);
 
-        Some(self.fold_item_recur(item))
+        self.visit_item_recur(item)
     }
 }
 
index 9b2fe0c77e6cfe71985687d3ab5ec3e4eeb27bb6..8541e6e18816f5c783800fbe23be99e5780cc1fc 100644 (file)
 
 use crate::clean::{self, utils::find_nearest_parent_module, Crate, Item, ItemLink, PrimitiveType};
 use crate::core::DocContext;
-use crate::fold::DocFolder;
 use crate::html::markdown::{markdown_links, MarkdownLink};
 use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS};
 use crate::passes::Pass;
+use crate::visit::DocVisitor;
 
 mod early;
 crate use early::load_intra_link_crates;
 };
 
 fn collect_intra_doc_links(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
-    LinkCollector {
+    let mut collector = LinkCollector {
         cx,
         mod_ids: Vec::new(),
         kind_side_channel: Cell::new(None),
         visited_links: FxHashMap::default(),
-    }
-    .fold_crate(krate)
+    };
+    collector.visit_crate(&krate);
+    krate
 }
 
 /// Top-level errors emitted by this pass.
@@ -816,8 +817,8 @@ fn is_derive_trait_collision<T>(ns: &PerNS<Result<(Res, T), ResolutionFailure<'_
     )
 }
 
-impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
-    fn fold_item(&mut self, item: Item) -> Option<Item> {
+impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> {
+    fn visit_item(&mut self, item: &Item) {
         use rustc_middle::ty::DefIdTree;
 
         let parent_node =
@@ -911,17 +912,16 @@ fn fold_item(&mut self, item: Item) -> Option<Item> {
             }
         }
 
-        Some(if item.is_mod() {
+        if item.is_mod() {
             if !inner_docs {
                 self.mod_ids.push(item.def_id.expect_def_id());
             }
 
-            let ret = self.fold_item_recur(item);
+            self.visit_item_recur(item);
             self.mod_ids.pop();
-            ret
         } else {
-            self.fold_item_recur(item)
-        })
+            self.visit_item_recur(item)
+        }
     }
 }
 
index 7a4198198fa694ca15f2883e039972fe5a8a8410..ea50134f00d477c485322b5ef9c0f423a4086d4c 100644 (file)
@@ -1,7 +1,7 @@
 use super::Pass;
 use crate::clean::*;
 use crate::core::DocContext;
-use crate::fold::DocFolder;
+use crate::visit::DocVisitor;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::DefId;
     description: "retrieves trait impls for items in the crate",
 };
 
-crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
-    let (mut krate, synth_impls) = cx.sess().time("collect_synthetic_impls", || {
+crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate {
+    let synth_impls = cx.sess().time("collect_synthetic_impls", || {
         let mut synth = SyntheticImplCollector { cx, impls: Vec::new() };
-        (synth.fold_crate(krate), synth.impls)
+        synth.visit_crate(&krate);
+        synth.impls
     });
 
     let prims: FxHashSet<PrimitiveType> = krate.primitives.iter().map(|p| p.1).collect();
 
     let crate_items = {
         let mut coll = ItemCollector::new();
-        krate = cx.sess().time("collect_items_for_trait_impls", || coll.fold_crate(krate));
+        cx.sess().time("collect_items_for_trait_impls", || coll.visit_crate(&krate));
         coll.items
     };
 
@@ -110,12 +111,12 @@ fn add_deref_target(
     }
 
     new_items.retain(|it| {
-        if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
+        if let ImplItem(Impl { ref for_, ref trait_, ref kind, .. }) = *it.kind {
             cleaner.keep_impl(
                 for_,
                 trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait(),
             ) || trait_.as_ref().map_or(false, |t| cleaner.keep_impl_with_def_id(t.def_id().into()))
-                || blanket_impl.is_some()
+                || kind.is_blanket()
         } else {
             true
         }
@@ -152,14 +153,13 @@ fn add_deref_target(
         }
     }
 
-    let items = if let ModuleItem(Module { ref mut items, .. }) = *krate.module.kind {
-        items
+    if let ModuleItem(Module { items, .. }) = &mut *krate.module.kind {
+        items.extend(synth_impls);
+        items.extend(new_items);
     } else {
         panic!("collect-trait-impls can't run");
     };
 
-    items.extend(synth_impls);
-    items.extend(new_items);
     krate
 }
 
@@ -168,8 +168,8 @@ struct SyntheticImplCollector<'a, 'tcx> {
     impls: Vec<Item>,
 }
 
-impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> {
-    fn fold_item(&mut self, i: Item) -> Option<Item> {
+impl<'a, 'tcx> DocVisitor for SyntheticImplCollector<'a, 'tcx> {
+    fn visit_item(&mut self, i: &Item) {
         if i.is_struct() || i.is_enum() || i.is_union() {
             // FIXME(eddyb) is this `doc(hidden)` check needed?
             if !self
@@ -184,7 +184,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
             }
         }
 
-        Some(self.fold_item_recur(i))
+        self.visit_item_recur(i)
     }
 }
 
@@ -199,11 +199,11 @@ fn new() -> Self {
     }
 }
 
-impl DocFolder for ItemCollector {
-    fn fold_item(&mut self, i: Item) -> Option<Item> {
+impl DocVisitor for ItemCollector {
+    fn visit_item(&mut self, i: &Item) {
         self.items.insert(i.def_id);
 
-        Some(self.fold_item_recur(i))
+        self.visit_item_recur(i)
     }
 }
 
index a3fde92d7655d776e9bb27dbe1bff1ce7c5ee19c..56b222d893262148d94d4e9e794e37022fc90afd 100644 (file)
@@ -1,11 +1,13 @@
 use super::Pass;
 use crate::clean::*;
 use crate::core::DocContext;
-use crate::fold::DocFolder;
 use crate::html::markdown::main_body_opts;
-use core::ops::Range;
+use crate::visit::DocVisitor;
+
 use pulldown_cmark::{Event, Parser, Tag};
+
 use std::iter::Peekable;
+use std::ops::Range;
 use std::str::CharIndices;
 
 crate const CHECK_INVALID_HTML_TAGS: Pass = Pass {
@@ -19,13 +21,11 @@ struct InvalidHtmlTagsLinter<'a, 'tcx> {
 }
 
 crate fn check_invalid_html_tags(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
-    if !cx.tcx.sess.is_nightly_build() {
-        krate
-    } else {
+    if cx.tcx.sess.is_nightly_build() {
         let mut coll = InvalidHtmlTagsLinter { cx };
-
-        coll.fold_crate(krate)
+        coll.visit_crate(&krate);
     }
+    krate
 }
 
 const ALLOWED_UNCLOSED: &[&str] = &[
@@ -165,14 +165,14 @@ fn extract_tags(
     }
 }
 
-impl<'a, 'tcx> DocFolder for InvalidHtmlTagsLinter<'a, 'tcx> {
-    fn fold_item(&mut self, item: Item) -> Option<Item> {
+impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
+    fn visit_item(&mut self, item: &Item) {
         let tcx = self.cx.tcx;
         let hir_id = match DocContext::as_local_hir_id(tcx, item.def_id) {
             Some(hir_id) => hir_id,
             None => {
                 // If non-local, no need to check anything.
-                return Some(self.fold_item_recur(item));
+                return;
             }
         };
         let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
@@ -217,6 +217,6 @@ fn fold_item(&mut self, item: Item) -> Option<Item> {
             }
         }
 
-        Some(self.fold_item_recur(item))
+        self.visit_item_recur(item)
     }
 }
index fc54e55b87655e5cf7baa10961086ce07498532d..3b39e3576e69a39d22f577b29dd3ab4c173feebf 100644 (file)
@@ -10,7 +10,6 @@
 use rustc_hir::{
     self as hir,
     intravisit::{self, Visitor},
-    HirId,
 };
 use rustc_interface::interface;
 use rustc_macros::{Decodable, Encodable};
@@ -49,7 +48,7 @@ impl ScrapeExamplesOptions {
                 target_crates,
             })),
             (Some(_), false) | (None, true) => {
-                diag.err(&format!("must use --scrape-examples-output-path and --scrape-examples-target-crate together"));
+                diag.err("must use --scrape-examples-output-path and --scrape-examples-target-crate together");
                 Err(1)
             }
             (None, false) => Ok(None),
@@ -83,15 +82,10 @@ fn new(span: rustc_span::Span, file: &SourceFile) -> Self {
 
 impl CallLocation {
     fn new(
-        tcx: TyCtxt<'_>,
         expr_span: rustc_span::Span,
-        expr_id: HirId,
+        enclosing_item_span: rustc_span::Span,
         source_file: &SourceFile,
     ) -> Self {
-        let enclosing_item_span =
-            tcx.hir().span_with_body(tcx.hir().get_parent_item(expr_id)).source_callsite();
-        assert!(enclosing_item_span.contains(expr_span));
-
         CallLocation {
             call_expr: SyntaxRange::new(expr_span, source_file),
             enclosing_item: SyntaxRange::new(enclosing_item_span, source_file),
@@ -132,12 +126,28 @@ fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
     fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
         intravisit::walk_expr(self, ex);
 
-        // Get type of function if expression is a function call
         let tcx = self.tcx;
+
+        // If we visit an item that contains an expression outside a function body,
+        // then we need to exit before calling typeck (which will panic). See
+        // test/run-make/rustdoc-scrape-examples-invalid-expr for an example.
+        let hir = tcx.hir();
+        let owner = hir.local_def_id_to_hir_id(ex.hir_id.owner);
+        if hir.maybe_body_owned_by(owner).is_none() {
+            return;
+        }
+
+        // Get type of function if expression is a function call
         let (ty, span) = match ex.kind {
             hir::ExprKind::Call(f, _) => {
                 let types = tcx.typeck(ex.hir_id.owner);
-                (types.node_type(f.hir_id), ex.span)
+
+                match types.node_type_opt(f.hir_id) {
+                    Some(ty) => (ty, ex.span),
+                    None => {
+                        return;
+                    }
+                }
             }
             hir::ExprKind::MethodCall(_, _, _, span) => {
                 let types = tcx.typeck(ex.hir_id.owner);
@@ -152,13 +162,29 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
         // If this span comes from a macro expansion, then the source code may not actually show
         // a use of the given item, so it would be a poor example. Hence, we skip all uses in macros.
         if span.from_expansion() {
+            trace!("Rejecting expr from macro: {:?}", span);
             return;
         }
 
+        // If the enclosing item has a span coming from a proc macro, then we also don't want to include
+        // the example.
+        let enclosing_item_span = tcx.hir().span_with_body(tcx.hir().get_parent_item(ex.hir_id));
+        if enclosing_item_span.from_expansion() {
+            trace!("Rejecting expr ({:?}) from macro item: {:?}", span, enclosing_item_span);
+            return;
+        }
+
+        assert!(
+            enclosing_item_span.contains(span),
+            "Attempted to scrape call at [{:?}] whose enclosing item [{:?}] doesn't contain the span of the call.",
+            span,
+            enclosing_item_span
+        );
+
         // Save call site if the function resolves to a concrete definition
         if let ty::FnDef(def_id, _) = ty.kind() {
-            // Ignore functions not from the crate being documented
             if self.target_crates.iter().all(|krate| *krate != def_id.krate) {
+                trace!("Rejecting expr from crate not being documented: {:?}", span);
                 return;
             }
 
@@ -182,7 +208,8 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
                 let fn_key = tcx.def_path_hash(*def_id);
                 let fn_entries = self.calls.entry(fn_key).or_default();
 
-                let location = CallLocation::new(tcx, span, ex.hir_id, &file);
+                trace!("Including expr: {:?}", span);
+                let location = CallLocation::new(span, enclosing_item_span, &file);
                 fn_entries.entry(abs_path).or_insert_with(mk_call_data).locations.push(location);
             }
         }
@@ -224,6 +251,13 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
         let mut finder = FindCalls { calls: &mut calls, tcx, map: tcx.hir(), cx, target_crates };
         tcx.hir().visit_all_item_likes(&mut finder.as_deep_visitor());
 
+        // Sort call locations within a given file in document order
+        for fn_calls in calls.values_mut() {
+            for file_calls in fn_calls.values_mut() {
+                file_calls.locations.sort_by_key(|loc| loc.call_expr.byte_span.0);
+            }
+        }
+
         // Save output to provided path
         let mut encoder = FileEncoder::new(options.output_path).map_err(|e| e.to_string())?;
         calls.encode(&mut encoder).map_err(|e| e.to_string())?;
diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs
new file mode 100644 (file)
index 0000000..df4d155
--- /dev/null
@@ -0,0 +1,71 @@
+use crate::clean::*;
+
+crate trait DocVisitor: Sized {
+    fn visit_item(&mut self, item: &Item) {
+        self.visit_item_recur(item)
+    }
+
+    /// don't override!
+    fn visit_inner_recur(&mut self, kind: &ItemKind) {
+        match kind {
+            StrippedItem(..) => unreachable!(),
+            ModuleItem(i) => {
+                self.visit_mod(i);
+                return;
+            }
+            StructItem(i) => i.fields.iter().for_each(|x| self.visit_item(x)),
+            UnionItem(i) => i.fields.iter().for_each(|x| self.visit_item(x)),
+            EnumItem(i) => i.variants.iter().for_each(|x| self.visit_item(x)),
+            TraitItem(i) => i.items.iter().for_each(|x| self.visit_item(x)),
+            ImplItem(i) => i.items.iter().for_each(|x| self.visit_item(x)),
+            VariantItem(i) => match i {
+                Variant::Struct(j) => j.fields.iter().for_each(|x| self.visit_item(x)),
+                Variant::Tuple(fields) => fields.iter().for_each(|x| self.visit_item(x)),
+                Variant::CLike => {}
+            },
+            ExternCrateItem { src: _ }
+            | ImportItem(_)
+            | FunctionItem(_)
+            | TypedefItem(_, _)
+            | OpaqueTyItem(_)
+            | StaticItem(_)
+            | ConstantItem(_)
+            | TraitAliasItem(_)
+            | TyMethodItem(_)
+            | MethodItem(_, _)
+            | StructFieldItem(_)
+            | ForeignFunctionItem(_)
+            | ForeignStaticItem(_)
+            | ForeignTypeItem
+            | MacroItem(_)
+            | ProcMacroItem(_)
+            | PrimitiveItem(_)
+            | AssocConstItem(_, _)
+            | AssocTypeItem(_, _)
+            | KeywordItem(_) => {}
+        }
+    }
+
+    /// don't override!
+    fn visit_item_recur(&mut self, item: &Item) {
+        match &*item.kind {
+            StrippedItem(i) => self.visit_inner_recur(i),
+            _ => self.visit_inner_recur(&item.kind),
+        }
+    }
+
+    fn visit_mod(&mut self, m: &Module) {
+        m.items.iter().for_each(|i| self.visit_item(i))
+    }
+
+    fn visit_crate(&mut self, c: &Crate) {
+        self.visit_item(&c.module);
+
+        // FIXME: make this a simple by-ref for loop once external_traits is cleaned up
+        let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) };
+        for (k, v) in external_traits {
+            v.trait_.items.iter().for_each(|i| self.visit_item(i));
+            c.external_traits.borrow_mut().insert(k, v);
+        }
+    }
+}
index 66c39a48c6e1d5fbc1ecb2ea3207c5dedeb4af37..04b5f4aed9bb5c87ef34b0658a78c60586022d39 100644 (file)
@@ -2,7 +2,7 @@
 // compile-flags: --target aarch64-unknown-linux-gnu
 // needs-llvm-components: aarch64
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_sym)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
index c848e3284ff1f06bb1926b6ba7587e13b2bb5983..0c57b1fc4782de50a8752cb372d439e973ea18b9 100644 (file)
@@ -3,7 +3,7 @@
 // compile-flags: -C target-feature=+neon
 // needs-llvm-components: arm
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_sym)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
index 7271ef11287efcfd8c6614ffd25291adc5fb7045..3428d93fb1205d60b3e3040a76996cbbc4552c08 100644 (file)
@@ -3,7 +3,7 @@
 // compile-flags: --target bpfel-unknown-none -C target_feature=+alu32
 // needs-llvm-components: bpf
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_sym, asm_experimental_arch)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
index 1c981040d601474da4547213aa610003c4e16e0d..7e48c386abcde7cc978b0e5ef4653413e00a8601 100644 (file)
@@ -2,7 +2,7 @@
 // assembly-output: emit-asm
 // compile-flags: -C llvm-args=--x86-asm-syntax=intel
 
-#![feature(asm, global_asm)]
+#![feature(global_asm, asm_const)]
 #![crate_type = "rlib"]
 
 // CHECK: mov eax, eax
index 2156d77233d83888f99ed4ee9454596dfb4920e2..de310c78488d9e9fea925fb0f32644c61898cefc 100644 (file)
@@ -2,7 +2,7 @@
 // compile-flags: --target hexagon-unknown-linux-musl
 // needs-llvm-components: hexagon
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_sym, asm_experimental_arch)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
index eb6627639f159d5d77a02c6e9756b7cdcffa5204..04bf49a40efbcd0b816754138a36717b5e64b6f3 100644 (file)
@@ -5,7 +5,7 @@
 //[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64
 //[mips64] needs-llvm-components: mips
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_sym, asm_experimental_arch)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
index cc816fd78f81e2063c66a74e2740afe941b2182f..3ebd5b4b89681252dd4bc3715a03a55b408e7d02 100644 (file)
@@ -3,7 +3,7 @@
 // compile-flags: --crate-type cdylib
 // needs-llvm-components: nvptx
 
-#![feature(no_core, lang_items, rustc_attrs)]
+#![feature(no_core, lang_items, rustc_attrs, asm_sym, asm_experimental_arch)]
 #![no_core]
 
 #[rustc_builtin_macro]
index 342998245315e8be0eeb55ce1bfb4c235b218d3b..b8859c07e164fe03a38ba7654802920bf488f6bc 100644 (file)
@@ -6,7 +6,7 @@
 //[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
 //[powerpc64] needs-llvm-components: powerpc
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_sym, asm_experimental_arch)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
index c510689b42bff788ce2ac9626c10a10446eabf08..0f9f61bd6d916a85d4bd7c5aa908574949e2aaa1 100644 (file)
@@ -6,7 +6,7 @@
 //[riscv32] needs-llvm-components: riscv
 // compile-flags: -C target-feature=+d
 
-#![feature(no_core, lang_items, rustc_attrs)]
+#![feature(no_core, lang_items, rustc_attrs, asm_sym)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register)]
index b8a4ca08df1cc8ce2d06a39ad7513558b69ede8c..6a12902a0461f711d76f08bdfb70428b37c53c95 100644 (file)
@@ -3,7 +3,7 @@
 //[s390x] compile-flags: --target s390x-unknown-linux-gnu
 //[s390x] needs-llvm-components: systemz
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_sym, asm_experimental_arch)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
index 4b2e83e69b1065ba5701286557cbcbc373176632..3aa128c46ac01f8e6ef8e824a0f5fd66ff88674b 100644 (file)
@@ -3,7 +3,7 @@
 // compile-flags: --crate-type cdylib
 // needs-llvm-components: webassembly
 
-#![feature(no_core, lang_items, rustc_attrs)]
+#![feature(no_core, lang_items, rustc_attrs, asm_sym, asm_experimental_arch)]
 #![no_core]
 
 #[rustc_builtin_macro]
index 81be79cbaac18c25d8e9516bd8bb6327bdb6b92d..e871535cfdeef75a79da05884a06faa1b4c911cd 100644 (file)
@@ -7,7 +7,7 @@
 // compile-flags: -C llvm-args=--x86-asm-syntax=intel
 // compile-flags: -C target-feature=+avx512bw
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_sym)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
diff --git a/src/test/codegen-units/item-collection/implicit-panic-call.rs b/src/test/codegen-units/item-collection/implicit-panic-call.rs
new file mode 100644 (file)
index 0000000..abec7ad
--- /dev/null
@@ -0,0 +1,58 @@
+// compile-flags:-Zprint-mono-items=lazy
+
+// rust-lang/rust#90405
+// Ensure implicit panic calls are collected
+
+#![feature(lang_items)]
+#![feature(no_core)]
+#![crate_type = "lib"]
+#![no_core]
+#![no_std]
+
+#[lang = "panic_location"]
+struct Location<'a> {
+    _file: &'a str,
+    _line: u32,
+    _col: u32,
+}
+
+#[lang = "panic"]
+#[inline]
+#[track_caller]
+fn panic(_: &'static str) -> ! {
+    loop {}
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "freeze"]
+trait Freeze {}
+
+impl Copy for i32 {}
+
+#[lang = "div"]
+trait Div<Rhs = Self> {
+    type Output;
+    fn div(self, rhs: Rhs) -> Self::Output;
+}
+
+impl Div for i32 {
+    type Output = i32;
+    fn div(self, rhs: i32) -> i32 {
+        self / rhs
+    }
+}
+
+#[allow(unconditional_panic)]
+pub fn foo() {
+    // This implicitly generates a panic call.
+    let _ = 1 / 0;
+}
+
+//~ MONO_ITEM fn foo
+//~ MONO_ITEM fn <i32 as Div>::div
+//~ MONO_ITEM fn panic
index ce13a7ff938c8beb23ce18f7c230dd6ddfc4f8aa..10b20ba6beb0a614cdb53a13ceed46fc8fa97978 100644 (file)
@@ -7,7 +7,7 @@
 //[powerpc64le] needs-llvm-components: powerpc
 
 #![crate_type = "rlib"]
-#![feature(no_core, rustc_attrs, lang_items)]
+#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
 #![no_core]
 
 #[lang = "sized"]
index 906d094f72b4a1b45b838babfc42698c8a3e67de..39f665402b025cf12918fba727f95bc93ecf6410 100644 (file)
@@ -1,4 +1,4 @@
-// EMIT_MIR issue_78192.f.InstCombine.diff
+// compile-flags: -Zmir-opt-level=1 -Zinline-mir
 pub fn f<T>(a: &T) -> *const T {
     let b: &*const T = &(a as *const T);
     *b
@@ -7,3 +7,5 @@ pub fn f<T>(a: &T) -> *const T {
 fn main() {
     f(&2);
 }
+
+// EMIT_MIR issue_78192.f.InstCombine.diff
index c75713c3ee53d1798915a4abfd36c4144a0669ec..de463a330149b0416afbf5b98c21a4591082a5da 100644 (file)
@@ -3,4 +3,4 @@
 all:
        touch $(TMPDIR)/lib.rmeta
        $(AR) crus $(TMPDIR)/libfoo-ffffffff-1.0.rlib $(TMPDIR)/lib.rmeta
-       $(RUSTC) foo.rs 2>&1 | $(CGREP) "can't find crate for"
+       $(RUSTC) foo.rs 2>&1 | $(CGREP) "found invalid metadata"
index 013bf3baca45f1d18d321ba80ea4641bbc72ecbc..5472baae3f2b0bb0d1a9de1cef1b0bf7729524ba 100644 (file)
@@ -1,3 +1,5 @@
+# needs-llvm-components: x86 arm
+
 -include ../tools.mk
 
 all: default
diff --git a/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile b/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile
new file mode 100644 (file)
index 0000000..4934e87
--- /dev/null
@@ -0,0 +1,18 @@
+-include ../../run-make-fulldeps/tools.mk
+
+OUTPUT_DIR := "$(TMPDIR)/rustdoc"
+DYLIB_NAME := $(shell echo | $(RUSTC) --crate-name foobar_macro --crate-type dylib --print file-names -)
+
+all:
+       $(RUSTC) src/proc.rs --crate-name foobar_macro --edition=2021 --crate-type proc-macro --emit=dep-info,link
+
+       $(RUSTC) src/lib.rs --crate-name foobar --edition=2021 --crate-type lib --emit=dep-info,link
+
+       $(RUSTDOC) examples/ex.rs --crate-name ex --crate-type bin --output $(OUTPUT_DIR) \
+               --extern foobar=$(TMPDIR)/libfoobar.rlib --extern foobar_macro=$(TMPDIR)/$(DYLIB_NAME) \
+               -Z unstable-options --scrape-examples-output-path $(TMPDIR)/ex.calls --scrape-examples-target-crate foobar
+
+       $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --output $(OUTPUT_DIR) \
+               -Z unstable-options --with-examples $(TMPDIR)/ex.calls
+
+       $(HTMLDOCCK) $(OUTPUT_DIR) src/lib.rs
diff --git a/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/examples/ex.rs b/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/examples/ex.rs
new file mode 100644 (file)
index 0000000..4d8c8b3
--- /dev/null
@@ -0,0 +1,27 @@
+extern crate foobar;
+extern crate foobar_macro;
+
+use foobar::*;
+use foobar_macro::*;
+
+a_proc_macro!(); // no
+
+#[an_attr_macro]
+fn a() {
+  f(); // no
+}
+
+#[an_attr_macro(with_span)]
+fn b() {
+  f(); // yes
+}
+
+fn c() {
+  a_rules_macro!(f()); // yes
+}
+
+fn d() {
+  a_rules_macro!(()); // no
+}
+
+fn main(){}
diff --git a/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/lib.rs b/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/lib.rs
new file mode 100644 (file)
index 0000000..bac3970
--- /dev/null
@@ -0,0 +1,12 @@
+// Scraped example should only include line numbers for items b and c in ex.rs
+// @!has foobar/fn.f.html '//*[@class="line-numbers"]' '14'
+// @has foobar/fn.f.html '//*[@class="line-numbers"]' '15'
+// @has foobar/fn.f.html '//*[@class="line-numbers"]' '21'
+// @!has foobar/fn.f.html '//*[@class="line-numbers"]' '22'
+
+pub fn f() {}
+
+#[macro_export]
+macro_rules! a_rules_macro {
+  ($e:expr) => { ($e, foobar::f()); }
+}
diff --git a/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/proc.rs b/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/proc.rs
new file mode 100644 (file)
index 0000000..46e518f
--- /dev/null
@@ -0,0 +1,39 @@
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro]
+pub fn a_proc_macro(_item: TokenStream) -> TokenStream {
+    "fn ex() { foobar::f(); }".parse().unwrap()
+}
+
+// inserts foobar::f() to the end of the function
+#[proc_macro_attribute]
+pub fn an_attr_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
+    let new_call: TokenStream = "foobar::f();".parse().unwrap();
+
+    let mut tokens = item.into_iter();
+
+    let fn_tok = tokens.next().unwrap();
+    let ident_tok = tokens.next().unwrap();
+    let args_tok = tokens.next().unwrap();
+    let body = match tokens.next().unwrap() {
+        TokenTree::Group(g) => {
+            let new_g = Group::new(g.delimiter(), new_call);
+            let mut outer_g = Group::new(
+                g.delimiter(),
+                [TokenTree::Group(g.clone()), TokenTree::Group(new_g)].into_iter().collect(),
+            );
+
+            if attr.to_string() == "with_span" {
+                outer_g.set_span(g.span());
+            }
+
+            TokenTree::Group(outer_g)
+        }
+        _ => unreachable!(),
+    };
+
+    let tokens = vec![fn_tok, ident_tok, args_tok, body].into_iter().collect::<TokenStream>();
+
+    tokens
+}
diff --git a/src/test/run-make/invalid-so/Makefile b/src/test/run-make/invalid-so/Makefile
new file mode 100644 (file)
index 0000000..5b82ecd
--- /dev/null
@@ -0,0 +1,7 @@
+include ../../run-make-fulldeps/tools.mk
+
+DYLIB_NAME := $(shell echo | $(RUSTC) --crate-name foo --crate-type dylib --print file-names -)
+
+all:
+       echo >> $(TMPDIR)/$(DYLIB_NAME)
+       $(RUSTC) --crate-type lib --extern foo=$(TMPDIR)/$(DYLIB_NAME) bar.rs 2>&1 | $(CGREP) 'invalid metadata files for crate `foo`'
diff --git a/src/test/run-make/invalid-so/bar.rs b/src/test/run-make/invalid-so/bar.rs
new file mode 100644 (file)
index 0000000..49af74e
--- /dev/null
@@ -0,0 +1 @@
+extern crate foo;
diff --git a/src/test/run-make/rustdoc-scrape-examples-invalid-expr/Makefile b/src/test/run-make/rustdoc-scrape-examples-invalid-expr/Makefile
new file mode 100644 (file)
index 0000000..dce8b83
--- /dev/null
@@ -0,0 +1,5 @@
+deps := ex
+
+-include ../rustdoc-scrape-examples-multiple/scrape.mk
+
+all: scrape
diff --git a/src/test/run-make/rustdoc-scrape-examples-invalid-expr/examples/ex.rs b/src/test/run-make/rustdoc-scrape-examples-invalid-expr/examples/ex.rs
new file mode 100644 (file)
index 0000000..b342b5b
--- /dev/null
@@ -0,0 +1,2 @@
+pub struct Foo([usize; foobar::f()]);
+fn main() {}
diff --git a/src/test/run-make/rustdoc-scrape-examples-invalid-expr/src/lib.rs b/src/test/run-make/rustdoc-scrape-examples-invalid-expr/src/lib.rs
new file mode 100644 (file)
index 0000000..c30c99d
--- /dev/null
@@ -0,0 +1 @@
+pub const fn f() -> usize { 5 }
index bd59584bbbf4fafbb70c7920d901807bb6d6064e..bdfeda92d79a0684e6adf2a5e46a27f518b61575 100644 (file)
@@ -1,4 +1,6 @@
 // @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]//*[@class="prev"]' ''
 // @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' ''
+// @has src/ex/ex.rs.html
+// @has foobar/fn.ok.html '//a[@href="../src/ex/ex.rs.html#2"]' ''
 
 pub fn ok() {}
index d6d5982087658066359803dbda99c85143ec88fe..05c18007b0c718bfe72aadf237fc18ae89c197f2 100644 (file)
@@ -1,8 +1,10 @@
 fn main() {
-    foobar::ok();
+    foobar::ok(0);
 
     // this is a
 
+    //  ..
+
     // BIG
 
     // item
index a1133117f861e9cab46ce570c989c199b9a4aa7c..de21d9061f8dcc4c49cc76d2b1263f46d3f19acf 100644 (file)
@@ -1,4 +1,8 @@
 fn main() {
-    foobar::ok();
+    foobar::ok(1);
     // small item
 }
+
+fn f() {
+    foobar::ok(2);
+}
index f1b7686d36800f774dc718d0ff793729bdd60302..5afffffdf9976f84854352224888f49ea786889c 100644 (file)
@@ -1,4 +1,7 @@
 // @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' 'ex2'
 // @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' 'ex1'
+// @has foobar/fn.ok.html '//*[@class="highlight focus"]' '1'
+// @has foobar/fn.ok.html '//*[@class="highlight"]' '2'
+// @has foobar/fn.ok.html '//*[@class="highlight focus"]' '0'
 
-pub fn ok() {}
+pub fn ok(_x: i32) {}
index 35d772170f6f98c3b96f5cf69a6ab4ce96d19ad0..bdf17ec45705780952ccc74d6068e8e8161fafb0 100644 (file)
@@ -109,6 +109,9 @@ assert-css: ("h6#sub-heading-for-enum-impl-item-doc", {"border-bottom-width": "0
 assert-css: ("h6#sub-sub-heading-for-enum-impl-item-doc", {"font-size": "15.2px"})
 assert-css: ("h6#sub-sub-heading-for-enum-impl-item-doc", {"border-bottom-width": "0px"})
 
+assert-text: (".sidebar .others h3", "Modules")
+assert-css: (".sidebar .others h3", {"border-bottom-width": "1px"}, ALL)
+
 goto: file://|DOC_PATH|/test_docs/union.HeavilyDocumentedUnion.html
 
 assert-css: ("h1.fqn", {"font-size": "24px"})
diff --git a/src/test/rustdoc-gui/javascript-disabled.goml b/src/test/rustdoc-gui/javascript-disabled.goml
new file mode 100644 (file)
index 0000000..1693f7b
--- /dev/null
@@ -0,0 +1,6 @@
+// When JavaScript is disabled, we hide the search bar, because it
+// can't be used without JS.
+javascript: false
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert-css: (".sub", {"display": "none"})
index eacc9f6c15fe1eb8c42abcff9424c0934668fce2..f9c707f81e79c8022c510a1f183d74f2f92cd5f6 100644 (file)
@@ -4,17 +4,17 @@ assert-text: (".sidebar > .location", "Crate test_docs")
 assert-count: (".sidebar .location", 1)
 assert-text: (".sidebar-elems > #all-types", "See all test_docs's items")
 // We check that we have the crates list and that the "current" on is "test_docs".
-assert-text: (".sidebar-elems .crate > ul > li > a.current", "test_docs")
+assert-text: (".sidebar-elems .crate > ul > li > a.current", "test_docs")
 // And we're also supposed to have the list of items in the current module.
-assert-text: (".sidebar-elems .items > ul > li:nth-child(1)", "Modules")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(2)", "Macros")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(3)", "Structs")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(4)", "Enums")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(5)", "Traits")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(6)", "Functions")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(7)", "Type Definitions")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(8)", "Unions")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(9)", "Keywords")
+assert-text: (".sidebar-elems .items > ul > li:nth-child(1)", "Modules")
+assert-text: (".sidebar-elems .items > ul > li:nth-child(2)", "Macros")
+assert-text: (".sidebar-elems .items > ul > li:nth-child(3)", "Structs")
+assert-text: (".sidebar-elems .items > ul > li:nth-child(4)", "Enums")
+assert-text: (".sidebar-elems .items > ul > li:nth-child(5)", "Traits")
+assert-text: (".sidebar-elems .items > ul > li:nth-child(6)", "Functions")
+assert-text: (".sidebar-elems .items > ul > li:nth-child(7)", "Type Definitions")
+assert-text: (".sidebar-elems .items > ul > li:nth-child(8)", "Unions")
+assert-text: (".sidebar-elems .items > ul > li:nth-child(9)", "Keywords")
 assert-text: ("#structs + .item-table .item-left > a", "Foo")
 click: "#structs + .item-table .item-left > a"
 
@@ -24,13 +24,13 @@ assert-count: (".sidebar .location", 2)
 assert-false: ".sidebar-elems > .crate"
 // We now go back to the crate page to click on the "lib2" crate link.
 goto: file://|DOC_PATH|/test_docs/index.html
-click: ".sidebar-elems .crate > ul > li:first-child > a"
+click: ".sidebar-elems .crate > ul > li:first-child > a"
 
 // PAGE: lib2/index.html
 goto: file://|DOC_PATH|/lib2/index.html
 assert-text: (".sidebar > .location", "Crate lib2")
 // We check that we have the crates list and that the "current" on is now "lib2".
-assert-text: (".sidebar-elems .crate > ul > li > a.current", "lib2")
+assert-text: (".sidebar-elems .crate > ul > li > a.current", "lib2")
 // We now go to the "foobar" function page.
 assert-text: (".sidebar-elems > .items > ul > li:nth-child(1)", "Modules")
 assert-text: (".sidebar-elems > .items > ul > li:nth-child(2)", "Structs")
@@ -57,6 +57,6 @@ assert-false: ".sidebar-elems > .crate"
 goto: ./sub_module/sub_sub_module/index.html
 assert-text: (".sidebar > .location", "Module sub_sub_module")
 // We check that we don't have the crate list.
-assert-false: ".sidebar-elems .crate"
-assert-text: (".sidebar-elems .items > ul > li:nth-child(1)", "Functions")
+assert-false: ".sidebar-elems .crate"
+assert-text: (".sidebar-elems .items > ul > li:nth-child(1)", "Functions")
 assert-text: ("#functions + .item-table .item-left > a", "foo")
diff --git a/src/test/rustdoc/doc-auto-cfg.rs b/src/test/rustdoc/doc-auto-cfg.rs
new file mode 100644 (file)
index 0000000..fcdd835
--- /dev/null
@@ -0,0 +1,8 @@
+#![feature(doc_auto_cfg)]
+
+#![crate_name = "foo"]
+
+// @has foo/fn.foo.html
+// @has - '//*[@class="item-info"]/*[@class="stab portability"]' 'non-test'
+#[cfg(not(test))]
+pub fn foo() {}
index b9d0d32313723ddb1128b563e33237881ef7ab11..424fa6d6a911fac841884f3d302fcb7a0805ed6c 100644 (file)
@@ -1,5 +1,5 @@
 #![crate_name = "oud"]
-#![feature(doc_cfg, doc_cfg_hide)]
+#![feature(doc_auto_cfg, doc_cfg, doc_cfg_hide)]
 
 #![doc(cfg_hide(feature = "solecism"))]
 
index 36c2025785d0f87a8e76915fe7fcd3ce897b4fe8..5d17a4ede6adcb16da2a182c0abe50e36b64132f 100644 (file)
@@ -1,5 +1,5 @@
 #![crate_name = "funambulism"]
-#![feature(doc_cfg)]
+#![feature(doc_auto_cfg, doc_cfg)]
 
 // @has 'funambulism/struct.Disorbed.html'
 // @count   - '//*[@class="stab portability"]' 1
diff --git a/src/test/rustdoc/feature-gate-doc_auto_cfg.rs b/src/test/rustdoc/feature-gate-doc_auto_cfg.rs
new file mode 100644 (file)
index 0000000..da76381
--- /dev/null
@@ -0,0 +1,8 @@
+#![feature(doc_cfg)]
+
+#![crate_name = "foo"]
+
+// @has foo/fn.foo.html
+// @count - '//*[@class="item-info"]/*[@class="stab portability"]' 0
+#[cfg(not(test))]
+pub fn foo() {}
diff --git a/src/test/ui/argument-passing.rs b/src/test/ui/argument-passing.rs
deleted file mode 100644 (file)
index 74759a4..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// run-pass
-
-struct X {
-    x: isize
-}
-
-fn f1(a: &mut X, b: &mut isize, c: isize) -> isize {
-    let r = a.x + *b + c;
-    a.x = 0;
-    *b = 10;
-    return r;
-}
-
-fn f2<F>(a: isize, f: F) -> isize where F: FnOnce(isize) { f(1); return a; }
-
-pub fn main() {
-    let mut a = X {x: 1};
-    let mut b = 2;
-    let c = 3;
-    assert_eq!(f1(&mut a, &mut b, c), 6);
-    assert_eq!(a.x, 0);
-    assert_eq!(b, 10);
-    assert_eq!(f2(a.x, |_| a.x = 50), 0);
-    assert_eq!(a.x, 50);
-}
diff --git a/src/test/ui/array-slice-vec/mut-vstore-expr.rs b/src/test/ui/array-slice-vec/mut-vstore-expr.rs
new file mode 100644 (file)
index 0000000..75b309a
--- /dev/null
@@ -0,0 +1,6 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+pub fn main() {
+    let _x: &mut [isize] = &mut [ 1, 2, 3 ];
+}
index 22d0499a1cc1d0c3cb6da58e8f82dd4d779cd385..4d7a7fd31feca7b5dacb21236ce712ffdbc20c6b 100644 (file)
@@ -1,7 +1,7 @@
 // only-aarch64
 // compile-flags: -C target-feature=+fp
 
-#![feature(asm)]
+#![feature(asm, asm_const, asm_sym)]
 
 fn main() {
     let mut foo = 0;
index 05165b2d46c0dd3eb85fccd5dd7711d57592b269..49fe48600c25c4948df632d25a2a02d82cb07338 100644 (file)
@@ -3,7 +3,7 @@
 // revisions: mirunsafeck thirunsafeck
 // [thirunsafeck]compile-flags: -Z thir-unsafeck
 
-#![feature(asm, global_asm)]
+#![feature(asm, global_asm, asm_const)]
 
 fn const_generic<const X: usize>() -> usize {
     unsafe {
index faa5e37b781ecffe1f8352304c112f472c1ce7b6..e19c5cd13d35aa545ab0565cff43989a681806d9 100644 (file)
@@ -1,6 +1,6 @@
 // only-aarch64
 
-#![feature(asm, global_asm)]
+#![feature(asm, global_asm, asm_const)]
 
 fn main() {
     let mut foo = 0;
index 526555334cb882cd1cf2c5d97ef225bab56974fc..b0dd143a0a1b6de603dae63e6dfc7e7c8422a6dc 100644 (file)
@@ -2,7 +2,7 @@
 // only-linux
 // run-pass
 
-#![feature(asm, thread_local)]
+#![feature(asm, thread_local, asm_sym)]
 
 extern "C" fn f1() -> i32 {
     111
@@ -75,5 +75,7 @@ fn main() {
     std::thread::spawn(|| {
         assert_eq!(static_addr!(S1), &S1 as *const u32);
         assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
-    }).join().unwrap();
+    })
+    .join()
+    .unwrap();
 }
index cf25dcb930c7920e0c6cb2d185a75683094b2756..e1e8a91dda6033a8087682b4d5b2c5a65d730210 100644 (file)
@@ -1,6 +1,6 @@
 // only-aarch64
 
-#![feature(asm, repr_simd, never_type)]
+#![feature(asm, repr_simd, never_type, asm_sym)]
 
 #[repr(simd)]
 #[derive(Clone, Copy)]
index d0d5954ca4aef78eb67355cb1c9497743e024419..fc1831a520a0cbc0b702c7756cf5321d29231d75 100644 (file)
@@ -1,13 +1,13 @@
 // only-aarch64
 // compile-flags: -C target-feature=+neon
 
-#![feature(asm, global_asm, repr_simd, stdsimd)]
+#![feature(asm, global_asm, repr_simd, stdsimd, asm_const)]
 
 use std::arch::aarch64::float64x2_t;
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct Simd256bit(f64, f64,f64, f64);
+struct Simd256bit(f64, f64, f64, f64);
 
 fn main() {
     let f64x2: float64x2_t = unsafe { std::mem::transmute(0i128) };
@@ -42,7 +42,6 @@ fn main() {
         asm!("{:b}", in(vreg) 0u64);
         asm!("{:d}", in(vreg_low16) f64x2);
 
-
         // Template modifier suggestions for sub-registers
 
         asm!("{}", in(reg) 0u8);
index c31a62ae7912a59e67303750374ae7f02520191f..ed9d3147b9ffaa52358a1fb85bd240bcb3a6e10d 100644 (file)
@@ -1,5 +1,5 @@
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:48:15
+  --> $DIR/type-check-3.rs:47:15
    |
 LL |         asm!("{}", in(reg) 0u8);
    |               ^^           --- for this argument
@@ -9,7 +9,7 @@ LL |         asm!("{}", in(reg) 0u8);
    = help: or use the `x` modifier to keep the default formatting of `x0`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:50:15
+  --> $DIR/type-check-3.rs:49:15
    |
 LL |         asm!("{}", in(reg) 0u16);
    |               ^^           ---- for this argument
@@ -18,7 +18,7 @@ LL |         asm!("{}", in(reg) 0u16);
    = help: or use the `x` modifier to keep the default formatting of `x0`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:52:15
+  --> $DIR/type-check-3.rs:51:15
    |
 LL |         asm!("{}", in(reg) 0i32);
    |               ^^           ---- for this argument
@@ -27,7 +27,7 @@ LL |         asm!("{}", in(reg) 0i32);
    = help: or use the `x` modifier to keep the default formatting of `x0`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:54:15
+  --> $DIR/type-check-3.rs:53:15
    |
 LL |         asm!("{}", in(reg) 0f32);
    |               ^^           ---- for this argument
@@ -36,7 +36,7 @@ LL |         asm!("{}", in(reg) 0f32);
    = help: or use the `x` modifier to keep the default formatting of `x0`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:57:15
+  --> $DIR/type-check-3.rs:56:15
    |
 LL |         asm!("{}", in(vreg) 0i16);
    |               ^^            ---- for this argument
@@ -45,7 +45,7 @@ LL |         asm!("{}", in(vreg) 0i16);
    = help: or use the `v` modifier to keep the default formatting of `v0`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:59:15
+  --> $DIR/type-check-3.rs:58:15
    |
 LL |         asm!("{}", in(vreg) 0f32);
    |               ^^            ---- for this argument
@@ -54,7 +54,7 @@ LL |         asm!("{}", in(vreg) 0f32);
    = help: or use the `v` modifier to keep the default formatting of `v0`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:61:15
+  --> $DIR/type-check-3.rs:60:15
    |
 LL |         asm!("{}", in(vreg) 0f64);
    |               ^^            ---- for this argument
@@ -63,7 +63,7 @@ LL |         asm!("{}", in(vreg) 0f64);
    = help: or use the `v` modifier to keep the default formatting of `v0`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:63:15
+  --> $DIR/type-check-3.rs:62:15
    |
 LL |         asm!("{}", in(vreg_low16) 0f64);
    |               ^^                  ---- for this argument
@@ -72,7 +72,7 @@ LL |         asm!("{}", in(vreg_low16) 0f64);
    = help: or use the `v` modifier to keep the default formatting of `v0`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:66:15
+  --> $DIR/type-check-3.rs:65:15
    |
 LL |         asm!("{0} {0}", in(reg) 0i16);
    |               ^^^ ^^^           ---- for this argument
@@ -81,7 +81,7 @@ LL |         asm!("{0} {0}", in(reg) 0i16);
    = help: or use the `x` modifier to keep the default formatting of `x0`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:68:15
+  --> $DIR/type-check-3.rs:67:15
    |
 LL |         asm!("{0} {0:x}", in(reg) 0i16);
    |               ^^^                 ---- for this argument
@@ -90,7 +90,7 @@ LL |         asm!("{0} {0:x}", in(reg) 0i16);
    = help: or use the `x` modifier to keep the default formatting of `x0`
 
 error: type `i128` cannot be used with this register class
-  --> $DIR/type-check-3.rs:73:28
+  --> $DIR/type-check-3.rs:72:28
    |
 LL |         asm!("{}", in(reg) 0i128);
    |                            ^^^^^
@@ -98,7 +98,7 @@ LL |         asm!("{}", in(reg) 0i128);
    = note: register class `reg` supports these types: i8, i16, i32, i64, f32, f64
 
 error: type `float64x2_t` cannot be used with this register class
-  --> $DIR/type-check-3.rs:75:28
+  --> $DIR/type-check-3.rs:74:28
    |
 LL |         asm!("{}", in(reg) f64x2);
    |                            ^^^^^
@@ -106,7 +106,7 @@ LL |         asm!("{}", in(reg) f64x2);
    = note: register class `reg` supports these types: i8, i16, i32, i64, f32, f64
 
 error: type `Simd256bit` cannot be used with this register class
-  --> $DIR/type-check-3.rs:77:29
+  --> $DIR/type-check-3.rs:76:29
    |
 LL |         asm!("{}", in(vreg) f64x4);
    |                             ^^^^^
@@ -114,7 +114,7 @@ LL |         asm!("{}", in(vreg) f64x4);
    = note: register class `vreg` supports these types: i8, i16, i32, i64, f32, f64, i8x8, i16x4, i32x2, i64x1, f32x2, f64x1, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
 
 error: incompatible types for asm inout argument
-  --> $DIR/type-check-3.rs:88:33
+  --> $DIR/type-check-3.rs:87:33
    |
 LL |         asm!("{:x}", inout(reg) 0u32 => val_f32);
    |                                 ^^^^    ^^^^^^^ type `f32`
@@ -124,7 +124,7 @@ LL |         asm!("{:x}", inout(reg) 0u32 => val_f32);
    = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
 
 error: incompatible types for asm inout argument
-  --> $DIR/type-check-3.rs:90:33
+  --> $DIR/type-check-3.rs:89:33
    |
 LL |         asm!("{:x}", inout(reg) 0u32 => val_ptr);
    |                                 ^^^^    ^^^^^^^ type `*mut u8`
@@ -134,7 +134,7 @@ LL |         asm!("{:x}", inout(reg) 0u32 => val_ptr);
    = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
 
 error: incompatible types for asm inout argument
-  --> $DIR/type-check-3.rs:92:33
+  --> $DIR/type-check-3.rs:91:33
    |
 LL |         asm!("{:x}", inout(reg) main => val_u32);
    |                                 ^^^^    ^^^^^^^ type `u32`
@@ -144,7 +144,7 @@ LL |         asm!("{:x}", inout(reg) main => val_u32);
    = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
 
 error[E0013]: constants cannot refer to statics
-  --> $DIR/type-check-3.rs:108:25
+  --> $DIR/type-check-3.rs:107:25
    |
 LL | global_asm!("{}", const S);
    |                         ^
@@ -152,7 +152,7 @@ LL | global_asm!("{}", const S);
    = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error[E0013]: constants cannot refer to statics
-  --> $DIR/type-check-3.rs:111:35
+  --> $DIR/type-check-3.rs:110:35
    |
 LL | global_asm!("{}", const const_foo(S));
    |                                   ^
@@ -160,7 +160,7 @@ LL | global_asm!("{}", const const_foo(S));
    = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error[E0013]: constants cannot refer to statics
-  --> $DIR/type-check-3.rs:114:35
+  --> $DIR/type-check-3.rs:113:35
    |
 LL | global_asm!("{}", const const_bar(S));
    |                                   ^
index fca77e7aa71f37d9b3841cbaf4e9a1fe31793dd7..b062c45e6ea34947b37ab09c98d49f23f6a3eec2 100644 (file)
@@ -10,7 +10,7 @@
 // [aarch64_thirunsafeck] needs-llvm-components: aarch64
 // [aarch64_mirunsafeck] needs-llvm-components: aarch64
 
-#![feature(no_core, lang_items, rustc_attrs)]
+#![feature(no_core, lang_items, rustc_attrs, asm_const)]
 #![no_core]
 
 #[rustc_builtin_macro]
index bdcf3f305ebb18cc6841ff79ad59cd70000c747c..a4b22e21028d90c52af9152915a4ccc56581469d 100644 (file)
@@ -2,6 +2,7 @@
 // as both unused and possibly-uninitialized.
 
 // check-pass
+// needs-asm-support
 
 #![feature(asm)]
 #![warn(unused)]
index 9cc127b44d008765b7a841efca42ab93d68f91f0..3fb1526183bccdbb3527ddc970947f44945398c9 100644 (file)
@@ -1,11 +1,11 @@
 warning: unused variable: `x`
-  --> $DIR/issue-89305.rs:11:13
+  --> $DIR/issue-89305.rs:12:13
    |
 LL |         let x: () = asm!("nop");
    |             ^ help: if this is intentional, prefix it with an underscore: `_x`
    |
 note: the lint level is defined here
-  --> $DIR/issue-89305.rs:7:9
+  --> $DIR/issue-89305.rs:8:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
index 803311d4235058a0a6419f2c44a5a4f94b1692da..7154ce26efcf5e3833dec4a5ec96e69fdaa597e8 100644 (file)
@@ -7,11 +7,15 @@
 #![feature(llvm_asm)]
 #![feature(naked_functions)]
 #![feature(or_patterns)]
+#![feature(asm_const, asm_sym)]
 #![crate_type = "lib"]
 #![allow(deprecated)] // llvm_asm!
 
 #[repr(C)]
-pub struct P { x: u8, y: u16 }
+pub struct P {
+    x: u8,
+    y: u16,
+}
 
 #[naked]
 pub unsafe extern "C" fn patterns(
@@ -143,21 +147,27 @@ pub unsafe fn default_abi() {
 }
 
 #[naked]
-pub unsafe extern "Rust" fn rust_abi() {
+pub unsafe fn rust_abi() {
     //~^ WARN Rust ABI is unsupported in naked functions
     asm!("", options(noreturn));
 }
 
 #[naked]
 pub extern "C" fn valid_a<T>() -> T {
-    unsafe { asm!("", options(noreturn)); }
+    unsafe {
+        asm!("", options(noreturn));
+    }
 }
 
 #[naked]
 pub extern "C" fn valid_b() {
-    unsafe { { {
-        asm!("", options(noreturn)); ; ; ;
-    } ; }  ; }
+    unsafe {
+        {
+            {
+                asm!("", options(noreturn));
+            };
+        };
+    }
 }
 
 #[naked]
index 465db634aa2f0b84bf07c4a888150231d9521be6..e4ddb97ca27467393caa956ad8af2ab87031ea7b 100644 (file)
@@ -1,35 +1,35 @@
 error: asm with the `pure` option must have at least one output
-  --> $DIR/naked-functions.rs:131:14
+  --> $DIR/naked-functions.rs:135:14
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:18:5
+  --> $DIR/naked-functions.rs:22:5
    |
 LL |     mut a: u32,
    |     ^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:20:5
+  --> $DIR/naked-functions.rs:24:5
    |
 LL |     &b: &i32,
    |     ^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:22:6
+  --> $DIR/naked-functions.rs:26:6
    |
 LL |     (None | Some(_)): Option<std::ptr::NonNull<u8>>,
    |      ^^^^^^^^^^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:24:5
+  --> $DIR/naked-functions.rs:28:5
    |
 LL |     P { x, y }: P,
    |     ^^^^^^^^^^
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:34:5
+  --> $DIR/naked-functions.rs:38:5
    |
 LL |     a + 1
    |     ^
@@ -37,7 +37,7 @@ LL |     a + 1
    = help: follow the calling convention in asm block to use parameters
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:31:1
+  --> $DIR/naked-functions.rs:35:1
    |
 LL | / pub unsafe extern "C" fn inc(a: u32) -> u32 {
 LL | |
@@ -53,7 +53,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:40:31
+  --> $DIR/naked-functions.rs:44:31
    |
 LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    |                               ^
@@ -61,7 +61,7 @@ LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    = help: follow the calling convention in asm block to use parameters
 
 warning: only `const` and `sym` operands are supported in naked functions
-  --> $DIR/naked-functions.rs:40:23
+  --> $DIR/naked-functions.rs:44:23
    |
 LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    |                       ^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:47:1
+  --> $DIR/naked-functions.rs:51:1
    |
 LL | / pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
 LL | |
@@ -84,7 +84,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: only `const` and `sym` operands are supported in naked functions
-  --> $DIR/naked-functions.rs:67:10
+  --> $DIR/naked-functions.rs:71:10
    |
 LL |          in(reg) a,
    |          ^^^^^^^^^
@@ -102,7 +102,7 @@ LL |          out(reg) e,
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:64:5
+  --> $DIR/naked-functions.rs:68:5
    |
 LL | /     asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
 LL | |
@@ -117,7 +117,7 @@ LL | |     );
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:54:1
+  --> $DIR/naked-functions.rs:58:1
    |
 LL | / pub unsafe extern "C" fn unsupported_operands() {
 LL | |
@@ -141,7 +141,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:80:1
+  --> $DIR/naked-functions.rs:84:1
    |
 LL | / pub extern "C" fn missing_assembly() {
 LL | |
@@ -153,7 +153,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:89:5
+  --> $DIR/naked-functions.rs:93:5
    |
 LL |     asm!("");
    |     ^^^^^^^^
@@ -162,7 +162,7 @@ LL |     asm!("");
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:92:5
+  --> $DIR/naked-functions.rs:96:5
    |
 LL |     asm!("");
    |     ^^^^^^^^
@@ -171,7 +171,7 @@ LL |     asm!("");
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:95:5
+  --> $DIR/naked-functions.rs:99:5
    |
 LL |     asm!("");
    |     ^^^^^^^^
@@ -180,7 +180,7 @@ LL |     asm!("");
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:86:1
+  --> $DIR/naked-functions.rs:90:1
    |
 LL | / pub extern "C" fn too_many_asm_blocks() {
 LL | |
@@ -202,7 +202,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:106:11
+  --> $DIR/naked-functions.rs:110:11
    |
 LL |         *&y
    |           ^
@@ -210,7 +210,7 @@ LL |         *&y
    = help: follow the calling convention in asm block to use parameters
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:103:5
+  --> $DIR/naked-functions.rs:107:5
    |
 LL | /     pub extern "C" fn inner(y: usize) -> usize {
 LL | |
@@ -225,7 +225,7 @@ LL | |     }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: the LLVM-style inline assembly is unsupported in naked functions
-  --> $DIR/naked-functions.rs:116:5
+  --> $DIR/naked-functions.rs:120:5
    |
 LL |     llvm_asm!("");
    |     ^^^^^^^^^^^^^
@@ -236,7 +236,7 @@ LL |     llvm_asm!("");
    = note: this warning originates in the macro `llvm_asm` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:113:1
+  --> $DIR/naked-functions.rs:117:1
    |
 LL | / unsafe extern "C" fn llvm() -> ! {
 LL | |
@@ -252,7 +252,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm options unsupported in naked functions: `nomem`, `preserves_flags`
-  --> $DIR/naked-functions.rs:124:5
+  --> $DIR/naked-functions.rs:128:5
    |
 LL |     asm!("", options(nomem, preserves_flags, noreturn));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -261,7 +261,7 @@ LL |     asm!("", options(nomem, preserves_flags, noreturn));
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
-  --> $DIR/naked-functions.rs:131:5
+  --> $DIR/naked-functions.rs:135:5
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -270,7 +270,7 @@ LL |     asm!("", options(readonly, nostack), options(pure));
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:131:5
+  --> $DIR/naked-functions.rs:135:5
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL |     asm!("", options(readonly, nostack), options(pure));
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:140:15
+  --> $DIR/naked-functions.rs:144:15
    |
 LL | pub unsafe fn default_abi() {
    |               ^^^^^^^^^^^
@@ -287,13 +287,13 @@ LL | pub unsafe fn default_abi() {
    = note: `#[warn(undefined_naked_function_abi)]` on by default
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:146:29
+  --> $DIR/naked-functions.rs:150:15
    |
-LL | pub unsafe extern "Rust" fn rust_abi() {
-   |                             ^^^^^^^^
+LL | pub unsafe fn rust_abi() {
+   |               ^^^^^^^^
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:180:1
+  --> $DIR/naked-functions.rs:190:1
    |
 LL | #[inline]
    | ^^^^^^^^^
@@ -302,7 +302,7 @@ LL | #[inline]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:188:1
+  --> $DIR/naked-functions.rs:198:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
@@ -311,7 +311,7 @@ LL | #[inline(always)]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:196:1
+  --> $DIR/naked-functions.rs:206:1
    |
 LL | #[inline(never)]
    | ^^^^^^^^^^^^^^^^
@@ -320,7 +320,7 @@ LL | #[inline(never)]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:204:1
+  --> $DIR/naked-functions.rs:214:1
    |
 LL | #[inline]
    | ^^^^^^^^^
@@ -329,7 +329,7 @@ LL | #[inline]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:207:1
+  --> $DIR/naked-functions.rs:217:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
@@ -338,7 +338,7 @@ LL | #[inline(always)]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:210:1
+  --> $DIR/naked-functions.rs:220:1
    |
 LL | #[inline(never)]
    | ^^^^^^^^^^^^^^^^
index 82c47945a7b302c4db11ee389e3c54877b98a46c..c87188e46a2bbedd92dcea45d37a764f86f14ba6 100644 (file)
@@ -11,7 +11,7 @@
 // which causes less readable LLVM errors and in the worst cases causes ICEs
 // or segfaults based on system dependent behavior and codegen flags.
 
-#![feature(asm, global_asm, naked_functions)]
+#![feature(asm, global_asm, naked_functions, asm_const)]
 
 #[no_mangle]
 pub static FOO: usize = 42;
index bbbe798d1557b0e095559ae2cff6fcfd19ebede2..1e463107b18bc4471f86e29aabe0ffbc360198f2 100644 (file)
@@ -3,7 +3,7 @@
 // ignore-spirv
 // ignore-wasm32
 
-#![feature(asm, global_asm)]
+#![feature(asm, global_asm, asm_const)]
 
 fn main() {
     unsafe {
index 91d0f8c33f9793c58a0d8b37e6e20f7c3a321036..ba4e95db46a2da80e97978aebe43ccf115f132a1 100644 (file)
@@ -1,7 +1,7 @@
 // only-x86_64
 // compile-flags: -C target-feature=+avx2
 
-#![feature(asm)]
+#![feature(asm, asm_const, asm_sym)]
 
 fn main() {
     let mut foo = 0;
index dbf17755720829516155af2e69b864d2952e92ec..c1e4cdbb928f4ce392e6328fcd1e6bda6bbb3d0c 100644 (file)
@@ -3,7 +3,7 @@
 // revisions: mirunsafeck thirunsafeck
 // [thirunsafeck]compile-flags: -Z thir-unsafeck
 
-#![feature(asm, global_asm)]
+#![feature(asm, global_asm, asm_const)]
 
 fn const_generic<const X: usize>() -> usize {
     unsafe {
index fa14c52cf0ad7f9fcd43549989d2bbf52d14b4e1..e7f3804c5886c24a0896b0e61fbd4381870387fa 100644 (file)
@@ -1,6 +1,6 @@
 // only-x86_64
 
-#![feature(asm, global_asm)]
+#![feature(asm, global_asm, asm_const)]
 
 fn main() {
     let mut foo = 0;
index 188d03e298e0182b734bb4dce9d5091aaef89589..958dbbdd37646acef7ce8906760ef74f7641b7f8 100644 (file)
@@ -3,7 +3,7 @@
 // only-linux
 // run-pass
 
-#![feature(asm, thread_local)]
+#![feature(asm, thread_local, asm_sym)]
 
 extern "C" fn f1() -> i32 {
     111
@@ -76,5 +76,7 @@ fn main() {
     std::thread::spawn(|| {
         assert_eq!(static_addr!(S1), &S1 as *const u32);
         assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
-    }).join().unwrap();
+    })
+    .join()
+    .unwrap();
 }
index 2311f86d340f48e4db0cc2917b407d44f8f5c216..94aadcf09f423466969d022b754e209d613215ab 100644 (file)
@@ -1,6 +1,6 @@
 // only-x86_64
 
-#![feature(asm, repr_simd, never_type)]
+#![feature(asm, repr_simd, never_type, asm_sym)]
 
 #[repr(simd)]
 struct SimdNonCopy(f32, f32, f32, f32);
index c2c1885ff166f45136a3eb891cbe2d7171387fea..83674cf8204d677f9544166fd938ddbdbc22a21e 100644 (file)
@@ -1,7 +1,7 @@
 // only-x86_64
 // compile-flags: -C target-feature=+avx512f
 
-#![feature(asm, global_asm)]
+#![feature(asm, global_asm, asm_const)]
 
 use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps};
 
diff --git a/src/test/ui/associated-types/issue-22066.rs b/src/test/ui/associated-types/issue-22066.rs
new file mode 100644 (file)
index 0000000..8e8ba5d
--- /dev/null
@@ -0,0 +1,12 @@
+// check-pass
+pub trait LineFormatter<'a> {
+    type Iter: Iterator<Item=&'a str> + 'a;
+    fn iter(&'a self, line: &'a str) -> Self::Iter;
+
+    fn dimensions(&'a self, line: &'a str) {
+        let iter: Self::Iter = self.iter(line);
+        <_ as IntoIterator>::into_iter(iter);
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-22828.rs b/src/test/ui/associated-types/issue-22828.rs
new file mode 100644 (file)
index 0000000..adf4dd6
--- /dev/null
@@ -0,0 +1,23 @@
+// run-pass
+#![allow(dead_code)]
+// Test transitive analysis for associated types. Collected types
+// should be normalized and new obligations generated.
+
+// pretty-expanded FIXME #23616
+
+trait Foo {
+    type A;
+    fn foo(&self) {}
+}
+
+impl Foo for usize {
+    type A = usize;
+}
+
+struct Bar<T: Foo> { inner: T::A }
+
+fn is_send<T: Send>() {}
+
+fn main() {
+    is_send::<Bar<usize>>();
+}
diff --git a/src/test/ui/associated-types/issue-28871.rs b/src/test/ui/associated-types/issue-28871.rs
new file mode 100644 (file)
index 0000000..210c783
--- /dev/null
@@ -0,0 +1,24 @@
+// check-pass
+// Regression test for #28871. The problem is that rustc encountered
+// two ways to project, one from a where clause and one from the where
+// clauses on the trait definition. (In fact, in this case, the where
+// clauses originated from the trait definition as well.) The true
+// cause of the error is that the trait definition where clauses are
+// not being normalized, and hence the two sources are considered in
+// conflict, and not a duplicate. Hacky solution is to prefer where
+// clauses over the data found in the trait definition.
+
+trait T {
+    type T;
+}
+
+struct S;
+impl T for S {
+    type T = S;
+}
+
+trait T2 {
+    type T: Iterator<Item=<S as T>::T>;
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/issue-47139-1.rs b/src/test/ui/associated-types/issue-47139-1.rs
new file mode 100644 (file)
index 0000000..c55fc34
--- /dev/null
@@ -0,0 +1,78 @@
+// run-pass
+// Regression test for issue #47139:
+//
+// Coherence was encountering an (unnecessary) overflow trying to
+// decide if the two impls of dummy overlap.
+//
+// The overflow went something like:
+//
+// - `&'a ?T: Insertable` ?
+// - let ?T = Option<?U> ?
+// - `Option<?U>: Insertable` ?
+// - `Option<&'a ?U>: Insertable` ?
+// - `&'a ?U: Insertable` ?
+//
+// While somewhere in the middle, a projection would occur, which
+// broke cycle detection.
+//
+// It turned out that this cycle was being kicked off due to some
+// extended diagnostic attempts in coherence, so removing those
+// sidestepped the issue for now.
+
+#![allow(dead_code)]
+
+pub trait Insertable {
+    type Values;
+
+    fn values(self) -> Self::Values;
+}
+
+impl<T> Insertable for Option<T>
+    where
+    T: Insertable,
+    T::Values: Default,
+{
+    type Values = T::Values;
+
+    fn values(self) -> Self::Values {
+        self.map(Insertable::values).unwrap_or_default()
+    }
+}
+
+impl<'a, T> Insertable for &'a Option<T>
+    where
+    Option<&'a T>: Insertable,
+{
+    type Values = <Option<&'a T> as Insertable>::Values;
+
+    fn values(self) -> Self::Values {
+        self.as_ref().values()
+    }
+}
+
+impl<'a, T> Insertable for &'a [T]
+{
+    type Values = Self;
+
+    fn values(self) -> Self::Values {
+        self
+    }
+}
+
+trait Unimplemented { }
+
+trait Dummy { }
+
+struct Foo<T> { t: T }
+
+impl<'a, U> Dummy for Foo<&'a U>
+    where &'a U: Insertable
+{
+}
+
+impl<T> Dummy for T
+    where T: Unimplemented
+{ }
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/issue-54467.rs b/src/test/ui/associated-types/issue-54467.rs
new file mode 100644 (file)
index 0000000..734bf27
--- /dev/null
@@ -0,0 +1,46 @@
+// run-pass
+
+pub trait Stream {
+    type Item;
+    type Error;
+}
+
+pub trait ParseError<I> {
+    type Output;
+}
+
+impl ParseError<char> for u32 {
+    type Output = ();
+}
+
+impl Stream for () {
+    type Item = char;
+    type Error = u32;
+}
+
+pub struct Lex<'a, I>
+    where I: Stream,
+          I::Error: ParseError<char>,
+          <<I as Stream>::Error as ParseError<char>>::Output: 'a
+{
+    x: &'a <I::Error as ParseError<char>>::Output
+}
+
+pub struct Reserved<'a, I> where
+    I: Stream<Item=char> + 'a,
+    I::Error: ParseError<I::Item>,
+    <<I as Stream>::Error as ParseError<char>>::Output: 'a
+
+{
+    x: Lex<'a, I>
+}
+
+fn main() {
+    let r: Reserved<()> = Reserved {
+        x: Lex {
+            x: &()
+        }
+    };
+
+    let _v = r.x.x;
+}
index 656ade67c71a7a3eb9d165cce773fcd154a98811..b652d239153302fc7fddd99b23cdc4d2be9b559b 100644 (file)
@@ -1,4 +1,6 @@
 // edition:2018
+#![feature(must_not_suspend)]
+#![allow(must_not_suspend)]
 
 // This tests the basic example case for the async-await-specific error.
 
index 7125c62dbaf9ad2da33782abe04979925f8fe542..a373ba6aa71361ea74b4bb90880874cd70cdfe4e 100644 (file)
@@ -1,12 +1,12 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-64130-non-send-future-diags.rs:21:13
+  --> $DIR/issue-64130-non-send-future-diags.rs:23:13
    |
 LL |     is_send(foo());
    |             ^^^^^ future returned by `foo` is not `Send`
    |
    = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, u32>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-64130-non-send-future-diags.rs:15:5
+  --> $DIR/issue-64130-non-send-future-diags.rs:17:5
    |
 LL |     let g = x.lock().unwrap();
    |         - has type `MutexGuard<'_, u32>` which is not `Send`
@@ -15,7 +15,7 @@ LL |     baz().await;
 LL | }
    | - `g` is later dropped here
 note: required by a bound in `is_send`
-  --> $DIR/issue-64130-non-send-future-diags.rs:7:15
+  --> $DIR/issue-64130-non-send-future-diags.rs:9:15
    |
 LL | fn is_send<T: Send>(t: T) { }
    |               ^^^^ required by this bound in `is_send`
index ebb392a45308e85bb34c7c84ab5adc4ba8345e87..7695e0325ff31feb45ee5dc1dc990d44d08ec2af 100644 (file)
@@ -1,4 +1,6 @@
 // edition:2018
+#![feature(must_not_suspend)]
+#![allow(must_not_suspend)]
 
 use std::future::Future;
 use std::sync::Mutex;
index ac254346c08a63841c9420354dcac1399e482732..3cc800f96c20d0ed983779fc88362c13f5bf7aa2 100644 (file)
@@ -1,12 +1,12 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-71137.rs:20:14
+  --> $DIR/issue-71137.rs:22:14
    |
 LL |   fake_spawn(wrong_mutex());
    |              ^^^^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
    |
    = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, i32>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-71137.rs:12:5
+  --> $DIR/issue-71137.rs:14:5
    |
 LL |     let mut guard = m.lock().unwrap();
    |         --------- has type `MutexGuard<'_, i32>` which is not `Send`
@@ -16,7 +16,7 @@ LL |     *guard += 1;
 LL |   }
    |   - `mut guard` is later dropped here
 note: required by a bound in `fake_spawn`
-  --> $DIR/issue-71137.rs:6:27
+  --> $DIR/issue-71137.rs:8:27
    |
 LL | fn fake_spawn<F: Future + Send + 'static>(f: F) { }
    |                           ^^^^ required by this bound in `fake_spawn`
diff --git a/src/test/ui/async-await/issue-73541-1.rs b/src/test/ui/async-await/issue-73541-1.rs
new file mode 100644 (file)
index 0000000..7fb0d6c
--- /dev/null
@@ -0,0 +1,12 @@
+// edition:2018
+
+fn main() {
+    'a: loop {
+        async {
+            loop {
+                continue 'a
+                //~^ ERROR use of unreachable label `'a`
+            }
+        };
+    }
+}
diff --git a/src/test/ui/async-await/issue-73541-1.stderr b/src/test/ui/async-await/issue-73541-1.stderr
new file mode 100644 (file)
index 0000000..80c1fdf
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0767]: use of unreachable label `'a`
+  --> $DIR/issue-73541-1.rs:7:26
+   |
+LL |     'a: loop {
+   |     -- unreachable label defined here
+...
+LL |                 continue 'a
+   |                          ^^ unreachable label `'a`
+   |
+   = note: labels are unreachable through functions, closures, async blocks and modules
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0767`.
diff --git a/src/test/ui/attributes/issue-40962.rs b/src/test/ui/attributes/issue-40962.rs
new file mode 100644 (file)
index 0000000..7b91c06
--- /dev/null
@@ -0,0 +1,11 @@
+// check-pass
+macro_rules! m {
+    ($i:meta) => {
+        #[derive($i)]
+        struct S;
+    }
+}
+
+m!(Clone);
+
+fn main() {}
diff --git a/src/test/ui/attributes/unrestricted-attribute-tokens.rs b/src/test/ui/attributes/unrestricted-attribute-tokens.rs
new file mode 100644 (file)
index 0000000..e31bc91
--- /dev/null
@@ -0,0 +1,8 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![feature(rustc_attrs)]
+
+#[rustc_dummy(a b c d)]
+#[rustc_dummy[a b c d]]
+#[rustc_dummy{a b c d}]
+fn main() {}
diff --git a/src/test/ui/auxiliary/changing-crates-a1.rs b/src/test/ui/auxiliary/changing-crates-a1.rs
deleted file mode 100644 (file)
index bc0559b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#![crate_name = "a"]
-
-pub fn foo<T>() {}
diff --git a/src/test/ui/auxiliary/changing-crates-a2.rs b/src/test/ui/auxiliary/changing-crates-a2.rs
deleted file mode 100644 (file)
index fafc6d5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#![crate_name = "a"]
-
-pub fn foo<T>() { println!("hello!"); }
diff --git a/src/test/ui/auxiliary/changing-crates-b.rs b/src/test/ui/auxiliary/changing-crates-b.rs
deleted file mode 100644 (file)
index f9ce29e..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#![crate_name = "b"]
-
-extern crate a;
-
-pub fn foo() { a::foo::<isize>(); }
diff --git a/src/test/ui/auxiliary/legacy-const-generics.rs b/src/test/ui/auxiliary/legacy-const-generics.rs
deleted file mode 100644 (file)
index 67352a2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(rustc_attrs)]
-
-#[rustc_legacy_const_generics(1)]
-pub fn foo<const Y: usize>(x: usize, z: usize) -> [usize; 3] {
-    [x, Y, z]
-}
diff --git a/src/test/ui/auxiliary/lto-duplicate-symbols1.rs b/src/test/ui/auxiliary/lto-duplicate-symbols1.rs
deleted file mode 100644 (file)
index ec6d056..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-
-#[no_mangle]
-pub extern "C" fn foo() {}
diff --git a/src/test/ui/auxiliary/lto-duplicate-symbols2.rs b/src/test/ui/auxiliary/lto-duplicate-symbols2.rs
deleted file mode 100644 (file)
index ec6d056..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-
-#[no_mangle]
-pub extern "C" fn foo() {}
diff --git a/src/test/ui/auxiliary/lto-rustc-loads-linker-plugin.rs b/src/test/ui/auxiliary/lto-rustc-loads-linker-plugin.rs
deleted file mode 100644 (file)
index d24375b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// compile-flags: -Clinker-plugin-lto
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-
-pub fn foo() {}
diff --git a/src/test/ui/auxiliary/nested_item.rs b/src/test/ui/auxiliary/nested_item.rs
deleted file mode 100644 (file)
index 9db9d19..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// original problem
-pub fn foo<T>() -> isize {
-    {
-        static foo: isize = 2;
-        foo
-    }
-}
-
-// issue 8134
-struct Foo;
-impl Foo {
-    pub fn foo<T>(&self) {
-        static X: usize = 1;
-    }
-}
-
-// issue 8134
-pub struct Parser<T>(T);
-impl<T: std::iter::Iterator<Item=char>> Parser<T> {
-    fn in_doctype(&mut self) {
-        static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E'];
-    }
-}
-
-struct Bar;
-impl Foo {
-    pub fn bar<T>(&self) {
-        static X: usize = 1;
-    }
-}
diff --git a/src/test/ui/bastion-of-the-turbofish.rs b/src/test/ui/bastion-of-the-turbofish.rs
deleted file mode 100644 (file)
index e128570..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// check-pass
-
-// Bastion of the Turbofish
-// ------------------------
-// Beware travellers, lest you venture into waters callous and unforgiving,
-// where hope must be abandoned, ere it is cruelly torn from you. For here
-// stands the bastion of the Turbofish: an impenetrable fortress holding
-// unshaking against those who would dare suggest the supererogation of the
-// Turbofish.
-//
-// Once I was young and foolish and had the impudence to imagine that I could
-// shake free from the coils by which that creature had us tightly bound. I
-// dared to suggest that there was a better way: a brighter future, in which
-// Rustaceans both new and old could be rid of that vile beast. But alas! In
-// my foolhardiness my ignorance was unveiled and my dreams were dashed
-// unforgivingly against the rock of syntactic ambiguity.
-//
-// This humble program, small and insignificant though it might seem,
-// demonstrates that to which we had previously cast a blind eye: an ambiguity
-// in permitting generic arguments to be provided without the consent of the
-// Great Turbofish. Should you be so naïve as to try to revolt against its
-// mighty clutches, here shall its wrath be indomitably displayed. This
-// program must pass for all eternity: forever watched by the guardian angel
-// which gave this beast its name, and stands fundamentally at odds with the
-// impetuous rebellion against the Turbofish.
-//
-// My heart aches in sorrow, for I know I am defeated. Let this be a warning
-// to all those who come after: for they too must overcome the impassible
-// hurdle of defeating the great beast, championed by a resolute winged
-// guardian.
-//
-// Here stands the Bastion of the Turbofish, a memorial to Anna Harren,
-// Guardian Angel of these Hallowed Grounds. <3
-
-// See https://github.com/rust-lang/rust/pull/53562
-// and https://github.com/rust-lang/rfcs/pull/2527
-// and https://twitter.com/garblefart/status/1393236602856611843
-// for context.
-
-fn main() {
-    let (the, guardian, stands, resolute) = ("the", "Turbofish", "remains", "undefeated");
-    let _: (bool, bool) = (the<guardian, stands>(resolute));
-}
diff --git a/src/test/ui/binop/structured-compare.rs b/src/test/ui/binop/structured-compare.rs
new file mode 100644 (file)
index 0000000..63d30c4
--- /dev/null
@@ -0,0 +1,30 @@
+// run-pass
+
+#![allow(non_camel_case_types)]
+
+
+#[derive(Copy, Clone, Debug)]
+enum foo { large, small, }
+
+impl PartialEq for foo {
+    fn eq(&self, other: &foo) -> bool {
+        ((*self) as usize) == ((*other) as usize)
+    }
+    fn ne(&self, other: &foo) -> bool { !(*self).eq(other) }
+}
+
+pub fn main() {
+    let a = (1, 2, 3);
+    let b = (1, 2, 3);
+    assert_eq!(a, b);
+    assert!((a != (1, 2, 4)));
+    assert!((a < (1, 2, 4)));
+    assert!((a <= (1, 2, 4)));
+    assert!(((1, 2, 4) > a));
+    assert!(((1, 2, 4) >= a));
+    let x = foo::large;
+    let y = foo::small;
+    assert!((x != y));
+    assert_eq!(x, foo::large);
+    assert!((x != foo::small));
+}
diff --git a/src/test/ui/borrowck/issue-46095.rs b/src/test/ui/borrowck/issue-46095.rs
new file mode 100644 (file)
index 0000000..59ddb60
--- /dev/null
@@ -0,0 +1,30 @@
+// run-pass
+struct A;
+
+impl A {
+    fn take_mutably(&mut self) {}
+}
+
+fn identity<T>(t: T) -> T {
+    t
+}
+
+// Issue 46095
+// Built-in indexing should be used even when the index is not
+// trivially an integer
+// Overloaded indexing would cause wrapped to be borrowed mutably
+
+fn main() {
+    let mut a1 = A;
+    let mut a2 = A;
+
+    let wrapped = [&mut a1, &mut a2];
+
+    {
+        wrapped[0 + 1 - 1].take_mutably();
+    }
+
+    {
+        wrapped[identity(0)].take_mutably();
+    }
+}
diff --git a/src/test/ui/box/new-box.rs b/src/test/ui/box/new-box.rs
new file mode 100644 (file)
index 0000000..96a3b19
--- /dev/null
@@ -0,0 +1,30 @@
+// run-pass
+
+fn f(x: Box<isize>) {
+    let y: &isize = &*x;
+    println!("{}", *x);
+    println!("{}", *y);
+}
+
+trait Trait {
+    fn printme(&self);
+}
+
+struct Struct;
+
+impl Trait for Struct {
+    fn printme(&self) {
+        println!("hello world!");
+    }
+}
+
+fn g(x: Box<dyn Trait>) {
+    x.printme();
+    let y: &dyn Trait = &*x;
+    y.printme();
+}
+
+fn main() {
+    f(Box::new(1234));
+    g(Box::new(Struct) as Box<dyn Trait>);
+}
diff --git a/src/test/ui/c-variadic/issue-32201.rs b/src/test/ui/c-variadic/issue-32201.rs
new file mode 100644 (file)
index 0000000..f27bb1c
--- /dev/null
@@ -0,0 +1,13 @@
+extern "C" {
+    fn foo(a: i32, ...);
+}
+
+fn bar(_: *const u8) {}
+
+fn main() {
+    unsafe {
+        foo(0, bar);
+        //~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function
+        //~| HELP cast the value to `fn(*const u8)`
+    }
+}
diff --git a/src/test/ui/c-variadic/issue-32201.stderr b/src/test/ui/c-variadic/issue-32201.stderr
new file mode 100644 (file)
index 0000000..cedb587
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0617]: can't pass `fn(*const u8) {bar}` to variadic function
+  --> $DIR/issue-32201.rs:9:16
+   |
+LL |         foo(0, bar);
+   |                ^^^ help: cast the value to `fn(*const u8)`: `bar as fn(*const u8)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0617`.
diff --git a/src/test/ui/cast/supported-cast.rs b/src/test/ui/cast/supported-cast.rs
new file mode 100644 (file)
index 0000000..ff41ce6
--- /dev/null
@@ -0,0 +1,206 @@
+// run-pass
+
+pub fn main() {
+  let f = 1_usize as *const String;
+  println!("{:?}", f as isize);
+  println!("{:?}", f as usize);
+  println!("{:?}", f as i8);
+  println!("{:?}", f as i16);
+  println!("{:?}", f as i32);
+  println!("{:?}", f as i64);
+  println!("{:?}", f as u8);
+  println!("{:?}", f as u16);
+  println!("{:?}", f as u32);
+  println!("{:?}", f as u64);
+
+  println!("{:?}", 1 as isize);
+  println!("{:?}", 1 as usize);
+  println!("{:?}", 1 as *const String);
+  println!("{:?}", 1 as i8);
+  println!("{:?}", 1 as i16);
+  println!("{:?}", 1 as i32);
+  println!("{:?}", 1 as i64);
+  println!("{:?}", 1 as u8);
+  println!("{:?}", 1 as u16);
+  println!("{:?}", 1 as u32);
+  println!("{:?}", 1 as u64);
+  println!("{:?}", 1 as f32);
+  println!("{:?}", 1 as f64);
+
+  println!("{:?}", 1_usize as isize);
+  println!("{:?}", 1_usize as usize);
+  println!("{:?}", 1_usize as *const String);
+  println!("{:?}", 1_usize as i8);
+  println!("{:?}", 1_usize as i16);
+  println!("{:?}", 1_usize as i32);
+  println!("{:?}", 1_usize as i64);
+  println!("{:?}", 1_usize as u8);
+  println!("{:?}", 1_usize as u16);
+  println!("{:?}", 1_usize as u32);
+  println!("{:?}", 1_usize as u64);
+  println!("{:?}", 1_usize as f32);
+  println!("{:?}", 1_usize as f64);
+
+  println!("{:?}", 1i8 as isize);
+  println!("{:?}", 1i8 as usize);
+  println!("{:?}", 1i8 as *const String);
+  println!("{:?}", 1i8 as i8);
+  println!("{:?}", 1i8 as i16);
+  println!("{:?}", 1i8 as i32);
+  println!("{:?}", 1i8 as i64);
+  println!("{:?}", 1i8 as u8);
+  println!("{:?}", 1i8 as u16);
+  println!("{:?}", 1i8 as u32);
+  println!("{:?}", 1i8 as u64);
+  println!("{:?}", 1i8 as f32);
+  println!("{:?}", 1i8 as f64);
+
+  println!("{:?}", 1u8 as isize);
+  println!("{:?}", 1u8 as usize);
+  println!("{:?}", 1u8 as *const String);
+  println!("{:?}", 1u8 as i8);
+  println!("{:?}", 1u8 as i16);
+  println!("{:?}", 1u8 as i32);
+  println!("{:?}", 1u8 as i64);
+  println!("{:?}", 1u8 as u8);
+  println!("{:?}", 1u8 as u16);
+  println!("{:?}", 1u8 as u32);
+  println!("{:?}", 1u8 as u64);
+  println!("{:?}", 1u8 as f32);
+  println!("{:?}", 1u8 as f64);
+
+  println!("{:?}", 1i16 as isize);
+  println!("{:?}", 1i16 as usize);
+  println!("{:?}", 1i16 as *const String);
+  println!("{:?}", 1i16 as i8);
+  println!("{:?}", 1i16 as i16);
+  println!("{:?}", 1i16 as i32);
+  println!("{:?}", 1i16 as i64);
+  println!("{:?}", 1i16 as u8);
+  println!("{:?}", 1i16 as u16);
+  println!("{:?}", 1i16 as u32);
+  println!("{:?}", 1i16 as u64);
+  println!("{:?}", 1i16 as f32);
+  println!("{:?}", 1i16 as f64);
+
+  println!("{:?}", 1u16 as isize);
+  println!("{:?}", 1u16 as usize);
+  println!("{:?}", 1u16 as *const String);
+  println!("{:?}", 1u16 as i8);
+  println!("{:?}", 1u16 as i16);
+  println!("{:?}", 1u16 as i32);
+  println!("{:?}", 1u16 as i64);
+  println!("{:?}", 1u16 as u8);
+  println!("{:?}", 1u16 as u16);
+  println!("{:?}", 1u16 as u32);
+  println!("{:?}", 1u16 as u64);
+  println!("{:?}", 1u16 as f32);
+  println!("{:?}", 1u16 as f64);
+
+  println!("{:?}", 1i32 as isize);
+  println!("{:?}", 1i32 as usize);
+  println!("{:?}", 1i32 as *const String);
+  println!("{:?}", 1i32 as i8);
+  println!("{:?}", 1i32 as i16);
+  println!("{:?}", 1i32 as i32);
+  println!("{:?}", 1i32 as i64);
+  println!("{:?}", 1i32 as u8);
+  println!("{:?}", 1i32 as u16);
+  println!("{:?}", 1i32 as u32);
+  println!("{:?}", 1i32 as u64);
+  println!("{:?}", 1i32 as f32);
+  println!("{:?}", 1i32 as f64);
+
+  println!("{:?}", 1u32 as isize);
+  println!("{:?}", 1u32 as usize);
+  println!("{:?}", 1u32 as *const String);
+  println!("{:?}", 1u32 as i8);
+  println!("{:?}", 1u32 as i16);
+  println!("{:?}", 1u32 as i32);
+  println!("{:?}", 1u32 as i64);
+  println!("{:?}", 1u32 as u8);
+  println!("{:?}", 1u32 as u16);
+  println!("{:?}", 1u32 as u32);
+  println!("{:?}", 1u32 as u64);
+  println!("{:?}", 1u32 as f32);
+  println!("{:?}", 1u32 as f64);
+
+  println!("{:?}", 1i64 as isize);
+  println!("{:?}", 1i64 as usize);
+  println!("{:?}", 1i64 as *const String);
+  println!("{:?}", 1i64 as i8);
+  println!("{:?}", 1i64 as i16);
+  println!("{:?}", 1i64 as i32);
+  println!("{:?}", 1i64 as i64);
+  println!("{:?}", 1i64 as u8);
+  println!("{:?}", 1i64 as u16);
+  println!("{:?}", 1i64 as u32);
+  println!("{:?}", 1i64 as u64);
+  println!("{:?}", 1i64 as f32);
+  println!("{:?}", 1i64 as f64);
+
+  println!("{:?}", 1u64 as isize);
+  println!("{:?}", 1u64 as usize);
+  println!("{:?}", 1u64 as *const String);
+  println!("{:?}", 1u64 as i8);
+  println!("{:?}", 1u64 as i16);
+  println!("{:?}", 1u64 as i32);
+  println!("{:?}", 1u64 as i64);
+  println!("{:?}", 1u64 as u8);
+  println!("{:?}", 1u64 as u16);
+  println!("{:?}", 1u64 as u32);
+  println!("{:?}", 1u64 as u64);
+  println!("{:?}", 1u64 as f32);
+  println!("{:?}", 1u64 as f64);
+
+  println!("{:?}", 1u64 as isize);
+  println!("{:?}", 1u64 as usize);
+  println!("{:?}", 1u64 as *const String);
+  println!("{:?}", 1u64 as i8);
+  println!("{:?}", 1u64 as i16);
+  println!("{:?}", 1u64 as i32);
+  println!("{:?}", 1u64 as i64);
+  println!("{:?}", 1u64 as u8);
+  println!("{:?}", 1u64 as u16);
+  println!("{:?}", 1u64 as u32);
+  println!("{:?}", 1u64 as u64);
+  println!("{:?}", 1u64 as f32);
+  println!("{:?}", 1u64 as f64);
+
+  println!("{:?}", true as isize);
+  println!("{:?}", true as usize);
+  println!("{:?}", true as i8);
+  println!("{:?}", true as i16);
+  println!("{:?}", true as i32);
+  println!("{:?}", true as i64);
+  println!("{:?}", true as u8);
+  println!("{:?}", true as u16);
+  println!("{:?}", true as u32);
+  println!("{:?}", true as u64);
+
+  println!("{:?}", 1f32 as isize);
+  println!("{:?}", 1f32 as usize);
+  println!("{:?}", 1f32 as i8);
+  println!("{:?}", 1f32 as i16);
+  println!("{:?}", 1f32 as i32);
+  println!("{:?}", 1f32 as i64);
+  println!("{:?}", 1f32 as u8);
+  println!("{:?}", 1f32 as u16);
+  println!("{:?}", 1f32 as u32);
+  println!("{:?}", 1f32 as u64);
+  println!("{:?}", 1f32 as f32);
+  println!("{:?}", 1f32 as f64);
+
+  println!("{:?}", 1f64 as isize);
+  println!("{:?}", 1f64 as usize);
+  println!("{:?}", 1f64 as i8);
+  println!("{:?}", 1f64 as i16);
+  println!("{:?}", 1f64 as i32);
+  println!("{:?}", 1f64 as i64);
+  println!("{:?}", 1f64 as u8);
+  println!("{:?}", 1f64 as u16);
+  println!("{:?}", 1f64 as u32);
+  println!("{:?}", 1f64 as u64);
+  println!("{:?}", 1f64 as f32);
+  println!("{:?}", 1f64 as f64);
+}
diff --git a/src/test/ui/changing-crates.rs b/src/test/ui/changing-crates.rs
deleted file mode 100644 (file)
index 60c043b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// ignore-msvc FIXME #31306
-
-// note that these aux-build directives must be in this order
-// aux-build:changing-crates-a1.rs
-// aux-build:changing-crates-b.rs
-// aux-build:changing-crates-a2.rs
-// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2"
-
-extern crate a;
-extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
-
-fn main() {}
diff --git a/src/test/ui/changing-crates.stderr b/src/test/ui/changing-crates.stderr
deleted file mode 100644 (file)
index cc62a4d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0460]: found possibly newer version of crate `a` which `b` depends on
-  --> $DIR/changing-crates.rs:10:1
-   |
-LL | extern crate b;
-   | ^^^^^^^^^^^^^^^
-   |
-   = note: perhaps that crate needs to be recompiled?
-   = note: the following crate versions were found:
-           crate `a`: $PATH_a
-           crate `b`: $PATH_b
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-90465.fixed b/src/test/ui/closures/2229_closure_analysis/issue-90465.fixed
new file mode 100644 (file)
index 0000000..4e0b18e
--- /dev/null
@@ -0,0 +1,35 @@
+// run-rustfix
+
+#![deny(rust_2021_incompatible_closure_captures)]
+//~^ NOTE lint level is defined here
+
+fn main() {
+    struct Foo(u32);
+    impl Drop for Foo {
+        fn drop(&mut self) {
+            println!("dropped {}", self.0);
+        }
+    }
+
+    let f0 = Foo(0);
+    let f1 = Foo(1);
+
+    let c0 = move || {
+        let _ = &f0;
+        //~^ ERROR changes to closure capture in Rust 2021 will affect drop order
+        //~| NOTE for more information
+        let _ = f0;
+        //~^ NOTE in Rust 2018, this causes the closure to capture `f0`, but in Rust 2021, it has no effect
+    };
+
+    let c1 = move || {
+        let _ = &f1;
+    };
+
+    println!("dropping 0");
+    drop(c0);
+    println!("dropping 1");
+    drop(c1);
+    println!("dropped all");
+}
+//~^ NOTE in Rust 2018, `f0` is dropped here along with the closure, but in Rust 2021 `f0` is not part of the closure
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-90465.rs b/src/test/ui/closures/2229_closure_analysis/issue-90465.rs
new file mode 100644 (file)
index 0000000..466e6db
--- /dev/null
@@ -0,0 +1,34 @@
+// run-rustfix
+
+#![deny(rust_2021_incompatible_closure_captures)]
+//~^ NOTE lint level is defined here
+
+fn main() {
+    struct Foo(u32);
+    impl Drop for Foo {
+        fn drop(&mut self) {
+            println!("dropped {}", self.0);
+        }
+    }
+
+    let f0 = Foo(0);
+    let f1 = Foo(1);
+
+    let c0 = move || {
+        //~^ ERROR changes to closure capture in Rust 2021 will affect drop order
+        //~| NOTE for more information
+        let _ = f0;
+        //~^ NOTE in Rust 2018, this causes the closure to capture `f0`, but in Rust 2021, it has no effect
+    };
+
+    let c1 = move || {
+        let _ = &f1;
+    };
+
+    println!("dropping 0");
+    drop(c0);
+    println!("dropping 1");
+    drop(c1);
+    println!("dropped all");
+}
+//~^ NOTE in Rust 2018, `f0` is dropped here along with the closure, but in Rust 2021 `f0` is not part of the closure
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr b/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr
new file mode 100644 (file)
index 0000000..3e921dc
--- /dev/null
@@ -0,0 +1,26 @@
+error: changes to closure capture in Rust 2021 will affect drop order
+  --> $DIR/issue-90465.rs:17:14
+   |
+LL |     let c0 = move || {
+   |              ^^^^^^^
+...
+LL |         let _ = f0;
+   |                 -- in Rust 2018, this causes the closure to capture `f0`, but in Rust 2021, it has no effect
+...
+LL | }
+   | - in Rust 2018, `f0` is dropped here along with the closure, but in Rust 2021 `f0` is not part of the closure
+   |
+note: the lint level is defined here
+  --> $DIR/issue-90465.rs:3:9
+   |
+LL | #![deny(rust_2021_incompatible_closure_captures)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+help: add a dummy let to cause `f0` to be fully captured
+   |
+LL ~     let c0 = move || {
+LL +         let _ = &f0;
+   |
+
+error: aborting due to previous error
+
index b0fc5120f08f219783461c3e3e44316ed4323b28..26703fbf81193603e2a471b5a5d055b20bcc93db 100644 (file)
@@ -20,8 +20,8 @@ fn test_send_trait() {
     let mut f = 10;
     let fptr = SendPointer(&mut f as *mut i32);
     thread::spawn(move || { let _ = &fptr; unsafe {
-        //~^ ERROR: `Send` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0` does not implement `Send`
+        //~^ ERROR: changes to closure capture
+        //~| NOTE: in Rust 2018, this closure implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0 = 20;
@@ -40,8 +40,9 @@ fn test_sync_trait() {
     let f = CustomInt(&mut f as *mut i32);
     let fptr = SyncPointer(f);
     thread::spawn(move || { let _ = &fptr; unsafe {
-        //~^ ERROR: `Sync`, `Send` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Sync`, `Send` as `fptr` implements `Sync`, `Send`, but in Rust 2021, this closure will no longer implement `Sync`, `Send` as `fptr.0.0` does not implement `Sync`, `Send`
+        //~^ ERROR: changes to closure capture
+        //~| NOTE: in Rust 2018, this closure implements `Sync`
+        //~| NOTE: in Rust 2018, this closure implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0.0 = 20;
@@ -65,8 +66,8 @@ fn test_clone_trait() {
     let f = U(S(Foo(0)), T(0));
     let c = || {
         let _ = &f;
-        //~^ ERROR: `Clone` trait implementation for closure and drop order
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f.1` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
+        //~| NOTE: in Rust 2018, this closure implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         let f_1 = f.1;
index 2bcf9a795edbd8f9fa093efe8b216d76725d777f..932db51d437130699e7256ef92cf104542b34940 100644 (file)
@@ -20,8 +20,8 @@ fn test_send_trait() {
     let mut f = 10;
     let fptr = SendPointer(&mut f as *mut i32);
     thread::spawn(move || unsafe {
-        //~^ ERROR: `Send` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0` does not implement `Send`
+        //~^ ERROR: changes to closure capture
+        //~| NOTE: in Rust 2018, this closure implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0 = 20;
@@ -40,8 +40,9 @@ fn test_sync_trait() {
     let f = CustomInt(&mut f as *mut i32);
     let fptr = SyncPointer(f);
     thread::spawn(move || unsafe {
-        //~^ ERROR: `Sync`, `Send` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Sync`, `Send` as `fptr` implements `Sync`, `Send`, but in Rust 2021, this closure will no longer implement `Sync`, `Send` as `fptr.0.0` does not implement `Sync`, `Send`
+        //~^ ERROR: changes to closure capture
+        //~| NOTE: in Rust 2018, this closure implements `Sync`
+        //~| NOTE: in Rust 2018, this closure implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0.0 = 20;
@@ -64,8 +65,8 @@ fn clone(&self) -> Self {
 fn test_clone_trait() {
     let f = U(S(Foo(0)), T(0));
     let c = || {
-        //~^ ERROR: `Clone` trait implementation for closure and drop order
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f.1` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
+        //~| NOTE: in Rust 2018, this closure implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         let f_1 = f.1;
index 8d2d3553d4040f2fdbb6027cbe71d5fb5c3fd700..ee4907bb755cc115005945b6af0d7fa14e964da4 100644 (file)
@@ -1,8 +1,8 @@
-error: changes to closure capture in Rust 2021 will affect `Send` trait implementation for closure
+error: changes to closure capture in Rust 2021 will affect which traits the closure implements
   --> $DIR/auto_traits.rs:22:19
    |
 LL |     thread::spawn(move || unsafe {
-   |                   ^^^^^^^^^^^^^^ in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0` does not implement `Send`
+   |                   ^^^^^^^^^^^^^^ in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr` is not fully captured and `fptr.0` does not implement `Send`
 ...
 LL |         *fptr.0 = 20;
    |         ------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0`
@@ -23,11 +23,14 @@ LL |
 LL |         *fptr.0 = 20;
  ...
 
-error: changes to closure capture in Rust 2021 will affect `Sync`, `Send` trait implementation for closure
+error: changes to closure capture in Rust 2021 will affect which traits the closure implements
   --> $DIR/auto_traits.rs:42:19
    |
 LL |     thread::spawn(move || unsafe {
-   |                   ^^^^^^^^^^^^^^ in Rust 2018, this closure implements `Sync`, `Send` as `fptr` implements `Sync`, `Send`, but in Rust 2021, this closure will no longer implement `Sync`, `Send` as `fptr.0.0` does not implement `Sync`, `Send`
+   |                   ^^^^^^^^^^^^^^
+   |                   |
+   |                   in Rust 2018, this closure implements `Sync` as `fptr` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` because `fptr` is not fully captured and `fptr.0.0` does not implement `Sync`
+   |                   in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr` is not fully captured and `fptr.0.0` does not implement `Send`
 ...
 LL |         *fptr.0.0 = 20;
    |         --------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0.0`
@@ -40,14 +43,14 @@ LL |
 LL |
 LL |
 LL |
-LL |         *fptr.0.0 = 20;
+LL |
  ...
 
-error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure and drop order
-  --> $DIR/auto_traits.rs:66:13
+error: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
+  --> $DIR/auto_traits.rs:67:13
    |
 LL |     let c = || {
-   |             ^^ in Rust 2018, this closure implements `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f.1` does not implement `Clone`
+   |             ^^ in Rust 2018, this closure implements `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f` is not fully captured and `f.1` does not implement `Clone`
 ...
 LL |         let f_1 = f.1;
    |                   --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.1`
index a5652154682c5b672da67568c79a30dbc1f1e384..7df0dd76b44564b768e8989ece9e037c962d9136 100644 (file)
@@ -19,8 +19,9 @@ where
     let f = panic::AssertUnwindSafe(f);
     let result = panic::catch_unwind(move || {
         let _ = &f;
-        //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `UnwindSafe`, `RefUnwindSafe` as `f` implements `UnwindSafe`, `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe`, `RefUnwindSafe` as `f.0` does not implement `UnwindSafe`, `RefUnwindSafe`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
+        //~| NOTE: in Rust 2018, this closure implements `UnwindSafe`
+        //~| NOTE: in Rust 2018, this closure implements `RefUnwindSafe`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         f.0()
index d9acde073fc3d38fffd84202b80668764057f394..d02fac7c66952606048a19827fcd9c37050b3c23 100644 (file)
@@ -18,8 +18,9 @@ fn assert_panics<F>(f: F)
 {
     let f = panic::AssertUnwindSafe(f);
     let result = panic::catch_unwind(move || {
-        //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `UnwindSafe`, `RefUnwindSafe` as `f` implements `UnwindSafe`, `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe`, `RefUnwindSafe` as `f.0` does not implement `UnwindSafe`, `RefUnwindSafe`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
+        //~| NOTE: in Rust 2018, this closure implements `UnwindSafe`
+        //~| NOTE: in Rust 2018, this closure implements `RefUnwindSafe`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         f.0()
index 10816b7bc3adf9346df3414fd7ed2105e6b6a621..74f85b6ebaac50e5f3de999ef10a17f90740d93d 100644 (file)
@@ -1,8 +1,11 @@
-error: changes to closure capture in Rust 2021 will affect `UnwindSafe`, `RefUnwindSafe` trait implementation for closure
+error: changes to closure capture in Rust 2021 will affect which traits the closure implements
   --> $DIR/mir_calls_to_shims.rs:20:38
    |
 LL |     let result = panic::catch_unwind(move || {
-   |                                      ^^^^^^^ in Rust 2018, this closure implements `UnwindSafe`, `RefUnwindSafe` as `f` implements `UnwindSafe`, `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe`, `RefUnwindSafe` as `f.0` does not implement `UnwindSafe`, `RefUnwindSafe`
+   |                                      ^^^^^^^
+   |                                      |
+   |                                      in Rust 2018, this closure implements `UnwindSafe` as `f` implements `UnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe` because `f` is not fully captured and `f.0` does not implement `UnwindSafe`
+   |                                      in Rust 2018, this closure implements `RefUnwindSafe` as `f` implements `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `RefUnwindSafe` because `f` is not fully captured and `f.0` does not implement `RefUnwindSafe`
 ...
 LL |         f.0()
    |         --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.0`
index 11218eff1337f7f63e779df6b9ec5a7a40fdc429..2b86b0ddade2367196e542f83ac91b65cfc2b2b7 100644 (file)
@@ -18,7 +18,6 @@ impl Foo {
     }
 }
 
-
 struct S(Foo);
 
 #[derive(Clone)]
@@ -37,8 +36,8 @@ fn test_multi_issues() {
     let f2 = U(S(Foo::from("bar")), T(0));
     let c = || {
         let _ = (&f1, &f2);
-        //~^ ERROR: `Clone` trait implementation for closure and drop order
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1`, `f2` to be fully captured
         let _f_1 = f1.0;
@@ -57,8 +56,8 @@ fn test_capturing_all_disjoint_fields_individually() {
     let f1 = U(S(Foo::from("foo")), T(0));
     let c = || {
         let _ = &f1;
-        //~^ ERROR: `Clone` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_1 = f1.0;
@@ -83,9 +82,9 @@ fn test_capturing_several_disjoint_fields_individually_1() {
     let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
         let _ = &f1;
-        //~^ ERROR: `Clone` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.2` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_0 = f1.0;
@@ -103,8 +102,8 @@ fn test_capturing_several_disjoint_fields_individually_2() {
     let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
         let _ = &f1;
-        //~^ ERROR: `Clone` trait implementation for closure and drop order
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_0 = f1.0;
@@ -136,9 +135,10 @@ fn test_multi_traits_issues() {
     let mut f2 = 10;
     let fptr2 = SendPointer(&mut f2 as *mut i32);
     thread::spawn(move || { let _ = (&fptr1, &fptr2); unsafe {
-        //~^ ERROR: `Sync`, `Send` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Sync`, `Send` as `fptr1` implements `Sync`, `Send`, but in Rust 2021, this closure will no longer implement `Sync`, `Send` as `fptr1.0.0` does not implement `Sync`, `Send`
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr2.0` does not implement `Send`
+        //~^ ERROR: changes to closure capture in Rust 2021
+        //~| NOTE: in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`
+        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr1`, `fptr2` to be fully captured
         *fptr1.0.0 = 20;
index 02f2faa2e8741615266e5f91687be7713335d207..3cac4abfad7c2a5def2e614517d6d30684481719 100644 (file)
@@ -18,7 +18,6 @@ fn from(s: &str) -> Self {
     }
 }
 
-
 struct S(Foo);
 
 #[derive(Clone)]
@@ -36,8 +35,8 @@ fn test_multi_issues() {
     let f1 = U(S(Foo::from("foo")), T(0));
     let f2 = U(S(Foo::from("bar")), T(0));
     let c = || {
-        //~^ ERROR: `Clone` trait implementation for closure and drop order
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1`, `f2` to be fully captured
         let _f_1 = f1.0;
@@ -55,8 +54,8 @@ fn test_multi_issues() {
 fn test_capturing_all_disjoint_fields_individually() {
     let f1 = U(S(Foo::from("foo")), T(0));
     let c = || {
-        //~^ ERROR: `Clone` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_1 = f1.0;
@@ -80,9 +79,9 @@ fn clone(&self) -> Self {
 fn test_capturing_several_disjoint_fields_individually_1() {
     let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
-        //~^ ERROR: `Clone` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.2` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_0 = f1.0;
@@ -99,8 +98,8 @@ fn test_capturing_several_disjoint_fields_individually_1() {
 fn test_capturing_several_disjoint_fields_individually_2() {
     let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
-        //~^ ERROR: `Clone` trait implementation for closure and drop order
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~^ ERROR: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_0 = f1.0;
@@ -132,9 +131,10 @@ fn test_multi_traits_issues() {
     let mut f2 = 10;
     let fptr2 = SendPointer(&mut f2 as *mut i32);
     thread::spawn(move || unsafe {
-        //~^ ERROR: `Sync`, `Send` trait implementation for closure
-        //~| NOTE: in Rust 2018, this closure implements `Sync`, `Send` as `fptr1` implements `Sync`, `Send`, but in Rust 2021, this closure will no longer implement `Sync`, `Send` as `fptr1.0.0` does not implement `Sync`, `Send`
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr2.0` does not implement `Send`
+        //~^ ERROR: changes to closure capture in Rust 2021
+        //~| NOTE: in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`
+        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr1`, `fptr2` to be fully captured
         *fptr1.0.0 = 20;
index d425db5aa998c69394a674441809eef0581660b3..0008f1b2c07ed5811544fd27f9767c75c6bcfec0 100644 (file)
@@ -1,8 +1,8 @@
-error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure and drop order
-  --> $DIR/multi_diagnostics.rs:38:13
+error: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
+  --> $DIR/multi_diagnostics.rs:37:13
    |
 LL |     let c = || {
-   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.0` does not implement `Clone`
 ...
 LL |         let _f_1 = f1.0;
    |                    ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
@@ -25,11 +25,11 @@ LL ~     let c = || {
 LL +         let _ = (&f1, &f2);
    |
 
-error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure
-  --> $DIR/multi_diagnostics.rs:57:13
+error: changes to closure capture in Rust 2021 will affect which traits the closure implements
+  --> $DIR/multi_diagnostics.rs:56:13
    |
 LL |     let c = || {
-   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.0` does not implement `Clone`
 ...
 LL |         let _f_1 = f1.0;
    |                    ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
@@ -41,14 +41,14 @@ LL ~     let c = || {
 LL +         let _ = &f1;
    |
 
-error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure
-  --> $DIR/multi_diagnostics.rs:82:13
+error: changes to closure capture in Rust 2021 will affect which traits the closure implements
+  --> $DIR/multi_diagnostics.rs:81:13
    |
 LL |     let c = || {
    |             ^^
    |             |
-   |             in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
-   |             in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.2` does not implement `Clone`
+   |             in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.0` does not implement `Clone`
+   |             in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.2` does not implement `Clone`
 ...
 LL |         let _f_0 = f1.0;
    |                    ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
@@ -63,11 +63,11 @@ LL ~     let c = || {
 LL +         let _ = &f1;
    |
 
-error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure and drop order
-  --> $DIR/multi_diagnostics.rs:101:13
+error: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
+  --> $DIR/multi_diagnostics.rs:100:13
    |
 LL |     let c = || {
-   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.0` does not implement `Clone`
 ...
 LL |         let _f_0 = f1.0;
    |                    ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
@@ -88,14 +88,15 @@ LL ~     let c = || {
 LL +         let _ = &f1;
    |
 
-error: changes to closure capture in Rust 2021 will affect `Sync`, `Send` trait implementation for closure
-  --> $DIR/multi_diagnostics.rs:134:19
+error: changes to closure capture in Rust 2021 will affect which traits the closure implements
+  --> $DIR/multi_diagnostics.rs:133:19
    |
 LL |     thread::spawn(move || unsafe {
    |                   ^^^^^^^^^^^^^^
    |                   |
-   |                   in Rust 2018, this closure implements `Sync`, `Send` as `fptr1` implements `Sync`, `Send`, but in Rust 2021, this closure will no longer implement `Sync`, `Send` as `fptr1.0.0` does not implement `Sync`, `Send`
-   |                   in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr2.0` does not implement `Send`
+   |                   in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` because `fptr1` is not fully captured and `fptr1.0.0` does not implement `Sync`
+   |                   in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr1` is not fully captured and `fptr1.0.0` does not implement `Send`
+   |                   in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr2` is not fully captured and `fptr2.0` does not implement `Send`
 ...
 LL |         *fptr1.0.0 = 20;
    |         ---------- in Rust 2018, this closure captures all of `fptr1`, but in Rust 2021, it will only capture `fptr1.0.0`
diff --git a/src/test/ui/closures/issue-10398.rs b/src/test/ui/closures/issue-10398.rs
new file mode 100644 (file)
index 0000000..0405b2d
--- /dev/null
@@ -0,0 +1,11 @@
+#![feature(box_syntax)]
+
+fn main() {
+    let x: Box<_> = box 1;
+    let f = move|| {
+        let _a = x;
+        drop(x);
+        //~^ ERROR: use of moved value: `x`
+    };
+    f();
+}
diff --git a/src/test/ui/closures/issue-10398.stderr b/src/test/ui/closures/issue-10398.stderr
new file mode 100644 (file)
index 0000000..8d9faf3
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0382]: use of moved value: `x`
+  --> $DIR/issue-10398.rs:7:14
+   |
+LL |         let _a = x;
+   |                  - value moved here
+LL |         drop(x);
+   |              ^ value used here after move
+   |
+   = note: move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/closures/issue-42463.rs b/src/test/ui/closures/issue-42463.rs
new file mode 100644 (file)
index 0000000..51d6ea3
--- /dev/null
@@ -0,0 +1,32 @@
+// run-pass
+use std::ops::{Deref, DerefMut};
+
+struct CheckedDeref<T, F> {
+    value: T,
+    check: F
+}
+
+impl<F: Fn(&T) -> bool, T> Deref for CheckedDeref<T, F> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        assert!((self.check)(&self.value));
+        &self.value
+    }
+}
+
+impl<F: Fn(&T) -> bool, T> DerefMut for CheckedDeref<T, F> {
+    fn deref_mut(&mut self) -> &mut T {
+        assert!((self.check)(&self.value));
+        &mut self.value
+    }
+}
+
+
+fn main() {
+    let mut v = CheckedDeref {
+        value: vec![0],
+        check: |v: &Vec<_>| !v.is_empty()
+    };
+    v.push(1);
+    assert_eq!(*v, vec![0, 1]);
+}
index d9479002b6cde31df63b1e10c5c04bb77b4504e2..36d6450c9a2f0ceb45e23cf0fa4599f3019e9bf2 100644 (file)
@@ -9,7 +9,7 @@ LL |         let c1 : () = c;
    |                  expected due to this
    |
    = note: expected unit type `()`
-                found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable)]`
+                found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#25t, extern "rust-call" fn(()), _#26t]]`
 help: use parentheses to call this closure
    |
 LL |         let c1 : () = c();
index 880e38df2d70a87586c18a20cdd111dadcbd8711..91926f233d394d83762aa3472334b10838e306c0 100644 (file)
@@ -9,7 +9,7 @@ LL |         let c1 : () = c;
    |                  expected due to this
    |
    = note: expected unit type `()`
-                found closure `[f<T>::{closure#0} closure_substs=(unavailable)]`
+                found closure `[f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#25t, extern "rust-call" fn(()), _#26t]]`
 help: use parentheses to call this closure
    |
 LL |         let c1 : () = c();
index d19b07acbf175c3aa8ed7e88fbe87ed4e847e0b0..083717b333408e46d342f4e6a07b20d72058db87 100644 (file)
@@ -7,7 +7,7 @@ LL |     let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
    |              expected due to this
    |
    = note: expected fn pointer `fn(u8) -> u8`
-                 found closure `[main::{closure#0} closure_substs=(unavailable)]`
+                 found closure `[main::{closure#0} closure_substs=(unavailable) substs=[i8, extern "rust-call" fn((u8,)) -> u8, _#6t]]`
 note: closures can only be coerced to `fn` types if they do not capture any variables
   --> $DIR/closure-print-verbose.rs:10:39
    |
diff --git a/src/test/ui/coercion/auxiliary/issue-39823.rs b/src/test/ui/coercion/auxiliary/issue-39823.rs
new file mode 100644 (file)
index 0000000..3af9c68
--- /dev/null
@@ -0,0 +1,7 @@
+#![crate_type="rlib"]
+
+#[derive(Debug, PartialEq)]
+pub struct RemoteC(pub u32);
+
+#[derive(Debug, PartialEq)]
+pub struct RemoteG<T>(pub T);
diff --git a/src/test/ui/coercion/issue-14589.rs b/src/test/ui/coercion/issue-14589.rs
new file mode 100644 (file)
index 0000000..5d8aab2
--- /dev/null
@@ -0,0 +1,24 @@
+// run-pass
+// All 3 expressions should work in that the argument gets
+// coerced to a trait object
+
+// pretty-expanded FIXME #23616
+
+fn main() {
+    send::<Box<dyn Foo>>(Box::new(Output(0)));
+    Test::<Box<dyn Foo>>::foo(Box::new(Output(0)));
+    Test::<Box<dyn Foo>>::new().send(Box::new(Output(0)));
+}
+
+fn send<T>(_: T) {}
+
+struct Test<T> { marker: std::marker::PhantomData<T> }
+impl<T> Test<T> {
+    fn new() -> Test<T> { Test { marker: ::std::marker::PhantomData } }
+    fn foo(_: T) {}
+    fn send(&self, _: T) {}
+}
+
+trait Foo { fn dummy(&self) { }}
+struct Output(isize);
+impl Foo for Output {}
diff --git a/src/test/ui/coercion/issue-39823.rs b/src/test/ui/coercion/issue-39823.rs
new file mode 100644 (file)
index 0000000..148cf52
--- /dev/null
@@ -0,0 +1,25 @@
+// run-pass
+// aux-build:issue-39823.rs
+
+extern crate issue_39823;
+use issue_39823::{RemoteC, RemoteG};
+
+#[derive(Debug, PartialEq)]
+struct LocalC(u32);
+
+#[derive(Debug, PartialEq)]
+struct LocalG<T>(T);
+
+fn main() {
+    let virtual_localc : &dyn Fn(_) -> LocalC = &LocalC;
+    assert_eq!(virtual_localc(1), LocalC(1));
+
+    let virtual_localg : &dyn Fn(_) -> LocalG<u32> = &LocalG;
+    assert_eq!(virtual_localg(1), LocalG(1));
+
+    let virtual_remotec : &dyn Fn(_) -> RemoteC = &RemoteC;
+    assert_eq!(virtual_remotec(1), RemoteC(1));
+
+    let virtual_remoteg : &dyn Fn(_) -> RemoteG<u32> = &RemoteG;
+    assert_eq!(virtual_remoteg(1), RemoteG(1));
+}
diff --git a/src/test/ui/coercion/issue-73886.rs b/src/test/ui/coercion/issue-73886.rs
new file mode 100644 (file)
index 0000000..9c0c87a
--- /dev/null
@@ -0,0 +1,6 @@
+fn main() {
+    let _ = &&[0] as &[_];
+    //~^ ERROR non-primitive cast: `&&[i32; 1]` as `&[_]`
+    let _ = 7u32 as Option<_>;
+    //~^ ERROR non-primitive cast: `u32` as `Option<_>`
+}
diff --git a/src/test/ui/coercion/issue-73886.stderr b/src/test/ui/coercion/issue-73886.stderr
new file mode 100644 (file)
index 0000000..a6f8ba6
--- /dev/null
@@ -0,0 +1,17 @@
+error[E0605]: non-primitive cast: `&&[i32; 1]` as `&[_]`
+  --> $DIR/issue-73886.rs:2:13
+   |
+LL |     let _ = &&[0] as &[_];
+   |             ^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error[E0605]: non-primitive cast: `u32` as `Option<_>`
+  --> $DIR/issue-73886.rs:4:13
+   |
+LL |     let _ = 7u32 as Option<_>;
+   |             ^^^^^^^^^^^^^^^^^ help: consider using the `From` trait instead: `Option<_>::from(7u32)`
+   |
+   = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/src/test/ui/compare-method/issue-90444.rs b/src/test/ui/compare-method/issue-90444.rs
new file mode 100644 (file)
index 0000000..6c287d9
--- /dev/null
@@ -0,0 +1,17 @@
+pub struct A;
+impl From<fn((), (), &())> for A {
+    fn from(_: fn((), (), &mut ())) -> Self {
+        //~^ error: method `from` has an incompatible type for trait
+        loop {}
+    }
+}
+
+pub struct B;
+impl From<fn((), (), u32)> for B {
+    fn from(_: fn((), (), u64)) -> Self {
+        //~^ error: method `from` has an incompatible type for trait
+        loop {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/compare-method/issue-90444.stderr b/src/test/ui/compare-method/issue-90444.stderr
new file mode 100644 (file)
index 0000000..84bbec0
--- /dev/null
@@ -0,0 +1,27 @@
+error[E0053]: method `from` has an incompatible type for trait
+  --> $DIR/issue-90444.rs:3:16
+   |
+LL |     fn from(_: fn((), (), &mut ())) -> Self {
+   |                ^^^^^^^^^^^^^^^^^^^
+   |                |
+   |                types differ in mutability
+   |                help: change the parameter type to match the trait: `for<'r> fn((), (), &'r ())`
+   |
+   = note: expected fn pointer `fn(for<'r> fn((), (), &'r ())) -> A`
+              found fn pointer `fn(for<'r> fn((), (), &'r mut ())) -> A`
+
+error[E0053]: method `from` has an incompatible type for trait
+  --> $DIR/issue-90444.rs:11:16
+   |
+LL |     fn from(_: fn((), (), u64)) -> Self {
+   |                ^^^^^^^^^^^^^^^
+   |                |
+   |                expected `u32`, found `u64`
+   |                help: change the parameter type to match the trait: `fn((), (), u32)`
+   |
+   = note: expected fn pointer `fn(fn((), (), u32)) -> B`
+              found fn pointer `fn(fn((), (), u64)) -> B`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/src/test/ui/conditional-compilation/issue-34028.rs b/src/test/ui/conditional-compilation/issue-34028.rs
new file mode 100644 (file)
index 0000000..d761c0c
--- /dev/null
@@ -0,0 +1,10 @@
+// check-pass
+
+macro_rules! m {
+    () => { #[cfg(any())] fn f() {} }
+}
+
+trait T {}
+impl T for () { m!(); }
+
+fn main() {}
diff --git a/src/test/ui/const-generics/auxiliary/legacy-const-generics.rs b/src/test/ui/const-generics/auxiliary/legacy-const-generics.rs
new file mode 100644 (file)
index 0000000..67352a2
--- /dev/null
@@ -0,0 +1,6 @@
+#![feature(rustc_attrs)]
+
+#[rustc_legacy_const_generics(1)]
+pub fn foo<const Y: usize>(x: usize, z: usize) -> [usize; 3] {
+    [x, Y, z]
+}
diff --git a/src/test/ui/const-generics/legacy-const-generics-bad.rs b/src/test/ui/const-generics/legacy-const-generics-bad.rs
new file mode 100644 (file)
index 0000000..538eee3
--- /dev/null
@@ -0,0 +1,16 @@
+// aux-build:legacy-const-generics.rs
+
+extern crate legacy_const_generics;
+
+fn foo<const N: usize>() {
+    let a = 1;
+    legacy_const_generics::foo(0, a, 2);
+    //~^ ERROR attempt to use a non-constant value in a constant
+
+    legacy_const_generics::foo(0, N, 2);
+
+    legacy_const_generics::foo(0, N + 1, 2);
+    //~^ ERROR generic parameters may not be used in const operations
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/legacy-const-generics-bad.stderr b/src/test/ui/const-generics/legacy-const-generics-bad.stderr
new file mode 100644 (file)
index 0000000..3c78dd6
--- /dev/null
@@ -0,0 +1,20 @@
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/legacy-const-generics-bad.rs:7:35
+   |
+LL |     let a = 1;
+   |     ----- help: consider using `const` instead of `let`: `const a`
+LL |     legacy_const_generics::foo(0, a, 2);
+   |                                   ^ non-constant value
+
+error: generic parameters may not be used in const operations
+  --> $DIR/legacy-const-generics-bad.rs:12:35
+   |
+LL |     legacy_const_generics::foo(0, N + 1, 2);
+   |                                   ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0435`.
diff --git a/src/test/ui/const-generics/legacy-const-generics.rs b/src/test/ui/const-generics/legacy-const-generics.rs
new file mode 100644 (file)
index 0000000..9abc72d
--- /dev/null
@@ -0,0 +1,18 @@
+// aux-build:legacy-const-generics.rs
+// run-pass
+
+#![feature(rustc_attrs)]
+
+extern crate legacy_const_generics;
+
+#[rustc_legacy_const_generics(1)]
+pub fn bar<const Y: usize>(x: usize, z: usize) -> [usize; 3] {
+    [x, Y, z]
+}
+
+fn main() {
+    assert_eq!(legacy_const_generics::foo(0 + 0, 1 + 1, 2 + 2), [0, 2, 4]);
+    assert_eq!(legacy_const_generics::foo::<{1 + 1}>(0 + 0, 2 + 2), [0, 2, 4]);
+    // FIXME: Only works cross-crate
+    //assert_eq!(bar(0, 1, 2), [0, 1, 2]);
+}
index fa9542f93a36ce67cf62727a2385a64db846182b..b46ca6ba6df5464a5137e942b743cc5143e2b4cb 100644 (file)
@@ -1,3 +1,5 @@
+// needs-asm-support
+
 #![feature(asm)]
 
 const _: () = unsafe { asm!("nop") };
index f38044a290b631da4b46675ee0b92676a415c30e..65a828d118c0cdc70a2e487d7d4f0873fde6c47b 100644 (file)
@@ -1,5 +1,5 @@
 error[E0015]: inline assembly is not allowed in constants
-  --> $DIR/inline_asm.rs:3:24
+  --> $DIR/inline_asm.rs:5:24
    |
 LL | const _: () = unsafe { asm!("nop") };
    |                        ^^^^^^^^^^^
diff --git a/src/test/ui/consts/issue-13902.rs b/src/test/ui/consts/issue-13902.rs
new file mode 100644 (file)
index 0000000..1afde0e
--- /dev/null
@@ -0,0 +1,16 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(non_camel_case_types)]
+
+const JSVAL_TAG_CLEAR: u32 = 0xFFFFFF80;
+const JSVAL_TYPE_INT32: u8 = 0x01;
+const JSVAL_TYPE_UNDEFINED: u8 = 0x02;
+#[repr(u32)]
+enum ValueTag {
+    JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | (JSVAL_TYPE_INT32 as u32),
+    JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | (JSVAL_TYPE_UNDEFINED as u32),
+}
+
+fn main() {
+    let _ = ValueTag::JSVAL_TAG_INT32;
+}
diff --git a/src/test/ui/consts/issue-17074.rs b/src/test/ui/consts/issue-17074.rs
new file mode 100644 (file)
index 0000000..0ed8113
--- /dev/null
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(dead_code)]
+
+static X2: u64 = !0 as u16 as u64;
+static Y2: u64 = !0 as u32 as u64;
+const X: u64 = !0 as u16 as u64;
+const Y: u64 = !0 as u32 as u64;
+
+fn main() {
+    assert_eq!(match 1 {
+        X => unreachable!(),
+        Y => unreachable!(),
+        _ => 1
+    }, 1);
+}
diff --git a/src/test/ui/consts/issue-18294.rs b/src/test/ui/consts/issue-18294.rs
new file mode 100644 (file)
index 0000000..77355f0
--- /dev/null
@@ -0,0 +1,5 @@
+fn main() {
+    const X: u32 = 1;
+    const Y: usize = unsafe { &X as *const u32 as usize }; //~ ERROR pointers cannot be cast to integers
+    println!("{}", Y);
+}
diff --git a/src/test/ui/consts/issue-18294.stderr b/src/test/ui/consts/issue-18294.stderr
new file mode 100644 (file)
index 0000000..e0cbd2a
--- /dev/null
@@ -0,0 +1,11 @@
+error: pointers cannot be cast to integers during const eval
+  --> $DIR/issue-18294.rs:3:31
+   |
+LL |     const Y: usize = unsafe { &X as *const u32 as usize };
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: at compile-time, pointers do not have an integer value
+   = note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/consts/issue-23968-const-not-overflow.rs b/src/test/ui/consts/issue-23968-const-not-overflow.rs
new file mode 100644 (file)
index 0000000..b959302
--- /dev/null
@@ -0,0 +1,12 @@
+// run-pass
+const U8_MAX_HALF: u8 = !0u8 / 2;
+const U16_MAX_HALF: u16 = !0u16 / 2;
+const U32_MAX_HALF: u32 = !0u32 / 2;
+const U64_MAX_HALF: u64 = !0u64 / 2;
+
+fn main() {
+    assert_eq!(U8_MAX_HALF, 0x7f);
+    assert_eq!(U16_MAX_HALF, 0x7fff);
+    assert_eq!(U32_MAX_HALF, 0x7fff_ffff);
+    assert_eq!(U64_MAX_HALF, 0x7fff_ffff_ffff_ffff);
+}
diff --git a/src/test/ui/consts/issue-37550-1.rs b/src/test/ui/consts/issue-37550-1.rs
new file mode 100644 (file)
index 0000000..35b63bd
--- /dev/null
@@ -0,0 +1,6 @@
+const fn x() {
+    let t = true;
+    let x = || t; //~ ERROR function pointer
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/issue-37550-1.stderr b/src/test/ui/consts/issue-37550-1.stderr
new file mode 100644 (file)
index 0000000..f66d706
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: function pointers cannot appear in constant functions
+  --> $DIR/issue-37550-1.rs:3:9
+   |
+LL |     let x = || t;
+   |         ^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_fn_ptr_basics)]` 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/consts/issue-37991.rs b/src/test/ui/consts/issue-37991.rs
new file mode 100644 (file)
index 0000000..a6ac4d5
--- /dev/null
@@ -0,0 +1,17 @@
+// run-pass
+
+const fn foo() -> i64 {
+    3
+}
+
+const fn bar(x: i64) -> i64 {
+    x*2
+}
+
+fn main() {
+    let val = &(foo() % 2);
+    assert_eq!(*val, 1);
+
+    let val2 = &(bar(1+1) % 3);
+    assert_eq!(*val2, 1);
+}
index 99926532247ab1c1e5d7431feea83a4983c814be..6830b23cfa345eeb6ea83e49e8a156f107aaee53 100644 (file)
@@ -39,6 +39,8 @@ pub const fn promote_union() {
     let _val: &'static _ = &(Cell::new(1), 2).1; //~ ERROR temporary value dropped while borrowed
 };
 
+const TEST_DROP: String = String::new();
+
 fn main() {
     // We must not promote things with interior mutability. Not even if we "project it away".
     let _val: &'static _ = &(Cell::new(1), 2).0; //~ ERROR temporary value dropped while borrowed
@@ -50,4 +52,17 @@ fn main() {
     let _val: &'static _ = &(1%0); //~ ERROR temporary value dropped while borrowed
     let _val: &'static _ = &(1%(1-1)); //~ ERROR temporary value dropped while borrowed
     let _val: &'static _ = &([1,2,3][4]+1); //~ ERROR temporary value dropped while borrowed
+
+    // No promotion of temporaries that need to be dropped.
+    let _val: &'static _ = &TEST_DROP;
+    //~^ ERROR temporary value dropped while borrowed
+    let _val: &'static _ = &&TEST_DROP;
+    //~^ ERROR temporary value dropped while borrowed
+    //~| ERROR temporary value dropped while borrowed
+    let _val: &'static _ = &(&TEST_DROP,);
+    //~^ ERROR temporary value dropped while borrowed
+    //~| ERROR temporary value dropped while borrowed
+    let _val: &'static _ = &[&TEST_DROP; 1];
+    //~^ ERROR temporary value dropped while borrowed
+    //~| ERROR temporary value dropped while borrowed
 }
index 932109bd86dcfa6a957d09ef9a943ae358b5b970..0d0b0f9c689b5b6593d007015efb60d00f71fba3 100644 (file)
@@ -59,7 +59,7 @@ LL | };
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promote-not.rs:44:29
+  --> $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
@@ -70,7 +70,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promote-not.rs:45:29
+  --> $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
@@ -81,7 +81,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promote-not.rs:48:29
+  --> $DIR/promote-not.rs:50:29
    |
 LL |     let _val: &'static _ = &(1/0);
    |               ----------    ^^^^^ creates a temporary which is freed while still in use
@@ -92,7 +92,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promote-not.rs:49:29
+  --> $DIR/promote-not.rs:51:29
    |
 LL |     let _val: &'static _ = &(1/(1-1));
    |               ----------    ^^^^^^^^^ creates a temporary which is freed while still in use
@@ -103,7 +103,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promote-not.rs:50:29
+  --> $DIR/promote-not.rs:52:29
    |
 LL |     let _val: &'static _ = &(1%0);
    |               ----------    ^^^^^ creates a temporary which is freed while still in use
@@ -114,26 +114,102 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promote-not.rs:51:29
+  --> $DIR/promote-not.rs:53:29
    |
 LL |     let _val: &'static _ = &(1%(1-1));
    |               ----------    ^^^^^^^^^ creates a temporary which is freed while still in use
    |               |
    |               type annotation requires that borrow lasts for `'static`
-LL |     let _val: &'static _ = &([1,2,3][4]+1);
+...
 LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promote-not.rs:52:29
+  --> $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
    |               |
    |               type annotation requires that borrow lasts for `'static`
+...
+LL | }
+   | - temporary value is freed at the end of this statement
+
+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
+   |               |
+   |               type annotation requires that borrow lasts for `'static`
+...
+LL | }
+   | - temporary value is freed at the end of this statement
+
+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
+   |               |
+   |               type annotation requires that borrow lasts for `'static`
+...
+LL | }
+   | - temporary value is freed at the end of this statement
+
+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
+   |               |
+   |               type annotation requires that borrow lasts for `'static`
+...
+LL | }
+   | - temporary value is freed at the end of this statement
+
+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
+   |               |
+   |               type annotation requires that borrow lasts for `'static`
+...
 LL | }
    | - temporary value is freed at the end of this statement
 
-error: aborting due to 13 previous errors
+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
+   |               |
+   |               type annotation requires that borrow lasts for `'static`
+...
+LL | }
+   | - temporary value is freed at the end of this statement
+
+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
+   |               |
+   |               type annotation requires that borrow lasts for `'static`
+...
+LL | }
+   | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/promote-not.rs:65:31
+   |
+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
+   |               type annotation requires that borrow lasts for `'static`
+
+error: aborting due to 20 previous errors
 
 For more information about this error, try `rustc --explain E0716`.
index cedead00fec970e80fef71bf41e80ceebd3a7e01..f74a25a346fda1d3dbee947117bf3cd8390f951f 100644 (file)
@@ -2,6 +2,7 @@
 #![feature(const_mut_refs)]
 #![feature(const_precise_live_drops)]
 #![feature(const_swap)]
+#![feature(raw_ref_op)]
 
 // Mutable borrow of a field with drop impl.
 pub const fn f() {
@@ -42,3 +43,22 @@ pub const fn g2<T>() {
     let _ = x.is_some();
     let _y = x; //~ ERROR destructors cannot be evaluated
 }
+
+// Mutable raw reference to a Drop type.
+pub const fn address_of_mut() {
+    let mut x: Option<String> = None; //~ ERROR destructors cannot be evaluated
+    &raw mut x;
+
+    let mut y: Option<String> = None; //~ ERROR destructors cannot be evaluated
+    std::ptr::addr_of_mut!(y);
+}
+
+// Const raw reference to a Drop type. Conservatively assumed to allow mutation
+// until resolution of https://github.com/rust-lang/rust/issues/56604.
+pub const fn address_of_const() {
+    let x: Option<String> = None; //~ ERROR destructors cannot be evaluated
+    &raw const x;
+
+    let y: Option<String> = None; //~ ERROR destructors cannot be evaluated
+    std::ptr::addr_of!(y);
+}
index aa6ed465594e33cf613aeb7afbda8e20ab971710..713df12b7a55f5e4b12a4da0938f37d178e56371 100644 (file)
@@ -1,33 +1,57 @@
 error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/qualif-indirect-mutation-fail.rs:8:9
+  --> $DIR/qualif-indirect-mutation-fail.rs:9:9
    |
 LL |     let mut a: (u32, Option<String>) = (0, None);
    |         ^^^^^ constant functions cannot evaluate destructors
 
 error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/qualif-indirect-mutation-fail.rs:14:9
+  --> $DIR/qualif-indirect-mutation-fail.rs:15:9
    |
 LL |     let mut x = None;
    |         ^^^^^ constants cannot evaluate destructors
 
 error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/qualif-indirect-mutation-fail.rs:30:9
+  --> $DIR/qualif-indirect-mutation-fail.rs:31:9
    |
 LL |     let _z = x;
    |         ^^ constants cannot evaluate destructors
 
 error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/qualif-indirect-mutation-fail.rs:35:9
+  --> $DIR/qualif-indirect-mutation-fail.rs:36:9
    |
 LL |     let x: Option<T> = None;
    |         ^ constant functions cannot evaluate destructors
 
 error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/qualif-indirect-mutation-fail.rs:43:9
+  --> $DIR/qualif-indirect-mutation-fail.rs:44:9
    |
 LL |     let _y = x;
    |         ^^ constant functions cannot evaluate destructors
 
-error: aborting due to 5 previous errors
+error[E0493]: destructors cannot be evaluated at compile-time
+  --> $DIR/qualif-indirect-mutation-fail.rs:52:9
+   |
+LL |     let mut y: Option<String> = None;
+   |         ^^^^^ constant functions cannot evaluate destructors
+
+error[E0493]: destructors cannot be evaluated at compile-time
+  --> $DIR/qualif-indirect-mutation-fail.rs:49:9
+   |
+LL |     let mut x: Option<String> = None;
+   |         ^^^^^ constant functions cannot evaluate destructors
+
+error[E0493]: destructors cannot be evaluated at compile-time
+  --> $DIR/qualif-indirect-mutation-fail.rs:62:9
+   |
+LL |     let y: Option<String> = None;
+   |         ^ constant functions cannot evaluate destructors
+
+error[E0493]: destructors cannot be evaluated at compile-time
+  --> $DIR/qualif-indirect-mutation-fail.rs:59:9
+   |
+LL |     let x: Option<String> = None;
+   |         ^ constant functions cannot evaluate destructors
+
+error: aborting due to 9 previous errors
 
 For more information about this error, try `rustc --explain E0493`.
index 35a9b70a5f6f1f9339b6d126d00e45db3b196de6..06af6a03b8f60d86d66b042c4888315a7a466b57 100644 (file)
@@ -3,6 +3,7 @@
 #![feature(const_mut_refs)]
 #![feature(const_precise_live_drops)]
 
+// Mutable reference allows only mutation of !Drop place.
 pub const fn f() {
     let mut x: (Option<String>, u32) = (None, 0);
     let mut a = 10;
@@ -10,7 +11,14 @@ pub const fn f() {
     x.1 = a;
 }
 
+// Mutable reference allows only mutation of !Drop place.
 pub const fn g() {
     let mut a: (u32, Option<String>) = (0, None);
     let _ = &mut a.0;
 }
+
+// Shared reference does not allow for mutation.
+pub const fn h() {
+    let x: Option<String> = None;
+    let _ = &x;
+}
diff --git a/src/test/ui/crate-loading/auxiliary/libfoo.rlib b/src/test/ui/crate-loading/auxiliary/libfoo.rlib
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/test/ui/crate-loading/invalid-rlib.rs b/src/test/ui/crate-loading/invalid-rlib.rs
new file mode 100644 (file)
index 0000000..77c2909
--- /dev/null
@@ -0,0 +1,8 @@
+// compile-flags: --crate-type lib --extern foo={{src-base}}/crate-loading/auxiliary/libfoo.rlib
+// normalize-stderr-test: "failed to mmap file '.*auxiliary/libfoo.rlib':.*" -> "failed to mmap file 'auxiliary/libfoo.rlib'"
+// don't emit warn logging, it's basically the same as the errors and it's annoying to normalize
+// rustc-env:RUSTC_LOG=error
+// edition:2018
+#![no_std]
+use ::foo; //~ ERROR invalid metadata files for crate `foo`
+//~| NOTE failed to mmap file
diff --git a/src/test/ui/crate-loading/invalid-rlib.stderr b/src/test/ui/crate-loading/invalid-rlib.stderr
new file mode 100644 (file)
index 0000000..b2c79f7
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0786]: found invalid metadata files for crate `foo`
+  --> $DIR/invalid-rlib.rs:7:7
+   |
+LL | use ::foo;
+   |       ^^^
+   |
+   = note: failed to mmap file 'auxiliary/libfoo.rlib'
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0786`.
diff --git a/src/test/ui/deprecation/try-macro-suggestion.rs b/src/test/ui/deprecation/try-macro-suggestion.rs
new file mode 100644 (file)
index 0000000..635ceac
--- /dev/null
@@ -0,0 +1,9 @@
+// compile-flags: --edition 2018
+fn foo() -> Result<(), ()> {
+    Ok(try!()); //~ ERROR use of deprecated `try` macro
+    Ok(try!(Ok(()))) //~ ERROR use of deprecated `try` macro
+}
+
+fn main() {
+    let _ = foo();
+}
diff --git a/src/test/ui/deprecation/try-macro-suggestion.stderr b/src/test/ui/deprecation/try-macro-suggestion.stderr
new file mode 100644 (file)
index 0000000..c7dde7e
--- /dev/null
@@ -0,0 +1,31 @@
+error: use of deprecated `try` macro
+  --> $DIR/try-macro-suggestion.rs:3:8
+   |
+LL |     Ok(try!());
+   |        ^^^^^^
+   |
+   = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated
+help: you can still access the deprecated `try!()` macro using the "raw identifier" syntax
+   |
+LL |     Ok(r#try!());
+   |        ++
+
+error: use of deprecated `try` macro
+  --> $DIR/try-macro-suggestion.rs:4:8
+   |
+LL |     Ok(try!(Ok(())))
+   |        ^^^^^^^^^^^^
+   |
+   = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated
+help: you can use the `?` operator instead
+   |
+LL -     Ok(try!(Ok(())))
+LL +     Ok(Ok(())?)
+   | 
+help: alternatively, you can still access the deprecated `try!()` macro using the "raw identifier" syntax
+   |
+LL |     Ok(r#try!(Ok(())))
+   |        ++
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/deriving/issue-19358.rs b/src/test/ui/deriving/issue-19358.rs
new file mode 100644 (file)
index 0000000..3970a41
--- /dev/null
@@ -0,0 +1,23 @@
+// run-pass
+
+#![allow(dead_code)]
+
+trait Trait { fn dummy(&self) { } }
+
+#[derive(Debug)]
+struct Foo<T: Trait> {
+    foo: T,
+}
+
+#[derive(Debug)]
+struct Bar<T> where T: Trait {
+    bar: T,
+}
+
+impl Trait for isize {}
+
+fn main() {
+    let a = Foo { foo: 12 };
+    let b = Bar { bar: 12 };
+    println!("{:?} {:?}", a, b);
+}
diff --git a/src/test/ui/deriving/issue-58319.rs b/src/test/ui/deriving/issue-58319.rs
new file mode 100644 (file)
index 0000000..757307d
--- /dev/null
@@ -0,0 +1,621 @@
+// run-pass
+fn main() {}
+#[derive(Clone)]
+pub struct Little;
+#[derive(Clone)]
+pub struct Big(
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+    Little,
+);
diff --git a/src/test/ui/diverging-tuple-parts-39485.rs b/src/test/ui/diverging-tuple-parts-39485.rs
deleted file mode 100644 (file)
index 0cde611..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// After #39485, this test used to pass, but that change was reverted
-// due to numerous inference failures like #39808, so it now fails
-// again. #39485 made it so that diverging types never propagate
-// upward; but we now do propagate such types upward in many more
-// cases.
-
-fn g() {
-    &panic!() //~ ERROR mismatched types
-}
-
-fn f() -> isize {
-    (return 1, return 2) //~ ERROR mismatched types
-}
-
-fn main() {}
diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr
deleted file mode 100644 (file)
index 32967b3..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/diverging-tuple-parts-39485.rs:8:5
-   |
-LL |     &panic!()
-   |     ^^^^^^^^^ expected `()`, found reference
-   |
-   = note: expected unit type `()`
-              found reference `&_`
-help: try adding a return type
-   |
-LL | fn g() -> &_ {
-   |        +++++
-help: consider removing the borrow
-   |
-LL -     &panic!()
-LL +     panic!()
-   | 
-
-error[E0308]: mismatched types
-  --> $DIR/diverging-tuple-parts-39485.rs:12:5
-   |
-LL | fn f() -> isize {
-   |           ----- expected `isize` because of return type
-LL |     (return 1, return 2)
-   |     ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found tuple
-   |
-   = note: expected type `isize`
-             found tuple `(!, !)`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/drop/issue-35546.rs b/src/test/ui/drop/issue-35546.rs
new file mode 100644 (file)
index 0000000..004679a
--- /dev/null
@@ -0,0 +1,20 @@
+// build-pass
+#![allow(dead_code)]
+// Regression test for #35546. Check that we are able to codegen
+// this. Before we had problems because of the drop glue signature
+// around dropping a trait object (specifically, when dropping the
+// `value` field of `Node<Send>`).
+
+struct Node<T: ?Sized + Send> {
+    next: Option<Box<Node<dyn Send>>>,
+    value: T,
+}
+
+fn clear(head: &mut Option<Box<Node<dyn Send>>>) {
+    match head.take() {
+        Some(node) => *head = node.next,
+        None => (),
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/drop/terminate-in-initializer.rs b/src/test/ui/drop/terminate-in-initializer.rs
new file mode 100644 (file)
index 0000000..c9cb932
--- /dev/null
@@ -0,0 +1,33 @@
+// run-pass
+// ignore-emscripten no threads support
+
+// Issue #787
+// Don't try to clean up uninitialized locals
+
+
+use std::thread;
+
+fn test_break() { loop { let _x: Box<isize> = break; } }
+
+fn test_cont() { let mut i = 0; while i < 1 { i += 1; let _x: Box<isize> = continue; } }
+
+fn test_ret() { let _x: Box<isize> = return; }
+
+fn test_panic() {
+    fn f() { let _x: Box<isize> = panic!(); }
+    thread::spawn(move|| f() ).join().unwrap_err();
+}
+
+fn test_panic_indirect() {
+    fn f() -> ! { panic!(); }
+    fn g() { let _x: Box<isize> = f(); }
+    thread::spawn(move|| g() ).join().unwrap_err();
+}
+
+pub fn main() {
+    test_break();
+    test_cont();
+    test_ret();
+    test_panic();
+    test_panic_indirect();
+}
diff --git a/src/test/ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs b/src/test/ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs
new file mode 100644 (file)
index 0000000..23fd86a
--- /dev/null
@@ -0,0 +1,46 @@
+// run-pass
+
+// Demonstrate the use of the unguarded escape hatch with a type param in negative position
+// to assert that destructor will not access any dead data.
+//
+// Compare with ui/span/issue28498-reject-lifetime-param.rs
+
+// Demonstrate that a type param in negative position causes dropck to reject code
+// that might indirectly access previously dropped value.
+//
+// Compare with run-pass/issue28498-ugeh-with-passed-to-fn.rs
+
+#![feature(dropck_eyepatch)]
+
+#[derive(Debug)]
+struct ScribbleOnDrop(String);
+
+impl Drop for ScribbleOnDrop {
+    fn drop(&mut self) {
+        self.0 = format!("DROPPED");
+    }
+}
+
+struct Foo<T>(u32, T, Box<for <'r> fn(&'r T) -> String>);
+
+unsafe impl<#[may_dangle] T> Drop for Foo<T> {
+    fn drop(&mut self) {
+        // Use of `may_dangle` is sound, because destructor never passes a `self.1`
+        // to the callback (in `self.2`) despite having it available.
+        println!("Dropping Foo({}, _)", self.0);
+    }
+}
+
+fn callback(s: & &ScribbleOnDrop) -> String { format!("{:?}", s) }
+
+fn main() {
+    let (last_dropped, foo0);
+    let (foo1, first_dropped);
+
+    last_dropped = ScribbleOnDrop(format!("last"));
+    first_dropped = ScribbleOnDrop(format!("first"));
+    foo0 = Foo(0, &last_dropped, Box::new(callback));
+    foo1 = Foo(1, &first_dropped, Box::new(callback));
+
+    println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1);
+}
diff --git a/src/test/ui/editions-crate-root-2015.rs b/src/test/ui/editions-crate-root-2015.rs
deleted file mode 100644 (file)
index 4c890e3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// edition:2015
-
-mod inner {
-    fn global_inner(_: ::nonexistant::Foo) {
-        //~^ ERROR failed to resolve: maybe a missing crate `nonexistant`?
-    }
-    fn crate_inner(_: crate::nonexistant::Foo) {
-        //~^ ERROR failed to resolve: maybe a missing crate `nonexistant`?
-    }
-
-    fn bare_global(_: ::nonexistant) {
-        //~^ ERROR cannot find type `nonexistant` in the crate root
-    }
-    fn bare_crate(_: crate::nonexistant) {
-        //~^ ERROR cannot find type `nonexistant` in the crate root
-    }
-}
-
-fn main() {
-
-}
diff --git a/src/test/ui/editions-crate-root-2015.stderr b/src/test/ui/editions-crate-root-2015.stderr
deleted file mode 100644 (file)
index f8d65fe..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-error[E0433]: failed to resolve: maybe a missing crate `nonexistant`?
-  --> $DIR/editions-crate-root-2015.rs:4:26
-   |
-LL |     fn global_inner(_: ::nonexistant::Foo) {
-   |                          ^^^^^^^^^^^ maybe a missing crate `nonexistant`?
-
-error[E0433]: failed to resolve: maybe a missing crate `nonexistant`?
-  --> $DIR/editions-crate-root-2015.rs:7:30
-   |
-LL |     fn crate_inner(_: crate::nonexistant::Foo) {
-   |                              ^^^^^^^^^^^ maybe a missing crate `nonexistant`?
-
-error[E0412]: cannot find type `nonexistant` in the crate root
-  --> $DIR/editions-crate-root-2015.rs:11:25
-   |
-LL |     fn bare_global(_: ::nonexistant) {
-   |                         ^^^^^^^^^^^ not found in the crate root
-
-error[E0412]: cannot find type `nonexistant` in the crate root
-  --> $DIR/editions-crate-root-2015.rs:14:29
-   |
-LL |     fn bare_crate(_: crate::nonexistant) {
-   |                             ^^^^^^^^^^^ not found in the crate root
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0412, E0433.
-For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/editions/epoch-gate-feature.rs b/src/test/ui/editions/epoch-gate-feature.rs
new file mode 100644 (file)
index 0000000..5f7feb5
--- /dev/null
@@ -0,0 +1,15 @@
+// run-pass
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+// Checks if the correct registers are being used to pass arguments
+// when the sysv64 ABI is specified.
+
+#![feature(rust_2018_preview)]
+
+pub trait Foo {}
+
+// should compile without the dyn trait feature flag
+fn foo(x: &dyn Foo) {}
+
+pub fn main() {}
diff --git a/src/test/ui/enum-discriminant/issue-51582.rs b/src/test/ui/enum-discriminant/issue-51582.rs
new file mode 100644 (file)
index 0000000..40a70c6
--- /dev/null
@@ -0,0 +1,18 @@
+// run-pass
+#![feature(core_intrinsics)]
+
+#[repr(i8)]
+pub enum Enum {
+    VariantA,
+    VariantB,
+}
+
+fn make_b() -> Enum { Enum::VariantB }
+
+fn main() {
+    assert_eq!(1, make_b() as i8);
+    assert_eq!(1, make_b() as u8);
+    assert_eq!(1, make_b() as i32);
+    assert_eq!(1, make_b() as u32);
+    assert_eq!(1, std::intrinsics::discriminant_value(&make_b()));
+}
diff --git a/src/test/ui/enum/issue-42747.rs b/src/test/ui/enum/issue-42747.rs
new file mode 100644 (file)
index 0000000..fec6587
--- /dev/null
@@ -0,0 +1,46 @@
+// run-pass
+macro_rules! fooN {
+    ($cur:ident $prev:ty) => {
+        #[allow(dead_code)]
+        enum $cur {
+            Empty,
+            First($prev),
+            Second($prev),
+            Third($prev),
+            Fourth($prev),
+        }
+    }
+}
+
+fooN!(Foo0 ());
+fooN!(Foo1 Foo0);
+fooN!(Foo2 Foo1);
+fooN!(Foo3 Foo2);
+fooN!(Foo4 Foo3);
+fooN!(Foo5 Foo4);
+fooN!(Foo6 Foo5);
+fooN!(Foo7 Foo6);
+fooN!(Foo8 Foo7);
+fooN!(Foo9 Foo8);
+fooN!(Foo10 Foo9);
+fooN!(Foo11 Foo10);
+fooN!(Foo12 Foo11);
+fooN!(Foo13 Foo12);
+fooN!(Foo14 Foo13);
+fooN!(Foo15 Foo14);
+fooN!(Foo16 Foo15);
+fooN!(Foo17 Foo16);
+fooN!(Foo18 Foo17);
+fooN!(Foo19 Foo18);
+fooN!(Foo20 Foo19);
+fooN!(Foo21 Foo20);
+fooN!(Foo22 Foo21);
+fooN!(Foo23 Foo22);
+fooN!(Foo24 Foo23);
+fooN!(Foo25 Foo24);
+fooN!(Foo26 Foo25);
+fooN!(Foo27 Foo26);
+
+fn main() {
+    let _foo = Foo27::Empty;
+}
diff --git a/src/test/ui/epoch-gate-feature.rs b/src/test/ui/epoch-gate-feature.rs
deleted file mode 100644 (file)
index 5f7feb5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-
-#![allow(dead_code)]
-#![allow(unused_variables)]
-// Checks if the correct registers are being used to pass arguments
-// when the sysv64 ABI is specified.
-
-#![feature(rust_2018_preview)]
-
-pub trait Foo {}
-
-// should compile without the dyn trait feature flag
-fn foo(x: &dyn Foo) {}
-
-pub fn main() {}
index 3909b5301ade5ab672919e9d373c6692200b9d87..22792c11366ba3dda38e1d4102b264d8f2e661c9 100644 (file)
@@ -1,5 +1,5 @@
 // run-pass
-// only-i686
+// only-x86
 
 trait A {
     extern "fastcall" fn test1(i: i32);
index 8ce94aa71aae6e9172fc0fbfd7be185e49a22e75..717df57ec48485d2b57e56a729927dca03abfb38 100644 (file)
@@ -1,5 +1,5 @@
 // run-pass
-// only-i686
+// only-x86
 
 #![feature(abi_thiscall)]
 
index f625eb0890f05dc5efbd4b400f904b3038be6a0c..a283573c9fbd11afa437bf2884445766af3ecdbb 100644 (file)
@@ -1,7 +1,7 @@
 // run-pass
 // revisions: x64 x32
 // [x64]only-x86_64
-// [x32]only-i686
+// [x32]only-x86
 
 #![feature(abi_vectorcall)]
 
diff --git a/src/test/ui/extern/issue-28324.mir.stderr b/src/test/ui/extern/issue-28324.mir.stderr
new file mode 100644 (file)
index 0000000..aff8bf7
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/issue-28324.rs:8:24
+   |
+LL | pub static BAZ: u32 = *&error_message_count;
+   |                        ^^^^^^^^^^^^^^^^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/extern/issue-28324.rs b/src/test/ui/extern/issue-28324.rs
new file mode 100644 (file)
index 0000000..fbe83e3
--- /dev/null
@@ -0,0 +1,11 @@
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+extern "C" {
+    static error_message_count: u32;
+}
+
+pub static BAZ: u32 = *&error_message_count;
+//~^ ERROR use of extern static is unsafe and requires
+
+fn main() {}
diff --git a/src/test/ui/extern/issue-28324.thir.stderr b/src/test/ui/extern/issue-28324.thir.stderr
new file mode 100644 (file)
index 0000000..c696c35
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/issue-28324.rs:8:25
+   |
+LL | pub static BAZ: u32 = *&error_message_count;
+   |                         ^^^^^^^^^^^^^^^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/feature-gates/feature-gate-asm_const.rs b/src/test/ui/feature-gates/feature-gate-asm_const.rs
new file mode 100644 (file)
index 0000000..c152b54
--- /dev/null
@@ -0,0 +1,10 @@
+// only-x86_64
+
+#![feature(asm)]
+
+fn main() {
+    unsafe {
+        asm!("mov eax, {}", const 123);
+        //~^ ERROR const operands for inline assembly are unstable
+    }
+}
diff --git a/src/test/ui/feature-gates/feature-gate-asm_const.stderr b/src/test/ui/feature-gates/feature-gate-asm_const.stderr
new file mode 100644 (file)
index 0000000..2851a9b
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: const operands for inline assembly are unstable
+  --> $DIR/feature-gate-asm_const.rs:7:29
+   |
+LL |         asm!("mov eax, {}", const 123);
+   |                             ^^^^^^^^^
+   |
+   = note: see issue #72016 <https://github.com/rust-lang/rust/issues/72016> for more information
+   = help: add `#![feature(asm_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/feature-gates/feature-gate-asm_experimental_arch.rs b/src/test/ui/feature-gates/feature-gate-asm_experimental_arch.rs
new file mode 100644 (file)
index 0000000..53e2a4d
--- /dev/null
@@ -0,0 +1,21 @@
+// compile-flags: --target mips-unknown-linux-gnu
+// needs-llvm-components: mips
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![crate_type = "rlib"]
+#![no_core]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+unsafe fn main() {
+    asm!("");
+    //~^ ERROR inline assembly is not stable yet on this architecture
+}
diff --git a/src/test/ui/feature-gates/feature-gate-asm_experimental_arch.stderr b/src/test/ui/feature-gates/feature-gate-asm_experimental_arch.stderr
new file mode 100644 (file)
index 0000000..1b4188a
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: inline assembly is not stable yet on this architecture
+  --> $DIR/feature-gate-asm_experimental_arch.rs:19:5
+   |
+LL |     asm!("");
+   |     ^^^^^^^^
+   |
+   = note: see issue #72016 <https://github.com/rust-lang/rust/issues/72016> for more information
+   = help: add `#![feature(asm_experimental_arch)]` 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-asm_sym.rs b/src/test/ui/feature-gates/feature-gate-asm_sym.rs
new file mode 100644 (file)
index 0000000..d89c7dd
--- /dev/null
@@ -0,0 +1,10 @@
+// only-x86_64
+
+#![feature(asm)]
+
+fn main() {
+    unsafe {
+        asm!("mov eax, {}", sym main);
+        //~^ ERROR sym operands for inline assembly are unstable
+    }
+}
diff --git a/src/test/ui/feature-gates/feature-gate-asm_sym.stderr b/src/test/ui/feature-gates/feature-gate-asm_sym.stderr
new file mode 100644 (file)
index 0000000..99b61b8
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: sym operands for inline assembly are unstable
+  --> $DIR/feature-gate-asm_sym.rs:7:29
+   |
+LL |         asm!("mov eax, {}", sym main);
+   |                             ^^^^^^^^
+   |
+   = note: see issue #72016 <https://github.com/rust-lang/rust/issues/72016> for more information
+   = help: add `#![feature(asm_sym)]` 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-relaxed_struct_unsize.rs b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.rs
deleted file mode 100644 (file)
index 0cfd0a0..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// Test that we allow unsizing even if there is an unchanged param in the
-// field getting unsized.
-struct A<T, U: ?Sized + 'static>(T, B<T, U>);
-struct B<T, U: ?Sized>(T, U);
-
-fn main() {
-    let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1]));
-    let y: &A<[u32; 1], [u32]> = &x; //~ ERROR mismatched types
-    assert_eq!(y.1.1.len(), 1);
-}
diff --git a/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr
deleted file mode 100644 (file)
index f62def4..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/feature-gate-relaxed_struct_unsize.rs:8:34
-   |
-LL |     let y: &A<[u32; 1], [u32]> = &x;
-   |            -------------------   ^^ expected slice `[u32]`, found array `[u32; 1]`
-   |            |
-   |            expected due to this
-   |
-   = note: expected reference `&A<[u32; 1], [u32]>`
-              found reference `&A<[u32; 1], [u32; 1]>`
-
-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/issue-51345.rs b/src/test/ui/for-loop-while/issue-51345.rs
new file mode 100644 (file)
index 0000000..15571e8
--- /dev/null
@@ -0,0 +1,8 @@
+// run-pass
+#![allow(unreachable_code)]
+
+fn main() {
+    let mut v = Vec::new();
+
+    loop { v.push(break) }
+}
diff --git a/src/test/ui/for-loop-while/long-while.rs b/src/test/ui/for-loop-while/long-while.rs
new file mode 100644 (file)
index 0000000..529cca7
--- /dev/null
@@ -0,0 +1,12 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+#![allow(unused_variables)]
+
+pub fn main() {
+    let mut i: isize = 0;
+    while i < 1000000 {
+        i += 1;
+        let x = 3;
+    }
+}
diff --git a/src/test/ui/foreign/nil-decl-in-foreign.rs b/src/test/ui/foreign/nil-decl-in-foreign.rs
new file mode 100644 (file)
index 0000000..f3be948
--- /dev/null
@@ -0,0 +1,14 @@
+// run-pass
+
+#![allow(improper_ctypes)]
+#![allow(dead_code)]
+// Issue #901
+// pretty-expanded FIXME #23616
+
+mod libc {
+    extern "C" {
+        pub fn printf(x: ());
+    }
+}
+
+pub fn main() {}
index 0944bf110c1b5211a74d70797d57535e1be0a576..5b94cdee7c9c7deea6fb73f325ec198a982ee5a4 100644 (file)
@@ -8,7 +8,7 @@
 // check that we don't normalize with trait defaults.
 
 trait Collection<T> {
-    type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter;
+    type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter, Self: 'iter;
     type Family: CollectionFamily;
     // Test associated type defaults with parameters
     type Sibling<U>: Collection<U> =
index f14c6dac1b1ed9d28436adfc09c4dd511baf5f68..b0f2fb3f567856e8d649f1c0ed7c3e0c4612081b 100644 (file)
@@ -8,7 +8,7 @@
 // run-pass
 
 trait Collection<T> {
-    type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter;
+    type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter, Self: 'iter;
     type Family: CollectionFamily;
     // Test associated type defaults with parameters
     type Sibling<U>: Collection<U> =
index 5d3a3a893527eec22a81d8e34129fc277116698e..d7c4dbda2644e68a6d31003e323d8a034d8ad1c9 100644 (file)
@@ -3,7 +3,7 @@
 #![feature(generic_associated_types)]
 
 pub trait X {
-    type Y<'a>;
+    type Y<'a> where Self: 'a;
     fn m(&self) -> Self::Y<'_>;
 }
 
index d238f53bde7bee4df9e2d9d28628c710c3478e31..568996e1a17aa4b8b199fad7414ed6c3b688ff17 100644 (file)
@@ -3,7 +3,7 @@
 #![feature(generic_associated_types)]
 
 trait Document {
-    type Cursor<'a>: DocCursor<'a>;
+    type Cursor<'a>: DocCursor<'a> where Self: 'a;
 
     fn cursor(&self) -> Self::Cursor<'_>;
 }
index 1dad856d5a370fd888f13e7b3e83cce8d46706ba..20c6924afa614d34d34858dd25de778fad604efa 100644 (file)
@@ -3,7 +3,7 @@
 pub trait SubTrait {}
 
 pub trait SuperTrait {
-    type SubType<'a>: SubTrait;
+    type SubType<'a>: SubTrait where Self: 'a;
 
     fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>;
 }
index 0a7eb5dde6009838b44af2b5c6ff9bc75bdb03bb..64eeec1b2fcbe39c2dfbf92460a60dac57f4ac67 100644 (file)
@@ -7,7 +7,7 @@ LL |     let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruc
 note: associated type defined here, with 1 lifetime parameter: `'a`
   --> $DIR/issue-76535.rs:6:10
    |
-LL |     type SubType<'a>: SubTrait;
+LL |     type SubType<'a>: SubTrait where Self: 'a;
    |          ^^^^^^^ --
 help: add missing lifetime argument
    |
@@ -25,7 +25,7 @@ note: for a trait to be "object safe" it needs to allow building a vtable to all
    |
 LL | pub trait SuperTrait {
    |           ---------- this trait cannot be made into an object...
-LL |     type SubType<'a>: SubTrait;
+LL |     type SubType<'a>: SubTrait where Self: 'a;
    |          ^^^^^^^ ...because it contains the generic associated type `SubType`
    = help: consider moving `SubType` to another trait
 
@@ -40,7 +40,7 @@ note: for a trait to be "object safe" it needs to allow building a vtable to all
    |
 LL | pub trait SuperTrait {
    |           ---------- this trait cannot be made into an object...
-LL |     type SubType<'a>: SubTrait;
+LL |     type SubType<'a>: SubTrait where Self: 'a;
    |          ^^^^^^^ ...because it contains the generic associated type `SubType`
    = help: consider moving `SubType` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` for `Box<SuperStruct>`
index 7f0ac348358840c6bc0975e954cc1238345933e1..47ef38ff45d65beadccc13496883013c7420e21d 100644 (file)
@@ -17,12 +17,12 @@ fn t(&'a self) -> &'a T {
 }
 
 trait MapLike<K, V> {
-    type VRefCont<'a>: RefCont<'a, V>;
+    type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
     fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>;
 }
 
 impl<K: Ord, V: 'static> MapLike<K, V> for std::collections::BTreeMap<K, V> {
-    type VRefCont<'a> = &'a V;
+    type VRefCont<'a> where Self: 'a = &'a V;
     fn get<'a>(&'a self, key: &K) -> Option<&'a V> {
         std::collections::BTreeMap::get(self, key)
     }
index b6f856a97e7257fcc8c5a9795e024846ff4159f9..8b6f9b866e5ef1559333c848e618ffbf80fbdb32 100644 (file)
@@ -7,7 +7,7 @@ LL |         as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
 note: associated type defined here, with 1 lifetime parameter: `'a`
   --> $DIR/issue-79422.rs:20:10
    |
-LL |     type VRefCont<'a>: RefCont<'a, V>;
+LL |     type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
    |          ^^^^^^^^ --
 help: add missing lifetime argument
    |
@@ -25,7 +25,7 @@ note: for a trait to be "object safe" it needs to allow building a vtable to all
    |
 LL | trait MapLike<K, V> {
    |       ------- this trait cannot be made into an object...
-LL |     type VRefCont<'a>: RefCont<'a, V>;
+LL |     type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
    |          ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
    = help: consider moving `VRefCont` to another trait
 
@@ -40,7 +40,7 @@ note: for a trait to be "object safe" it needs to allow building a vtable to all
    |
 LL | trait MapLike<K, V> {
    |       ------- this trait cannot be made into an object...
-LL |     type VRefCont<'a>: RefCont<'a, V>;
+LL |     type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
    |          ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
    = help: consider moving `VRefCont` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>` for `Box<BTreeMap<u8, u8>>`
index f1f05ea6627e8f9282564e85d5732af2eea4488e..0f62f83e2563b15935bce74fc968ec97c56941f7 100644 (file)
@@ -9,6 +9,7 @@ enum Either<L, R> {
 pub trait HasChildrenOf {
     type T;
     type TRef<'a>;
+    //~^ Missing required bounds
 
     fn ref_children<'a>(&'a self) -> Vec<Self::TRef<'a>>;
     fn take_children(self) -> Vec<Self::T>;
@@ -20,9 +21,9 @@ impl<Left, Right> HasChildrenOf for Either<Left, Right>
     Right: HasChildrenOf,
 {
     type T = Either<Left::T, Right::T>;
+    // We used to error below because the where clause doesn't match the trait.
+    // Now, we error early on the trait itself.
     type TRef<'a>
-    //~^ `impl` associated type signature
-    //~^^ `impl` associated type signature
     where
     <Left as HasChildrenOf>::T: 'a,
     <Right as HasChildrenOf>::T: 'a
index 648eff77d73bb876abde0e156833a300d6db1494..87dcd875de703b589d4be1477ed8446f9233eb1b 100644 (file)
@@ -1,32 +1,10 @@
-error: `impl` associated type signature for `TRef` doesn't match `trait` associated type signature
-  --> $DIR/issue-86787.rs:23:5
+error: Missing required bounds on TRef
+  --> $DIR/issue-86787.rs:11:5
    |
-LL |       type TRef<'a>;
-   |       -------------- expected
-...
-LL | /     type TRef<'a>
-LL | |
-LL | |
-LL | |     where
-LL | |     <Left as HasChildrenOf>::T: 'a,
-LL | |     <Right as HasChildrenOf>::T: 'a
-LL | |     = Either<&'a Left::T, &'a Right::T>;
-   | |________________________________________^ found
+LL |     type TRef<'a>;
+   |     ^^^^^^^^^^^^^-
+   |                  |
+   |                  help: add the required where clauses: `where Self: 'a`
 
-error: `impl` associated type signature for `TRef` doesn't match `trait` associated type signature
-  --> $DIR/issue-86787.rs:23:5
-   |
-LL |       type TRef<'a>;
-   |       -------------- expected
-...
-LL | /     type TRef<'a>
-LL | |
-LL | |
-LL | |     where
-LL | |     <Left as HasChildrenOf>::T: 'a,
-LL | |     <Right as HasChildrenOf>::T: 'a
-LL | |     = Either<&'a Left::T, &'a Right::T>;
-   | |________________________________________^ found
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
index 2e65af594a6bd545cfbe1cd066e4844625f1f4d3..df5586ed422f84f0491c3330ccc6e492b33f194c 100644 (file)
@@ -13,7 +13,8 @@ trait SearchableResource<Criteria> {
 trait SearchableResourceExt<Criteria>: SearchableResource<Criteria> {
     type Future<'f, A: 'f + ?Sized, B: 'f>: Future<Output = Result<Vec<A::SearchResult>, ()>> + 'f
     where
-        A: SearchableResource<B>;
+        A: SearchableResource<B>,
+        Self: 'f;
 
     fn search<'c>(&'c self, client: &'c ()) -> Self::Future<'c, Self, Criteria>;
 }
@@ -29,6 +30,7 @@ impl<T, Criteria> SearchableResourceExt<Criteria> for T
     type Future<'f, A, B: 'f>
     where
         A: SearchableResource<B> + ?Sized + 'f,
+        Self: 'f,
     = SearchFutureTy<'f, A, B>;
 
     fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> {
index 06af3f5ec96d65f2d7f5c3c6c9480bc30726c62a..8ee98201aba7a79ec6624e8aa626025e403d032d 100644 (file)
@@ -1,13 +1,14 @@
 #![feature(generic_associated_types)]
 
 trait GatTrait {
-    type Gat<'a>;
+    type Gat<'a> where Self: 'a;
 
     fn test(&self) -> Self::Gat<'_>;
 }
 
 trait SuperTrait<T>
 where
+    Self: 'static,
     for<'a> Self: GatTrait<Gat<'a> = &'a T>,
 {
     fn copy(&self) -> Self::Gat<'_> where T: Copy {
index cfbf3aaa4e65d556a156915c43e7c87aa74c32ea..5f769d799faa16ab547dfd1d80a3abf54fbd11b5 100644 (file)
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-88360.rs:14:9
+  --> $DIR/issue-88360.rs:15:9
    |
 LL | trait SuperTrait<T>
    |                  - this type parameter
diff --git a/src/test/ui/generic-associated-types/issue-88459.rs b/src/test/ui/generic-associated-types/issue-88459.rs
new file mode 100644 (file)
index 0000000..3b26a18
--- /dev/null
@@ -0,0 +1,19 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+trait Trait {
+    type Assoc<'a>;
+}
+
+fn f<T: Trait>(_: T, _: impl Fn(T::Assoc<'_>)) {}
+
+struct Type;
+
+impl Trait for Type {
+    type Assoc<'a> = ();
+}
+
+fn main() {
+    f(Type, |_|());
+}
index b976ee3261fcc7f9569d9fc2758dd50da656a0aa..bcbcfc18996375a47fe0dd4c6024512530ce2e18 100644 (file)
@@ -1,7 +1,7 @@
 #![feature(generic_associated_types)]
 
 pub trait X {
-    type Y<'a>;
+    type Y<'a> where Self: 'a;
     fn m(&self) -> Self::Y<'_>;
 }
 
diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.rs b/src/test/ui/generic-associated-types/self-outlives-lint.rs
new file mode 100644 (file)
index 0000000..af90d15
--- /dev/null
@@ -0,0 +1,173 @@
+#![feature(generic_associated_types)]
+
+// check-fail
+
+use std::fmt::Debug;
+
+// We have a `&'a self`, so we need a `Self: 'a`
+trait Iterable {
+    type Item<'x>;
+    //~^ Missing required bounds
+    fn iter<'a>(&'a self) -> Self::Item<'a>;
+}
+
+/*
+impl<T> Iterable for T {
+    type Item<'a> = &'a T;
+    fn iter<'a>(&'a self) -> Self::Item<'a> {
+        self
+    }
+}
+*/
+
+// We have a `&'a T`, so we need a `T: 'x`
+trait Deserializer<T> {
+    type Out<'x>;
+    //~^ Missing required bounds
+    fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a>;
+}
+
+/*
+impl<T> Deserializer<T> for () {
+    type Out<'a> = &'a T;
+    fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a> { input }
+}
+*/
+
+// We have a `&'b T` and a `'b: 'a`, so it is implied that `T: 'a`. Therefore, we need a `T: 'x`
+trait Deserializer2<T> {
+    type Out<'x>;
+    //~^ Missing required bounds
+    fn deserialize2<'a, 'b: 'a>(&self, input1: &'b T) -> Self::Out<'a>;
+}
+
+// We have a `&'a T` and a `&'b U`, so we need a `T: 'x` and a `U: 'y`
+trait Deserializer3<T, U> {
+    type Out<'x, 'y>;
+    //~^ Missing required bounds
+    fn deserialize2<'a, 'b>(&self, input: &'a T, input2: &'b U) -> Self::Out<'a, 'b>;
+}
+
+// `T` is a param on the function, so it can't be named by the associated type
+trait Deserializer4 {
+    type Out<'x>;
+    fn deserialize<'a, T>(&self, input: &'a T) -> Self::Out<'a>;
+}
+
+struct Wrap<T>(T);
+
+// We pass `Wrap<T>` and we see `&'z Wrap<T>`, so we require `D: 'x`
+trait Des {
+    type Out<'x, D>;
+    //~^ Missing required bounds
+    fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, Wrap<T>>;
+}
+/*
+impl Des for () {
+    type Out<'x, D> = &'x D; // Not okay
+    fn des<'a, T>(&self, data: &'a Wrap<T>) -> Self::Out<'a, Wrap<T>> {
+        data
+    }
+}
+*/
+
+// We have `T` and `'z` as GAT substs. Because of `&'z Wrap<T>`, there is an
+// implied bound that `T: 'z`, so we require `D: 'x`
+trait Des2 {
+    type Out<'x, D>;
+    //~^ Missing required bounds
+    fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, T>;
+}
+/*
+impl Des2 for () {
+    type Out<'x, D> = &'x D;
+    fn des<'a, T>(&self, data: &'a Wrap<T>) -> Self::Out<'a, T> {
+        &data.0
+    }
+}
+*/
+
+// We see `&'z T`, so we require `D: 'x`
+trait Des3 {
+    type Out<'x, D>;
+    //~^ Missing required bounds
+    fn des<'z, T>(&self, data: &'z T) -> Self::Out<'z, T>;
+}
+/*
+impl Des3 for () {
+    type Out<'x, D> = &'x D;
+    fn des<'a, T>(&self, data: &'a T) -> Self::Out<'a, T> {
+          data
+    }
+}
+*/
+
+// Similar case to before, except with GAT.
+trait NoGat<'a> {
+    type Bar;
+    fn method(&'a self) -> Self::Bar;
+}
+
+// Lifetime is not on function; except `Self: 'a`
+// FIXME: we require two bounds (`where Self: 'a, Self: 'b`) when we should only require one
+trait TraitLifetime<'a> {
+    type Bar<'b>;
+    //~^ Missing required bounds
+    fn method(&'a self) -> Self::Bar<'a>;
+}
+
+// Like above, but we have a where clause that can prove what we want
+// FIXME: we require two bounds (`where Self: 'a, Self: 'b`) when we should only require one
+trait TraitLifetimeWhere<'a> where Self: 'a {
+    type Bar<'b>;
+    //~^ Missing required bounds
+    fn method(&'a self) -> Self::Bar<'a>;
+}
+
+// Explicit bound instead of implicit; we want to still error
+trait ExplicitBound {
+    type Bar<'b>;
+    //~^ Missing required bounds
+    fn method<'b>(&self, token: &'b ()) -> Self::Bar<'b> where Self: 'b;
+}
+
+// The use of the GAT here is not in the return, we don't want to error
+trait NotInReturn {
+    type Bar<'b>;
+    fn method<'b>(&'b self) where Self::Bar<'b>: Debug;
+}
+
+// We obviously error for `Iterator`, but we should also error for `Item`
+trait IterableTwo {
+    type Item<'a>;
+    type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
+    //~^ Missing required bounds
+    fn iter<'a>(&'a self) -> Self::Iterator<'a>;
+}
+
+// We also should report region outlives clauses
+trait RegionOutlives {
+    type Bar<'a, 'b>;
+    //~^ Missing required bounds
+    fn foo<'x, 'y>(&self, input: &'x &'y ()) -> Self::Bar<'x, 'y>;
+}
+
+/*
+impl Foo for () {
+    type Bar<'a, 'b> = &'a &'b ();
+    fn foo<'x, 'y>(&self, input: &'x &'y ()) -> Self::Bar<'x, 'y> {
+        input
+    }
+}
+*/
+
+// If there are multiple methods that return the GAT, require a set of clauses
+// that can be satisfied by *all* methods
+trait MultipleMethods {
+    type Bar<'me>;
+
+    fn gimme<'a>(&'a self) -> Self::Bar<'a>;
+    fn gimme_default(&self) -> Self::Bar<'static>;
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.stderr b/src/test/ui/generic-associated-types/self-outlives-lint.stderr
new file mode 100644 (file)
index 0000000..bf85780
--- /dev/null
@@ -0,0 +1,98 @@
+error: Missing required bounds on Item
+  --> $DIR/self-outlives-lint.rs:9:5
+   |
+LL |     type Item<'x>;
+   |     ^^^^^^^^^^^^^-
+   |                  |
+   |                  help: add the required where clauses: `where Self: 'x`
+
+error: Missing required bounds on Out
+  --> $DIR/self-outlives-lint.rs:25:5
+   |
+LL |     type Out<'x>;
+   |     ^^^^^^^^^^^^-
+   |                 |
+   |                 help: add the required where clauses: `where T: 'x`
+
+error: Missing required bounds on Out
+  --> $DIR/self-outlives-lint.rs:39:5
+   |
+LL |     type Out<'x>;
+   |     ^^^^^^^^^^^^-
+   |                 |
+   |                 help: add the required where clauses: `where T: 'x`
+
+error: Missing required bounds on Out
+  --> $DIR/self-outlives-lint.rs:46:5
+   |
+LL |     type Out<'x, 'y>;
+   |     ^^^^^^^^^^^^^^^^-
+   |                     |
+   |                     help: add the required where clauses: `where T: 'x, U: 'y`
+
+error: Missing required bounds on Out
+  --> $DIR/self-outlives-lint.rs:61:5
+   |
+LL |     type Out<'x, D>;
+   |     ^^^^^^^^^^^^^^^-
+   |                    |
+   |                    help: add the required where clauses: `where D: 'x`
+
+error: Missing required bounds on Out
+  --> $DIR/self-outlives-lint.rs:77:5
+   |
+LL |     type Out<'x, D>;
+   |     ^^^^^^^^^^^^^^^-
+   |                    |
+   |                    help: add the required where clauses: `where D: 'x`
+
+error: Missing required bounds on Out
+  --> $DIR/self-outlives-lint.rs:92:5
+   |
+LL |     type Out<'x, D>;
+   |     ^^^^^^^^^^^^^^^-
+   |                    |
+   |                    help: add the required where clauses: `where D: 'x`
+
+error: Missing required bounds on Bar
+  --> $DIR/self-outlives-lint.rs:114:5
+   |
+LL |     type Bar<'b>;
+   |     ^^^^^^^^^^^^-
+   |                 |
+   |                 help: add the required where clauses: `where Self: 'a, Self: 'b`
+
+error: Missing required bounds on Bar
+  --> $DIR/self-outlives-lint.rs:122:5
+   |
+LL |     type Bar<'b>;
+   |     ^^^^^^^^^^^^-
+   |                 |
+   |                 help: add the required where clauses: `where Self: 'a, Self: 'b`
+
+error: Missing required bounds on Bar
+  --> $DIR/self-outlives-lint.rs:129:5
+   |
+LL |     type Bar<'b>;
+   |     ^^^^^^^^^^^^-
+   |                 |
+   |                 help: add the required where clauses: `where Self: 'b`
+
+error: Missing required bounds on Iterator
+  --> $DIR/self-outlives-lint.rs:143:5
+   |
+LL |     type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+   |                                                       |
+   |                                                       help: add the required where clauses: `where Self: 'a`
+
+error: Missing required bounds on Bar
+  --> $DIR/self-outlives-lint.rs:150:5
+   |
+LL |     type Bar<'a, 'b>;
+   |     ^^^^^^^^^^^^^^^^-
+   |                     |
+   |                     help: add the required where clauses: `where 'a: 'b`
+
+error: aborting due to 12 previous errors
+
index 2feff9f4c6f2ff3f64e191e5ac148064fd68018a..f83d4d7b68e48ae155a5db86ae28bf2f6486654a 100644 (file)
@@ -5,12 +5,12 @@
 use std::fmt::Display;
 
 trait StreamingIterator {
-    type Item<'a>;
+    type Item<'a> where Self: 'a;
     // Applying the lifetime parameter `'a` to `Self::Item` inside the trait.
     fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
 }
 
-struct Foo<T: StreamingIterator> {
+struct Foo<T: StreamingIterator + 'static> {
     // Applying a concrete lifetime to the constructor outside the trait.
     bar: <T as StreamingIterator>::Item<'static>,
 }
@@ -30,7 +30,7 @@ struct StreamEnumerate<I> {
 }
 
 impl<I: StreamingIterator> StreamingIterator for StreamEnumerate<I> {
-    type Item<'a> = (usize, I::Item<'a>);
+    type Item<'a> where Self: 'a = (usize, I::Item<'a>);
     fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
         match self.iter.next() {
             None => None,
@@ -44,7 +44,7 @@ fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
 }
 
 impl<I: Iterator> StreamingIterator for I {
-    type Item<'a> = <I as Iterator>::Item;
+    type Item<'a> where Self: 'a = <I as Iterator>::Item;
     fn next(&mut self) -> Option<<I as StreamingIterator>::Item<'_>> {
         Iterator::next(self)
     }
index 7bc250ee87b944dc50cf4f0714923f5ce893bb4f..7d0f7638ac89dc008a5f43305440cff3c2299bb7 100644 (file)
@@ -3,7 +3,7 @@
 #![feature(generic_associated_types)]
 
 trait A {
-    type B<'a>;
+    type B<'a> where Self: 'a;
 
     fn make_b<'a>(&'a self) -> Self::B<'a>;
 }
diff --git a/src/test/ui/generics/issue-1112.rs b/src/test/ui/generics/issue-1112.rs
new file mode 100644 (file)
index 0000000..3ba7bb2
--- /dev/null
@@ -0,0 +1,37 @@
+// run-pass
+#![allow(dead_code)]
+// Issue #1112
+// Alignment of interior pointers to dynamic-size types
+
+
+struct X<T> {
+    a: T,
+    b: u8,
+    c: bool,
+    d: u8,
+    e: u16,
+    f: u8,
+    g: u8
+}
+
+pub fn main() {
+    let x: X<isize> = X {
+        a: 12345678,
+        b: 9,
+        c: true,
+        d: 10,
+        e: 11,
+        f: 12,
+        g: 13
+    };
+    bar(x);
+}
+
+fn bar<T>(x: X<T>) {
+    assert_eq!(x.b, 9);
+    assert_eq!(x.c, true);
+    assert_eq!(x.d, 10);
+    assert_eq!(x.e, 11);
+    assert_eq!(x.f, 12);
+    assert_eq!(x.g, 13);
+}
diff --git a/src/test/ui/generics/issue-333.rs b/src/test/ui/generics/issue-333.rs
new file mode 100644 (file)
index 0000000..0753aaa
--- /dev/null
@@ -0,0 +1,7 @@
+// run-pass
+
+fn quux<T>(x: T) -> T { let f = id::<T>; return f(x); }
+
+fn id<T>(x: T) -> T { return x; }
+
+pub fn main() { assert_eq!(quux(10), 10); }
diff --git a/src/test/ui/generics/issue-59508-1.rs b/src/test/ui/generics/issue-59508-1.rs
new file mode 100644 (file)
index 0000000..6376c42
--- /dev/null
@@ -0,0 +1,17 @@
+#![allow(dead_code)]
+#![feature(const_generics_defaults)]
+
+// This test checks that generic parameter re-ordering diagnostic suggestions mention that
+// consts come after types and lifetimes when the `const_generics_defaults` feature is enabled.
+// We cannot run rustfix on this test because of the above const generics warning.
+
+struct A;
+
+impl A {
+    pub fn do_things<T, 'a, 'b: 'a>() {
+    //~^ ERROR lifetime parameters must be declared prior to type parameters
+        println!("panic");
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generics/issue-59508-1.stderr b/src/test/ui/generics/issue-59508-1.stderr
new file mode 100644 (file)
index 0000000..df244f0
--- /dev/null
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/issue-59508-1.rs:11:25
+   |
+LL |     pub fn do_things<T, 'a, 'b: 'a>() {
+   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b: 'a, T>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/generics/issue-59508.fixed b/src/test/ui/generics/issue-59508.fixed
new file mode 100644 (file)
index 0000000..b5c60a1
--- /dev/null
@@ -0,0 +1,16 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
+
+struct A;
+
+impl A {
+    pub fn do_things<'a, 'b: 'a, T>() {
+    //~^ ERROR lifetime parameters must be declared prior to type parameters
+        println!("panic");
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generics/issue-59508.rs b/src/test/ui/generics/issue-59508.rs
new file mode 100644 (file)
index 0000000..0b39c5d
--- /dev/null
@@ -0,0 +1,16 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
+
+struct A;
+
+impl A {
+    pub fn do_things<T, 'a, 'b: 'a>() {
+    //~^ ERROR lifetime parameters must be declared prior to type parameters
+        println!("panic");
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generics/issue-59508.stderr b/src/test/ui/generics/issue-59508.stderr
new file mode 100644 (file)
index 0000000..33e967c
--- /dev/null
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/issue-59508.rs:10:25
+   |
+LL |     pub fn do_things<T, 'a, 'b: 'a>() {
+   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>`
+
+error: aborting due to previous error
+
index 738f151b0f60b17c8aee1845f5123bb30114a8b2..134d8af5bfb8aba42320695460111a4b87ca45cf 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 // edition:2021
-// compile-flags: -Zunstable-options
 
 fn main() {
     println!("hello, 2021");
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-60283.rs b/src/test/ui/higher-rank-trait-bounds/issue-60283.rs
new file mode 100644 (file)
index 0000000..c63b154
--- /dev/null
@@ -0,0 +1,20 @@
+pub trait Trait<'a> {
+    type Item;
+}
+
+impl<'a> Trait<'a> for () {
+    type Item = ();
+}
+
+pub fn foo<T, F>(_: T, _: F)
+where
+    T: for<'a> Trait<'a>,
+    F: for<'a> FnMut(<T as Trait<'a>>::Item),
+{
+}
+
+fn main() {
+    foo((), drop)
+    //~^ ERROR type mismatch in function arguments
+    //~| ERROR size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-60283.stderr b/src/test/ui/higher-rank-trait-bounds/issue-60283.stderr
new file mode 100644 (file)
index 0000000..34893cd
--- /dev/null
@@ -0,0 +1,42 @@
+error[E0631]: type mismatch in function arguments
+  --> $DIR/issue-60283.rs:17:13
+   |
+LL |     foo((), drop)
+   |     ---     ^^^^
+   |     |       |
+   |     |       expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
+   |     |       found signature of `fn(()) -> _`
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `foo`
+  --> $DIR/issue-60283.rs:12:16
+   |
+LL | pub fn foo<T, F>(_: T, _: F)
+   |        --- required by a bound in this
+...
+LL |     F: for<'a> FnMut(<T as Trait<'a>>::Item),
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
+  --> $DIR/issue-60283.rs:17:13
+   |
+LL |     foo((), drop)
+   |     ---     ^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Sized` is not implemented for `<() as Trait<'_>>::Item`
+note: required by a bound in `std::mem::drop`
+  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+   |
+LL | pub fn drop<T>(_x: T) {}
+   |             ^ required by this bound in `std::mem::drop`
+help: consider further restricting the associated type
+   |
+LL | fn main() where <() as Trait<'_>>::Item: Sized {
+   |           ++++++++++++++++++++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0631.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs
new file mode 100644 (file)
index 0000000..f255eac
--- /dev/null
@@ -0,0 +1,31 @@
+// check-pass
+
+pub trait Foo<'a> {
+    type Bar;
+    fn foo(&'a self) -> Self::Bar;
+}
+
+impl<'a, 'b, T: 'a> Foo<'a> for &'b T {
+    type Bar = &'a T;
+    fn foo(&'a self) -> &'a T {
+        self
+    }
+}
+
+pub fn uncallable<T, F>(x: T, f: F)
+where
+    T: for<'a> Foo<'a>,
+    F: for<'a> Fn(<T as Foo<'a>>::Bar),
+{
+    f(x.foo());
+}
+
+pub fn catalyst(x: &i32) {
+    broken(x, |_| {})
+}
+
+pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
+    uncallable(x, |y| f(y));
+}
+
+fn main() {}
index 24ac566f9df0c646061a912dbc1ad503a560f096..7c3c72e04cb781d32091328e33310422e858e473 100644 (file)
@@ -77,7 +77,7 @@ fn task<P>(processor: P) -> Task
 }
 
 fn main() {
-    task(annotate( //~ type mismatch
+    task(annotate(
         //~^ the size
         //~^^ the trait bound
         Annotate::<RefMutFamily<usize>>::new(),
index b13226fef6e76fe7ada4ad5948fa3f7428d26faa..01b14660b6531aa98a6f17f289e90aba6d632ebb 100644 (file)
@@ -1,29 +1,3 @@
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/issue-62529-1.rs:80:10
-   |
-LL |       task(annotate(
-   |  _____----_^
-   | |     |
-   | |     required by a bound introduced by this call
-LL | |
-LL | |
-LL | |         Annotate::<RefMutFamily<usize>>::new(),
-LL | |         |value: &mut usize| {
-   | |         ------------------- found signature of `for<'r> fn(&'r mut usize) -> _`
-LL | |             *value = 2;
-LL | |         }
-LL | |     ));
-   | |_____^ expected signature of `for<'r> fn(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
-   |
-note: required by a bound in `annotate`
-  --> $DIR/issue-62529-1.rs:44:8
-   |
-LL | fn annotate<F, Q>(_q: Annotate<Q>, func: F) -> impl Execute + 'static
-   |    -------- required by a bound in this
-LL | where
-LL |     F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out) + 'static,
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `annotate`
-
 error[E0277]: the size for values of type `impl Execute` cannot be known at compilation time
   --> $DIR/issue-62529-1.rs:80:10
    |
@@ -73,7 +47,6 @@ LL | fn task<P>(processor: P) -> Task
 LL | where P: Execute + 'static {
    |          ^^^^^^^ required by this bound in `task`
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0631.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
index 87d1a250f7ae6dd3b47729605b0ae210272f65e2..3ced40230f012033de6307c24ac43f1001144b1a 100644 (file)
@@ -1,3 +1,5 @@
+// check-pass
+
 pub trait MyTrait<'a> {
     type Output: 'a;
     fn gimme_value(&self) -> Self::Output;
@@ -23,7 +25,7 @@ fn meow<T, F>(t: T, f: F)
 
 fn main() {
     let struc = MyStruct;
-    meow(struc, |foo| { //~ type mismatch
+    meow(struc, |foo| {
         println!("{:?}", foo);
     })
 }
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.stderr
deleted file mode 100644 (file)
index efc9568..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/issue-70120.rs:26:5
-   |
-LL |     meow(struc, |foo| {
-   |     ^^^^        ----- found signature of `for<'r> fn(&'r usize) -> _`
-   |     |
-   |     expected signature of `for<'any2> fn(<MyStruct as MyTrait<'any2>>::Output) -> _`
-   |
-note: required by a bound in `meow`
-  --> $DIR/issue-70120.rs:18:8
-   |
-LL | fn meow<T, F>(t: T, f: F)
-   |    ---- required by a bound in this
-...
-LL |     F: for<'any2> Fn(<T as MyTrait<'any2>>::Output),
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `meow`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0631`.
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr
new file mode 100644 (file)
index 0000000..119cec1
--- /dev/null
@@ -0,0 +1,92 @@
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:52:5
+   |
+LL |     foo(bar, "string", |s| s.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:52:5
+   |
+LL |     foo(bar, "string", |s| s.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:52:5
+   |
+LL |     foo(bar, "string", |s| s.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:52:5
+   |
+LL |     foo(bar, "string", |s| s.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:52:5
+   |
+LL |     foo(bar, "string", |s| s.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:58:5
+   |
+LL |     foo(baz, "string", |s| s.0.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:58:5
+   |
+LL |     foo(baz, "string", |s| s.0.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:58:5
+   |
+LL |     foo(baz, "string", |s| s.0.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:58:5
+   |
+LL |     foo(baz, "string", |s| s.0.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: implementation of `Parser` is not general enough
+  --> $DIR/issue-71955.rs:58:5
+   |
+LL |     foo(baz, "string", |s| s.0.len() == 5);
+   |     ^^^ implementation of `Parser` is not general enough
+   |
+   = note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr
new file mode 100644 (file)
index 0000000..69ab446
--- /dev/null
@@ -0,0 +1,8 @@
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/issue-71955.rs:42:1
+   |
+LL | fn main() {
+   | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs
new file mode 100644 (file)
index 0000000..95e3b3d
--- /dev/null
@@ -0,0 +1,64 @@
+// ignore-compare-mode-nll
+// revisions: migrate nll
+// [nll]compile-flags: -Zborrowck=mir
+// check-fail
+
+#![feature(rustc_attrs)]
+
+trait Parser<'s> {
+    type Output;
+
+    fn call(&self, input: &'s str) -> (&'s str, Self::Output);
+}
+
+impl<'s, F, T> Parser<'s> for F
+where F: Fn(&'s str) -> (&'s str, T) {
+    type Output = T;
+    fn call(&self, input: &'s str) -> (&'s str, T) {
+        self(input)
+    }
+}
+
+fn foo<F1, F2>(
+    f1: F1,
+    base: &'static str,
+    f2: F2
+)
+where
+    F1: for<'a> Parser<'a>,
+    F2: FnOnce(&<F1 as Parser>::Output) -> bool
+{
+    let s: String = base.to_owned();
+    let str_ref = s.as_ref();
+    let (remaining, produced) = f1.call(str_ref);
+    assert!(f2(&produced));
+    assert_eq!(remaining.len(), 0);
+}
+
+struct Wrapper<'a>(&'a str);
+
+// Because nll currently succeeds and migrate doesn't
+#[rustc_error]
+fn main() {
+    //[nll]~^ fatal
+    fn bar<'a>(s: &'a str) -> (&'a str, &'a str) {
+        (&s[..1], &s[..])
+    }
+
+    fn baz<'a>(s: &'a str) -> (&'a str, Wrapper<'a>) {
+        (&s[..1], Wrapper(&s[..]))
+    }
+
+    foo(bar, "string", |s| s.len() == 5);
+    //[migrate]~^ ERROR implementation of `Parser` is not general enough
+    //[migrate]~| ERROR implementation of `Parser` is not general enough
+    //[migrate]~| ERROR implementation of `Parser` is not general enough
+    //[migrate]~| ERROR implementation of `Parser` is not general enough
+    //[migrate]~| ERROR implementation of `Parser` is not general enough
+    foo(baz, "string", |s| s.0.len() == 5);
+    //[migrate]~^ ERROR implementation of `Parser` is not general enough
+    //[migrate]~| ERROR implementation of `Parser` is not general enough
+    //[migrate]~| ERROR implementation of `Parser` is not general enough
+    //[migrate]~| ERROR implementation of `Parser` is not general enough
+    //[migrate]~| ERROR implementation of `Parser` is not general enough
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs
new file mode 100644 (file)
index 0000000..93ccb42
--- /dev/null
@@ -0,0 +1,30 @@
+// check-pass
+
+use std::marker::PhantomData;
+
+trait A<'a> {
+    type B;
+    fn b(self) -> Self::B;
+}
+
+struct T;
+struct S<'a>(PhantomData<&'a ()>);
+
+impl<'a> A<'a> for T {
+    type B = S<'a>;
+    fn b(self) -> Self::B {
+        S(PhantomData)
+    }
+}
+
+fn s<TT, F>(t: TT, f: F)
+where
+    TT: for<'a> A<'a>,
+    F: for<'a> FnOnce(<TT as A<'a>>::B)
+{
+    f(t.b());
+}
+
+fn main() {
+    s(T, |_| {});
+}
diff --git a/src/test/ui/hrtb/issue-90177.rs b/src/test/ui/hrtb/issue-90177.rs
new file mode 100644 (file)
index 0000000..b151a9d
--- /dev/null
@@ -0,0 +1,32 @@
+// check-pass
+
+trait Base<'f> {
+    type Assoc;
+
+    fn do_something(&self);
+}
+
+trait ForAnyLifetime: for<'f> Base<'f> {}
+
+impl<T> ForAnyLifetime for T where T: for<'f> Base<'f> {}
+
+trait CanBeDynamic: ForAnyLifetime + for<'f> Base<'f, Assoc = ()> {}
+
+fn foo(a: &dyn CanBeDynamic) {
+    a.do_something();
+}
+
+struct S;
+
+impl<'a> Base<'a> for S {
+    type Assoc = ();
+
+    fn do_something(&self) {}
+}
+
+impl CanBeDynamic for S {}
+
+fn main() {
+    let s = S;
+    foo(&s);
+}
diff --git a/src/test/ui/hygiene/lambda-var-hygiene.rs b/src/test/ui/hygiene/lambda-var-hygiene.rs
new file mode 100644 (file)
index 0000000..bf06765
--- /dev/null
@@ -0,0 +1,12 @@
+// run-pass
+// shouldn't affect evaluation of $ex:
+macro_rules! bad_macro {
+    ($ex:expr) => ({(|_x| { $ex }) (9) })
+}
+
+fn takes_x(_x : isize) {
+    assert_eq!(bad_macro!(_x),8);
+}
+fn main() {
+    takes_x(8);
+}
diff --git a/src/test/ui/impl-trait/issue-49579.rs b/src/test/ui/impl-trait/issue-49579.rs
new file mode 100644 (file)
index 0000000..98de014
--- /dev/null
@@ -0,0 +1,14 @@
+// check-pass
+
+fn fibs(n: u32) -> impl Iterator<Item=u128> {
+    (0 .. n)
+    .scan((0, 1), |st, _| {
+        *st = (st.1, st.0 + st.1);
+        Some(*st)
+    })
+    .map(&|(f, _)| f)
+}
+
+fn main() {
+    println!("{:?}", fibs(10).collect::<Vec<_>>());
+}
diff --git a/src/test/ui/impl-trait/issue-49685.rs b/src/test/ui/impl-trait/issue-49685.rs
new file mode 100644 (file)
index 0000000..fb328d6
--- /dev/null
@@ -0,0 +1,13 @@
+// run-pass
+// Regression test for #49685: drop elaboration was not revealing the
+// value of `impl Trait` returns, leading to an ICE.
+
+fn main() {
+    let _ = Some(())
+        .into_iter()
+        .flat_map(|_| Some(()).into_iter().flat_map(func));
+}
+
+fn func(_: ()) -> impl Iterator<Item = ()> {
+    Some(()).into_iter().flat_map(|_| vec![])
+}
diff --git a/src/test/ui/impl-trait/issue-51185.rs b/src/test/ui/impl-trait/issue-51185.rs
new file mode 100644 (file)
index 0000000..52a2b25
--- /dev/null
@@ -0,0 +1,8 @@
+// run-pass
+fn foo() -> impl Into<for<'a> fn(&'a ())> {
+    (|_| {}) as for<'a> fn(&'a ())
+}
+
+fn main() {
+    foo().into()(&());
+}
diff --git a/src/test/ui/in-band-lifetimes.rs b/src/test/ui/in-band-lifetimes.rs
deleted file mode 100644 (file)
index 9b2e1fe..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// run-pass
-
-#![allow(warnings)]
-#![feature(in_band_lifetimes)]
-
-fn foo(x: &'x u8) -> &'x u8 { x }
-fn foo2(x: &'a u8, y: &u8) -> &'a u8 { x }
-
-fn check_in_band_can_be_late_bound() {
-    let _: for<'x> fn(&'x u8, &u8) -> &'x u8 = foo2;
-}
-
-struct ForInherentNoParams;
-
-impl ForInherentNoParams {
-    fn foo(x: &'a u32, y: &u32) -> &'a u32 { x }
-}
-
-struct X<'a>(&'a u8);
-
-impl<'a> X<'a> {
-    fn inner(&self) -> &'a u8 {
-        self.0
-    }
-
-    fn same_lifetime_as_parameter(&mut self, x: &'a u8) {
-        self.0 = x;
-    }
-}
-
-impl X<'b> {
-    fn inner_2(&self) -> &'b u8 {
-        self.0
-    }
-
-    fn reference_already_introduced_in_band_from_method_with_explicit_binders<'a>(
-        &'b self, x: &'a u32
-    ) {}
-}
-
-struct Y<T>(T);
-
-impl Y<&'a u8> {
-    fn inner(&self) -> &'a u8 {
-        self.0
-    }
-}
-
-trait MyTrait<'a> {
-    fn my_lifetime(&self) -> &'a u8;
-    fn any_lifetime() -> &'b u8;
-    fn borrowed_lifetime(&'b self) -> &'b u8;
-    fn default_impl(&self, x: &'b u32, y: &u32) -> &'b u32 { x }
-    fn in_band_def_explicit_impl(&self, x: &'b u8);
-}
-
-impl MyTrait<'a> for Y<&'a u8> {
-    fn my_lifetime(&self) -> &'a u8 { self.0 }
-    fn any_lifetime() -> &'b u8 { &0 }
-    fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
-    fn in_band_def_explicit_impl<'b>(&self, x: &'b u8) {}
-}
-
-fn test_hrtb_defined_lifetime_where<F>(_: F) where for<'a> F: Fn(&'a u8) {}
-fn test_hrtb_defined_lifetime_polytraitref<F>(_: F) where F: for<'a> Fn(&'a u8) {}
-
-fn reference_in_band_from_locals(x: &'test u32) -> &'test u32 {
-    let y: &'test u32 = x;
-    y
-}
-
-fn in_generics_in_band<T: MyTrait<'a>>(x: &T) {}
-fn where_clause_in_band<T>(x: &T) where T: MyTrait<'a> {}
-fn impl_trait_in_band(x: &impl MyTrait<'a>) {}
-
-// Tests around using in-band lifetimes within existential traits.
-
-trait FunkyTrait<'a> { }
-impl<'a, T> FunkyTrait<'a> for T { }
-fn ret_pos_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a {
-    x
-}
-fn ret_pos_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> {
-    x
-}
-fn ret_pos_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a {
-    x
-}
-fn ret_pos_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a {
-    x
-}
-fn ret_pos_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a {
-    x
-}
-
-fn main() {}
diff --git a/src/test/ui/in-band-lifetimes/in-band-lifetimes.rs b/src/test/ui/in-band-lifetimes/in-band-lifetimes.rs
new file mode 100644 (file)
index 0000000..9b2e1fe
--- /dev/null
@@ -0,0 +1,96 @@
+// run-pass
+
+#![allow(warnings)]
+#![feature(in_band_lifetimes)]
+
+fn foo(x: &'x u8) -> &'x u8 { x }
+fn foo2(x: &'a u8, y: &u8) -> &'a u8 { x }
+
+fn check_in_band_can_be_late_bound() {
+    let _: for<'x> fn(&'x u8, &u8) -> &'x u8 = foo2;
+}
+
+struct ForInherentNoParams;
+
+impl ForInherentNoParams {
+    fn foo(x: &'a u32, y: &u32) -> &'a u32 { x }
+}
+
+struct X<'a>(&'a u8);
+
+impl<'a> X<'a> {
+    fn inner(&self) -> &'a u8 {
+        self.0
+    }
+
+    fn same_lifetime_as_parameter(&mut self, x: &'a u8) {
+        self.0 = x;
+    }
+}
+
+impl X<'b> {
+    fn inner_2(&self) -> &'b u8 {
+        self.0
+    }
+
+    fn reference_already_introduced_in_band_from_method_with_explicit_binders<'a>(
+        &'b self, x: &'a u32
+    ) {}
+}
+
+struct Y<T>(T);
+
+impl Y<&'a u8> {
+    fn inner(&self) -> &'a u8 {
+        self.0
+    }
+}
+
+trait MyTrait<'a> {
+    fn my_lifetime(&self) -> &'a u8;
+    fn any_lifetime() -> &'b u8;
+    fn borrowed_lifetime(&'b self) -> &'b u8;
+    fn default_impl(&self, x: &'b u32, y: &u32) -> &'b u32 { x }
+    fn in_band_def_explicit_impl(&self, x: &'b u8);
+}
+
+impl MyTrait<'a> for Y<&'a u8> {
+    fn my_lifetime(&self) -> &'a u8 { self.0 }
+    fn any_lifetime() -> &'b u8 { &0 }
+    fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
+    fn in_band_def_explicit_impl<'b>(&self, x: &'b u8) {}
+}
+
+fn test_hrtb_defined_lifetime_where<F>(_: F) where for<'a> F: Fn(&'a u8) {}
+fn test_hrtb_defined_lifetime_polytraitref<F>(_: F) where F: for<'a> Fn(&'a u8) {}
+
+fn reference_in_band_from_locals(x: &'test u32) -> &'test u32 {
+    let y: &'test u32 = x;
+    y
+}
+
+fn in_generics_in_band<T: MyTrait<'a>>(x: &T) {}
+fn where_clause_in_band<T>(x: &T) where T: MyTrait<'a> {}
+fn impl_trait_in_band(x: &impl MyTrait<'a>) {}
+
+// Tests around using in-band lifetimes within existential traits.
+
+trait FunkyTrait<'a> { }
+impl<'a, T> FunkyTrait<'a> for T { }
+fn ret_pos_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a {
+    x
+}
+fn ret_pos_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> {
+    x
+}
+fn ret_pos_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a {
+    x
+}
+fn ret_pos_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a {
+    x
+}
+fn ret_pos_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a {
+    x
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/lub-glb-with-unbound-infer-var.rs b/src/test/ui/inference/lub-glb-with-unbound-infer-var.rs
new file mode 100644 (file)
index 0000000..c9e1170
--- /dev/null
@@ -0,0 +1,15 @@
+// run-pass
+// Test for a specific corner case: when we compute the LUB of two fn
+// types and their parameters have unbound variables. In that case, we
+// wind up relating those two variables. This was causing an ICE in an
+// in-progress PR.
+
+fn main() {
+    let a_f: fn(_) = |_| ();
+    let b_f: fn(_) = |_| ();
+    let c_f = match 22 {
+        0 => a_f,
+        _ => b_f,
+    };
+    c_f(4);
+}
diff --git a/src/test/ui/issues/auxiliary/issue-19163.rs b/src/test/ui/issues/auxiliary/issue-19163.rs
deleted file mode 100644 (file)
index 0c0d9e4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#![crate_type = "lib"]
-
-#[macro_export]
-macro_rules! mywrite {
-    ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*)))
-}
diff --git a/src/test/ui/issues/auxiliary/issue-39823.rs b/src/test/ui/issues/auxiliary/issue-39823.rs
deleted file mode 100644 (file)
index 3af9c68..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#![crate_type="rlib"]
-
-#[derive(Debug, PartialEq)]
-pub struct RemoteC(pub u32);
-
-#[derive(Debug, PartialEq)]
-pub struct RemoteG<T>(pub T);
diff --git a/src/test/ui/issues/auxiliary/xcrate-issue-43189-a.rs b/src/test/ui/issues/auxiliary/xcrate-issue-43189-a.rs
deleted file mode 100644 (file)
index 9ab570f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#![crate_type="lib"]
-
-
-pub trait A {
-    fn a(&self) {}
-}
-impl A for () {}
diff --git a/src/test/ui/issues/auxiliary/xcrate-issue-43189-b.rs b/src/test/ui/issues/auxiliary/xcrate-issue-43189-b.rs
deleted file mode 100644 (file)
index 31dfb05..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#![crate_type="lib"]
-
-pub extern crate xcrate_issue_43189_a;
diff --git a/src/test/ui/issues/auxiliary/xcrate-issue-46112-rexport-core.rs b/src/test/ui/issues/auxiliary/xcrate-issue-46112-rexport-core.rs
deleted file mode 100644 (file)
index 2b517b5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#![crate_type="lib"]
-
-pub extern crate core;
diff --git a/src/test/ui/issues/auxiliary/xcrate-issue-61711-b.rs b/src/test/ui/issues/auxiliary/xcrate-issue-61711-b.rs
deleted file mode 100644 (file)
index 88a0405..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// edition:2018
-#![crate_type="lib"]
-#![crate_name="xcrate_issue_61711_b"]
-pub struct Struct;
-pub use crate as alias;
diff --git a/src/test/ui/issues/issue-10398.rs b/src/test/ui/issues/issue-10398.rs
deleted file mode 100644 (file)
index 0405b2d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#![feature(box_syntax)]
-
-fn main() {
-    let x: Box<_> = box 1;
-    let f = move|| {
-        let _a = x;
-        drop(x);
-        //~^ ERROR: use of moved value: `x`
-    };
-    f();
-}
diff --git a/src/test/ui/issues/issue-10398.stderr b/src/test/ui/issues/issue-10398.stderr
deleted file mode 100644 (file)
index 8d9faf3..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0382]: use of moved value: `x`
-  --> $DIR/issue-10398.rs:7:14
-   |
-LL |         let _a = x;
-   |                  - value moved here
-LL |         drop(x);
-   |              ^ value used here after move
-   |
-   = note: move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/issues/issue-1112.rs b/src/test/ui/issues/issue-1112.rs
deleted file mode 100644 (file)
index 3ba7bb2..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-// Issue #1112
-// Alignment of interior pointers to dynamic-size types
-
-
-struct X<T> {
-    a: T,
-    b: u8,
-    c: bool,
-    d: u8,
-    e: u16,
-    f: u8,
-    g: u8
-}
-
-pub fn main() {
-    let x: X<isize> = X {
-        a: 12345678,
-        b: 9,
-        c: true,
-        d: 10,
-        e: 11,
-        f: 12,
-        g: 13
-    };
-    bar(x);
-}
-
-fn bar<T>(x: X<T>) {
-    assert_eq!(x.b, 9);
-    assert_eq!(x.c, true);
-    assert_eq!(x.d, 10);
-    assert_eq!(x.e, 11);
-    assert_eq!(x.f, 12);
-    assert_eq!(x.g, 13);
-}
diff --git a/src/test/ui/issues/issue-11577.rs b/src/test/ui/issues/issue-11577.rs
deleted file mode 100644 (file)
index 70177c5..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// run-pass
-// Destructuring struct variants would ICE where regular structs wouldn't
-
-enum Foo {
-    VBar { num: isize }
-}
-
-struct SBar { num: isize }
-
-pub fn main() {
-    let vbar = Foo::VBar { num: 1 };
-    let Foo::VBar { num } = vbar;
-    assert_eq!(num, 1);
-
-    let sbar = SBar { num: 2 };
-    let SBar { num } = sbar;
-    assert_eq!(num, 2);
-}
diff --git a/src/test/ui/issues/issue-11940.rs b/src/test/ui/issues/issue-11940.rs
deleted file mode 100644 (file)
index 6815c87..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-pass
-
-const TEST_STR: &'static str = "abcd";
-
-fn main() {
-    let s = "abcd";
-    match s {
-        TEST_STR => (),
-        _ => unreachable!()
-    }
-}
diff --git a/src/test/ui/issues/issue-12796.rs b/src/test/ui/issues/issue-12796.rs
deleted file mode 100644 (file)
index 942d6b9..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-trait Trait {
-    fn outer(&self) {
-        fn inner(_: &Self) {
-            //~^ ERROR can't use generic parameters from outer function
-        }
-    }
-}
-
-fn main() { }
diff --git a/src/test/ui/issues/issue-12796.stderr b/src/test/ui/issues/issue-12796.stderr
deleted file mode 100644 (file)
index a01fd2d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0401]: can't use generic parameters from outer function
-  --> $DIR/issue-12796.rs:3:22
-   |
-LL |         fn inner(_: &Self) {
-   |                      ^^^^
-   |                      |
-   |                      use of generic parameter from outer function
-   |                      can't use `Self` here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0401`.
diff --git a/src/test/ui/issues/issue-13483.rs b/src/test/ui/issues/issue-13483.rs
deleted file mode 100644 (file)
index a2fd926..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-fn main() {
-    if true {
-    } else if { //~ ERROR missing condition
-    //~^ ERROR mismatched types
-    } else {
-    }
-}
-
-fn foo() {
-    if true {
-    } else if { //~ ERROR missing condition
-    //~^ ERROR mismatched types
-    }
-    bar();
-}
-
-fn bar() {}
diff --git a/src/test/ui/issues/issue-13483.stderr b/src/test/ui/issues/issue-13483.stderr
deleted file mode 100644 (file)
index 5fd05b1..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-error: missing condition for `if` expression
-  --> $DIR/issue-13483.rs:3:14
-   |
-LL |     } else if {
-   |              ^ expected if condition here
-
-error: missing condition for `if` expression
-  --> $DIR/issue-13483.rs:11:14
-   |
-LL |     } else if {
-   |              ^ expected if condition here
-
-error[E0308]: mismatched types
-  --> $DIR/issue-13483.rs:3:15
-   |
-LL |       } else if {
-   |  _______________^
-LL | |
-LL | |     } else {
-   | |_____^ expected `bool`, found `()`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-13483.rs:11:15
-   |
-LL |       } else if {
-   |  _______________^
-LL | |
-LL | |     }
-   | |_____^ expected `bool`, found `()`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-13902.rs b/src/test/ui/issues/issue-13902.rs
deleted file mode 100644 (file)
index 1afde0e..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-#![allow(non_camel_case_types)]
-
-const JSVAL_TAG_CLEAR: u32 = 0xFFFFFF80;
-const JSVAL_TYPE_INT32: u8 = 0x01;
-const JSVAL_TYPE_UNDEFINED: u8 = 0x02;
-#[repr(u32)]
-enum ValueTag {
-    JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | (JSVAL_TYPE_INT32 as u32),
-    JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | (JSVAL_TYPE_UNDEFINED as u32),
-}
-
-fn main() {
-    let _ = ValueTag::JSVAL_TAG_INT32;
-}
diff --git a/src/test/ui/issues/issue-14227.mir.stderr b/src/test/ui/issues/issue-14227.mir.stderr
deleted file mode 100644 (file)
index 8e7a251..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0133]: use of extern static is unsafe and requires unsafe function or block
-  --> $DIR/issue-14227.rs:7:21
-   |
-LL | static CRASH: u32 = symbol;
-   |                     ^^^^^^ use of extern static
-   |
-   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/issues/issue-14227.rs b/src/test/ui/issues/issue-14227.rs
deleted file mode 100644 (file)
index 5f866ec..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// revisions: mir thir
-// [thir]compile-flags: -Z thir-unsafeck
-
-extern "C" {
-    pub static symbol: u32;
-}
-static CRASH: u32 = symbol;
-//~^ ERROR use of extern static is unsafe and requires
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-14227.thir.stderr b/src/test/ui/issues/issue-14227.thir.stderr
deleted file mode 100644 (file)
index 8e7a251..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0133]: use of extern static is unsafe and requires unsafe function or block
-  --> $DIR/issue-14227.rs:7:21
-   |
-LL | static CRASH: u32 = symbol;
-   |                     ^^^^^^ use of extern static
-   |
-   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/issues/issue-14456.rs b/src/test/ui/issues/issue-14456.rs
deleted file mode 100644 (file)
index 52a56eb..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// run-pass
-#![allow(unused_mut)]
-// ignore-emscripten no processes
-// ignore-sgx no processes
-
-use std::env;
-use std::io::prelude::*;
-use std::io;
-use std::process::{Command, Stdio};
-
-fn main() {
-    let args: Vec<String> = env::args().collect();
-    if args.len() > 1 && args[1] == "child" {
-        return child()
-    }
-
-    test();
-}
-
-fn child() {
-    writeln!(&mut io::stdout(), "foo").unwrap();
-    writeln!(&mut io::stderr(), "bar").unwrap();
-    let mut stdin = io::stdin();
-    let mut s = String::new();
-    stdin.lock().read_line(&mut s).unwrap();
-    assert_eq!(s.len(), 0);
-}
-
-fn test() {
-    let args: Vec<String> = env::args().collect();
-    let mut p = Command::new(&args[0]).arg("child")
-                                     .stdin(Stdio::piped())
-                                     .stdout(Stdio::piped())
-                                     .stderr(Stdio::piped())
-                                     .spawn().unwrap();
-    assert!(p.wait().unwrap().success());
-}
diff --git a/src/test/ui/issues/issue-14589.rs b/src/test/ui/issues/issue-14589.rs
deleted file mode 100644 (file)
index 5d8aab2..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// run-pass
-// All 3 expressions should work in that the argument gets
-// coerced to a trait object
-
-// pretty-expanded FIXME #23616
-
-fn main() {
-    send::<Box<dyn Foo>>(Box::new(Output(0)));
-    Test::<Box<dyn Foo>>::foo(Box::new(Output(0)));
-    Test::<Box<dyn Foo>>::new().send(Box::new(Output(0)));
-}
-
-fn send<T>(_: T) {}
-
-struct Test<T> { marker: std::marker::PhantomData<T> }
-impl<T> Test<T> {
-    fn new() -> Test<T> { Test { marker: ::std::marker::PhantomData } }
-    fn foo(_: T) {}
-    fn send(&self, _: T) {}
-}
-
-trait Foo { fn dummy(&self) { }}
-struct Output(isize);
-impl Foo for Output {}
diff --git a/src/test/ui/issues/issue-14837.rs b/src/test/ui/issues/issue-14837.rs
deleted file mode 100644 (file)
index a83bc41..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// check-pass
-// pretty-expanded FIXME #23616
-
-#[deny(dead_code)]
-pub enum Foo {
-    Bar {
-        baz: isize
-    }
-}
-
-fn main() { }
diff --git a/src/test/ui/issues/issue-15080.rs b/src/test/ui/issues/issue-15080.rs
deleted file mode 100644 (file)
index 4dd6981..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// run-pass
-
-fn main() {
-    let mut x: &[_] = &[1, 2, 3, 4];
-
-    let mut result = vec![];
-    loop {
-        x = match *x {
-            [1, n, 3, ref rest @ ..] => {
-                result.push(n);
-                rest
-            }
-            [n, ref rest @ ..] => {
-                result.push(n);
-                rest
-            }
-            [] =>
-                break
-        }
-    }
-    assert_eq!(result, [2, 4]);
-}
diff --git a/src/test/ui/issues/issue-16098.rs b/src/test/ui/issues/issue-16098.rs
deleted file mode 100644 (file)
index 00acc20..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-macro_rules! prob1 {
-    (0) => {
-        0
-    };
-    ($n:expr) => {
-        if ($n % 3 == 0) || ($n % 5 == 0) {
-            $n + prob1!($n - 1); //~ ERROR recursion limit reached while expanding `prob1!`
-        } else {
-            prob1!($n - 1);
-        }
-    };
-}
-
-fn main() {
-    println!("Problem 1: {}", prob1!(1000));
-}
diff --git a/src/test/ui/issues/issue-16098.stderr b/src/test/ui/issues/issue-16098.stderr
deleted file mode 100644 (file)
index 6428021..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error: recursion limit reached while expanding `prob1!`
-  --> $DIR/issue-16098.rs:7:18
-   |
-LL |             $n + prob1!($n - 1);
-   |                  ^^^^^^^^^^^^^^
-...
-LL |     println!("Problem 1: {}", prob1!(1000));
-   |                               ------------ in this macro invocation
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_16098`)
-   = note: this error originates in the macro `prob1` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-16272.rs b/src/test/ui/issues/issue-16272.rs
deleted file mode 100644 (file)
index 5cf3fd9..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// run-pass
-// ignore-emscripten no processes
-// ignore-sgx no processes
-
-use std::process::Command;
-use std::env;
-
-fn main() {
-    let len = env::args().len();
-
-    if len == 1 {
-        test();
-    } else {
-        assert_eq!(len, 3);
-    }
-}
-
-fn test() {
-    let status = Command::new(&env::current_exe().unwrap())
-                         .arg("foo").arg("")
-                         .status().unwrap();
-    assert!(status.success());
-}
diff --git a/src/test/ui/issues/issue-17074.rs b/src/test/ui/issues/issue-17074.rs
deleted file mode 100644 (file)
index 0ed8113..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-
-static X2: u64 = !0 as u16 as u64;
-static Y2: u64 = !0 as u32 as u64;
-const X: u64 = !0 as u16 as u64;
-const Y: u64 = !0 as u32 as u64;
-
-fn main() {
-    assert_eq!(match 1 {
-        X => unreachable!(),
-        Y => unreachable!(),
-        _ => 1
-    }, 1);
-}
diff --git a/src/test/ui/issues/issue-18060.rs b/src/test/ui/issues/issue-18060.rs
deleted file mode 100644 (file)
index b5f3d0f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-pass
-// Regression test for #18060: match arms were matching in the wrong order.
-
-fn main() {
-    assert_eq!(2, match (1, 3) { (0, 2..=5) => 1, (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 });
-    assert_eq!(2, match (1, 3) {                  (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 });
-    assert_eq!(2, match (1, 7) { (0, 2..=5) => 1, (1, 7) => 2, (_, 2..=5) => 3, (_, _) => 4 });
-}
diff --git a/src/test/ui/issues/issue-18294.rs b/src/test/ui/issues/issue-18294.rs
deleted file mode 100644 (file)
index 77355f0..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
-    const X: u32 = 1;
-    const Y: usize = unsafe { &X as *const u32 as usize }; //~ ERROR pointers cannot be cast to integers
-    println!("{}", Y);
-}
diff --git a/src/test/ui/issues/issue-18294.stderr b/src/test/ui/issues/issue-18294.stderr
deleted file mode 100644 (file)
index e0cbd2a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error: pointers cannot be cast to integers during const eval
-  --> $DIR/issue-18294.rs:3:31
-   |
-LL |     const Y: usize = unsafe { &X as *const u32 as usize };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: at compile-time, pointers do not have an integer value
-   = note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-18652.rs b/src/test/ui/issues/issue-18652.rs
deleted file mode 100644 (file)
index 59aa015..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// run-pass
-// Tests multiple free variables being passed by value into an unboxed
-// once closure as an optimization by codegen.  This used to hit an
-// incorrect assert.
-
-fn main() {
-    let x = 2u8;
-    let y = 3u8;
-    assert_eq!((move || x + y)(), 5);
-}
diff --git a/src/test/ui/issues/issue-19163.rs b/src/test/ui/issues/issue-19163.rs
deleted file mode 100644 (file)
index d98c591..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// aux-build:issue-19163.rs
-
-#[macro_use] extern crate issue_19163;
-
-use std::io::Write;
-
-fn main() {
-    let mut v = vec![];
-    mywrite!(&v, "Hello world");
-    //~^ ERROR cannot borrow data in a `&` reference as mutable
-}
diff --git a/src/test/ui/issues/issue-19163.stderr b/src/test/ui/issues/issue-19163.stderr
deleted file mode 100644 (file)
index ae1ae14..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0596]: cannot borrow data in a `&` reference as mutable
-  --> $DIR/issue-19163.rs:9:5
-   |
-LL |     mywrite!(&v, "Hello world");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
-   |
-   = note: this error originates in the macro `mywrite` (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 E0596`.
diff --git a/src/test/ui/issues/issue-19358.rs b/src/test/ui/issues/issue-19358.rs
deleted file mode 100644 (file)
index 3970a41..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// run-pass
-
-#![allow(dead_code)]
-
-trait Trait { fn dummy(&self) { } }
-
-#[derive(Debug)]
-struct Foo<T: Trait> {
-    foo: T,
-}
-
-#[derive(Debug)]
-struct Bar<T> where T: Trait {
-    bar: T,
-}
-
-impl Trait for isize {}
-
-fn main() {
-    let a = Foo { foo: 12 };
-    let b = Bar { bar: 12 };
-    println!("{:?} {:?}", a, b);
-}
diff --git a/src/test/ui/issues/issue-19660.rs b/src/test/ui/issues/issue-19660.rs
deleted file mode 100644 (file)
index 400ac31..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// error-pattern: requires `copy` lang_item
-
-#![feature(lang_items, start, no_core)]
-#![no_core]
-
-#[lang = "sized"]
-trait Sized { }
-
-struct S;
-
-#[start]
-fn main(_: isize, _: *const *const u8) -> isize {
-    let _ = S;
-    0
-}
diff --git a/src/test/ui/issues/issue-19660.stderr b/src/test/ui/issues/issue-19660.stderr
deleted file mode 100644 (file)
index f5d903f..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-error: requires `copy` lang_item
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-20091.rs b/src/test/ui/issues/issue-20091.rs
deleted file mode 100644 (file)
index 86cc79d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// run-pass
-#![allow(stable_features)]
-
-// ignore-emscripten no processes
-// ignore-sgx no processes
-
-#![feature(os)]
-
-#[cfg(unix)]
-fn main() {
-    use std::process::Command;
-    use std::env;
-    use std::os::unix::prelude::*;
-    use std::ffi::OsStr;
-
-    if env::args().len() == 1 {
-        assert!(Command::new(&env::current_exe().unwrap())
-                        .arg(<OsStr as OsStrExt>::from_bytes(b"\xff"))
-                        .status().unwrap().success())
-    }
-}
-
-#[cfg(windows)]
-fn main() {}
diff --git a/src/test/ui/issues/issue-20616-4.rs b/src/test/ui/issues/issue-20616-4.rs
deleted file mode 100644 (file)
index a71f47c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// We need all these 9 issue-20616-N.rs files
-// because we can only catch one parsing error at a time
-
-type Type_1_<'a, T> = &'a T;
-
-
-//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
-
-
-//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
-
-
-//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
-
-
-type Type_4<T> = Type_1_<'static,, T>;
-//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
-
-
-type Type_5_<'a> = Type_1_<'a, ()>;
-
-
-//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
-
-
-//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
-
-
-//type Type_7 = Box<(),,>; // error: expected type, found `,`
-
-
-//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
-
-
-//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/issues/issue-20616-4.stderr b/src/test/ui/issues/issue-20616-4.stderr
deleted file mode 100644 (file)
index 2b3b75f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected one of `>`, a const expression, lifetime, or type, found `,`
-  --> $DIR/issue-20616-4.rs:16:34
-   |
-LL | type Type_4<T> = Type_1_<'static,, T>;
-   |                                  ^ expected one of `>`, a const expression, lifetime, or type
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-20616-5.rs b/src/test/ui/issues/issue-20616-5.rs
deleted file mode 100644 (file)
index b96d09d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// We need all these 9 issue-20616-N.rs files
-// because we can only catch one parsing error at a time
-
-type Type_1_<'a, T> = &'a T;
-
-
-//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
-
-
-//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
-
-
-//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
-
-
-//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
-
-
-type Type_5_<'a> = Type_1_<'a, ()>;
-
-
-type Type_5<'a> = Type_1_<'a, (),,>;
-//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
-
-
-//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
-
-
-//type Type_7 = Box<(),,>; // error: expected type, found `,`
-
-
-//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
-
-
-//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/issues/issue-20616-5.stderr b/src/test/ui/issues/issue-20616-5.stderr
deleted file mode 100644 (file)
index 1ec1dbd..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected one of `>`, a const expression, lifetime, or type, found `,`
-  --> $DIR/issue-20616-5.rs:22:34
-   |
-LL | type Type_5<'a> = Type_1_<'a, (),,>;
-   |                                  ^ expected one of `>`, a const expression, lifetime, or type
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-20616-6.rs b/src/test/ui/issues/issue-20616-6.rs
deleted file mode 100644 (file)
index a2c45ec..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// We need all these 9 issue-20616-N.rs files
-// because we can only catch one parsing error at a time
-
-type Type_1_<'a, T> = &'a T;
-
-
-//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
-
-
-//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
-
-
-//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
-
-
-//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
-
-
-type Type_5_<'a> = Type_1_<'a, ()>;
-
-
-//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
-
-
-type Type_6 = Type_5_<'a,,>;
-//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
-
-
-//type Type_7 = Box<(),,>; // error: expected type, found `,`
-
-
-//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
-
-
-//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/issues/issue-20616-6.stderr b/src/test/ui/issues/issue-20616-6.stderr
deleted file mode 100644 (file)
index 7401abd..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected one of `>`, a const expression, lifetime, or type, found `,`
-  --> $DIR/issue-20616-6.rs:25:26
-   |
-LL | type Type_6 = Type_5_<'a,,>;
-   |                          ^ expected one of `>`, a const expression, lifetime, or type
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-20616-7.rs b/src/test/ui/issues/issue-20616-7.rs
deleted file mode 100644 (file)
index 67209c0..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// We need all these 9 issue-20616-N.rs files
-// because we can only catch one parsing error at a time
-
-type Type_1_<'a, T> = &'a T;
-
-
-//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
-
-
-//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
-
-
-//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
-
-
-//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
-
-
-type Type_5_<'a> = Type_1_<'a, ()>;
-
-
-//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
-
-
-//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
-
-
-type Type_7 = Box<(),,>;
-//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
-
-
-//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
-
-
-//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/issues/issue-20616-7.stderr b/src/test/ui/issues/issue-20616-7.stderr
deleted file mode 100644 (file)
index e2c3efe..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected one of `>`, a const expression, lifetime, or type, found `,`
-  --> $DIR/issue-20616-7.rs:28:22
-   |
-LL | type Type_7 = Box<(),,>;
-   |                      ^ expected one of `>`, a const expression, lifetime, or type
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-20823.rs b/src/test/ui/issues/issue-20823.rs
deleted file mode 100644 (file)
index 9e209d5..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// run-pass
-// compile-flags: --test
-
-#[test]
-pub fn foo() {}
diff --git a/src/test/ui/issues/issue-21356.rs b/src/test/ui/issues/issue-21356.rs
deleted file mode 100644 (file)
index ae62392..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#![allow(unused_macros)]
-
-macro_rules! test { ($wrong:t_ty ..) => () }
-                  //~^ ERROR: invalid fragment specifier `t_ty`
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-21356.stderr b/src/test/ui/issues/issue-21356.stderr
deleted file mode 100644 (file)
index 17014c6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-error: invalid fragment specifier `t_ty`
-  --> $DIR/issue-21356.rs:3:22
-   |
-LL | macro_rules! test { ($wrong:t_ty ..) => () }
-   |                      ^^^^^^^^^^^
-   |
-   = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-21475.rs b/src/test/ui/issues/issue-21475.rs
deleted file mode 100644 (file)
index b028fca..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// run-pass
-#![allow(unused_imports, overlapping_range_endpoints)]
-// pretty-expanded FIXME #23616
-
-use m::{START, END};
-
-fn main() {
-    match 42 {
-        m::START..=m::END => {},
-        0..=m::END => {},
-        m::START..=59 => {},
-        _  => {},
-    }
-}
-
-mod m {
-  pub const START: u32 = 4;
-  pub const END:   u32 = 14;
-}
diff --git a/src/test/ui/issues/issue-21520.rs b/src/test/ui/issues/issue-21520.rs
deleted file mode 100644 (file)
index ab4ac72..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// check-pass
-#![allow(dead_code)]
-// Test that the requirement (in `Bar`) that `T::Bar : 'static` does
-// not wind up propagating to `T`.
-
-// pretty-expanded FIXME #23616
-
-pub trait Foo {
-    type Bar;
-
-    fn foo(&self) -> Self;
-}
-
-pub struct Static<T:'static>(T);
-
-struct Bar<T:Foo>
-    where T::Bar : 'static
-{
-    x: Static<Option<T::Bar>>
-}
-
-fn main() { }
diff --git a/src/test/ui/issues/issue-22066.rs b/src/test/ui/issues/issue-22066.rs
deleted file mode 100644 (file)
index 8e8ba5d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// check-pass
-pub trait LineFormatter<'a> {
-    type Iter: Iterator<Item=&'a str> + 'a;
-    fn iter(&'a self, line: &'a str) -> Self::Iter;
-
-    fn dimensions(&'a self, line: &'a str) {
-        let iter: Self::Iter = self.iter(line);
-        <_ as IntoIterator>::into_iter(iter);
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-22463.rs b/src/test/ui/issues/issue-22463.rs
deleted file mode 100644 (file)
index fdf5a2f..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// run-pass
-macro_rules! items {
-    () => {
-        type A = ();
-        fn a() {}
-    }
-}
-
-trait Foo {
-    type A;
-    fn a();
-}
-
-impl Foo for () {
-    items!();
-}
-
-fn main() {
-
-}
diff --git a/src/test/ui/issues/issue-22828.rs b/src/test/ui/issues/issue-22828.rs
deleted file mode 100644 (file)
index adf4dd6..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-// Test transitive analysis for associated types. Collected types
-// should be normalized and new obligations generated.
-
-// pretty-expanded FIXME #23616
-
-trait Foo {
-    type A;
-    fn foo(&self) {}
-}
-
-impl Foo for usize {
-    type A = usize;
-}
-
-struct Bar<T: Foo> { inner: T::A }
-
-fn is_send<T: Send>() {}
-
-fn main() {
-    is_send::<Bar<usize>>();
-}
diff --git a/src/test/ui/issues/issue-23458.rs b/src/test/ui/issues/issue-23458.rs
deleted file mode 100644 (file)
index d640828..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#![feature(llvm_asm)]
-#![allow(deprecated)] // llvm_asm!
-// compile-flags: -Ccodegen-units=1
-// build-fail
-// only-x86_64
-
-fn main() {
-    unsafe {
-        llvm_asm!("int $3"); //~ ERROR too few operands for instruction
-                             //~| ERROR invalid operand in inline asm
-    }
-}
diff --git a/src/test/ui/issues/issue-23458.stderr b/src/test/ui/issues/issue-23458.stderr
deleted file mode 100644 (file)
index 69e458f..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error: invalid operand in inline asm: 'int $3'
-  --> $DIR/issue-23458.rs:9:9
-   |
-LL |         llvm_asm!("int $3");
-   |         ^
-
-error: too few operands for instruction
-  --> $DIR/issue-23458.rs:9:9
-   |
-LL |         llvm_asm!("int $3");
-   |         ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     int 
-   |     ^
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/issues/issue-23716.rs b/src/test/ui/issues/issue-23716.rs
deleted file mode 100644 (file)
index e9139c0..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-static foo: i32 = 0;
-
-fn bar(foo: i32) {}
-//~^ ERROR function parameters cannot shadow statics
-//~| cannot be named the same as a static
-
-mod submod {
-    pub static answer: i32 = 42;
-}
-
-use self::submod::answer;
-
-fn question(answer: i32) {}
-//~^ ERROR function parameters cannot shadow statics
-//~| cannot be named the same as a static
-fn main() {
-}
diff --git a/src/test/ui/issues/issue-23716.stderr b/src/test/ui/issues/issue-23716.stderr
deleted file mode 100644 (file)
index e7bebfb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0530]: function parameters cannot shadow statics
-  --> $DIR/issue-23716.rs:3:8
-   |
-LL | static foo: i32 = 0;
-   | -------------------- the static `foo` is defined here
-LL | 
-LL | fn bar(foo: i32) {}
-   |        ^^^ cannot be named the same as a static
-
-error[E0530]: function parameters cannot shadow statics
-  --> $DIR/issue-23716.rs:13:13
-   |
-LL | use self::submod::answer;
-   |     -------------------- the static `answer` is imported here
-LL | 
-LL | fn question(answer: i32) {}
-   |             ^^^^^^ cannot be named the same as a static
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0530`.
diff --git a/src/test/ui/issues/issue-23968-const-not-overflow.rs b/src/test/ui/issues/issue-23968-const-not-overflow.rs
deleted file mode 100644 (file)
index b959302..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// run-pass
-const U8_MAX_HALF: u8 = !0u8 / 2;
-const U16_MAX_HALF: u16 = !0u16 / 2;
-const U32_MAX_HALF: u32 = !0u32 / 2;
-const U64_MAX_HALF: u64 = !0u64 / 2;
-
-fn main() {
-    assert_eq!(U8_MAX_HALF, 0x7f);
-    assert_eq!(U16_MAX_HALF, 0x7fff);
-    assert_eq!(U32_MAX_HALF, 0x7fff_ffff);
-    assert_eq!(U64_MAX_HALF, 0x7fff_ffff_ffff_ffff);
-}
diff --git a/src/test/ui/issues/issue-24010.rs b/src/test/ui/issues/issue-24010.rs
deleted file mode 100644 (file)
index f181853..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// run-pass
-
-trait Foo: Fn(i32) -> i32 + Send {}
-
-impl<T: ?Sized + Fn(i32) -> i32 + Send> Foo for T {}
-
-fn wants_foo(f: Box<dyn Foo>) -> i32 {
-    f(42)
-}
-
-fn main() {
-    let f = Box::new(|x| x);
-    assert_eq!(wants_foo(f), 42);
-}
diff --git a/src/test/ui/issues/issue-24313.rs b/src/test/ui/issues/issue-24313.rs
deleted file mode 100644 (file)
index c28b4ca..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// run-pass
-// ignore-emscripten no threads
-// ignore-sgx no processes
-
-use std::thread;
-use std::env;
-use std::process::Command;
-
-struct Handle(i32);
-
-impl Drop for Handle {
-    fn drop(&mut self) { panic!(); }
-}
-
-thread_local!(static HANDLE: Handle = Handle(0));
-
-fn main() {
-    let args = env::args().collect::<Vec<_>>();
-    if args.len() == 1 {
-        let out = Command::new(&args[0]).arg("test").output().unwrap();
-        let stderr = std::str::from_utf8(&out.stderr).unwrap();
-        assert!(stderr.contains("panicked at 'explicit panic'"),
-                "bad failure message:\n{}\n", stderr);
-    } else {
-        // TLS dtors are not always run on process exit
-        thread::spawn(|| {
-            HANDLE.with(|h| {
-                println!("{}", h.0);
-            });
-        }).join().unwrap();
-    }
-}
diff --git a/src/test/ui/issues/issue-2444.rs b/src/test/ui/issues/issue-2444.rs
deleted file mode 100644 (file)
index ac0d050..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// run-fail
-// error-pattern:explicit panic
-// ignore-emscripten no processes
-
-use std::sync::Arc;
-
-enum Err<T> {
-    Errr(Arc<T>),
-}
-
-fn foo() -> Err<isize> {
-    panic!();
-}
-
-fn main() {
-    let _f = foo();
-}
diff --git a/src/test/ui/issues/issue-26251.rs b/src/test/ui/issues/issue-26251.rs
deleted file mode 100644 (file)
index a3e26a4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-#![allow(overlapping_range_endpoints)]
-
-fn main() {
-    let x = 'a';
-
-    let y = match x {
-        'a'..='b' if false => "one",
-        'a' => "two",
-        'a'..='b' => "three",
-        _ => panic!("what?"),
-    };
-
-    assert_eq!(y, "two");
-}
diff --git a/src/test/ui/issues/issue-26448-1.rs b/src/test/ui/issues/issue-26448-1.rs
deleted file mode 100644 (file)
index 7d2d75b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-pass
-
-pub trait Foo<T> {
-    fn foo(self) -> T;
-}
-
-impl<'a, T> Foo<T> for &'a str where &'a str: Into<T> {
-    fn foo(self) -> T {
-        panic!();
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-26448-2.rs b/src/test/ui/issues/issue-26448-2.rs
deleted file mode 100644 (file)
index c60e06c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// check-pass
-
-pub struct Bar<T> {
-    items: Vec<&'static str>,
-    inner: T,
-}
-
-pub trait IntoBar<T> {
-    fn into_bar(self) -> Bar<T>;
-}
-
-impl<'a, T> IntoBar<T> for &'a str where &'a str: Into<T> {
-    fn into_bar(self) -> Bar<T> {
-        Bar {
-            items: Vec::new(),
-            inner: self.into(),
-        }
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-26448-3.rs b/src/test/ui/issues/issue-26448-3.rs
deleted file mode 100644 (file)
index d48022c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// check-pass
-
-pub struct Item {
-    _inner: &'static str,
-}
-
-pub struct Bar<T> {
-    items: Vec<Item>,
-    inner: T,
-}
-
-pub trait IntoBar<T> {
-    fn into_bar(self) -> Bar<T>;
-}
-
-impl<'a, T> IntoBar<T> for &'a str where &'a str: Into<T> {
-    fn into_bar(self) -> Bar<T> {
-        Bar {
-            items: Vec::new(),
-            inner: self.into(),
-        }
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-26638.rs b/src/test/ui/issues/issue-26638.rs
deleted file mode 100644 (file)
index 72fe428..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
-//~^ ERROR missing lifetime specifier [E0106]
-
-fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
-//~^ ERROR missing lifetime specifier [E0106]
-
-fn parse_type_3() -> &str { unimplemented!() }
-//~^ ERROR missing lifetime specifier [E0106]
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr
deleted file mode 100644 (file)
index bb7cdcb..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-error[E0106]: missing lifetime specifier
-  --> $DIR/issue-26638.rs:1:62
-   |
-LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
-   |                     ------------------------------------     ^ expected named lifetime parameter
-   |
-   = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from
-help: consider introducing a named lifetime parameter
-   |
-LL | fn parse_type<'a>(iter: Box<dyn Iterator<Item=&str>+'static>) -> &'a str { iter.next() }
-   |              ++++                                                 ++
-
-error[E0106]: missing lifetime specifier
-  --> $DIR/issue-26638.rs:4:40
-   |
-LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
-   |                                        ^ expected named lifetime parameter
-   |
-   = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
-help: consider using the `'static` lifetime
-   |
-LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &'static str { iter() }
-   |                                        ~~~~~~~~
-
-error[E0106]: missing lifetime specifier
-  --> $DIR/issue-26638.rs:7:22
-   |
-LL | fn parse_type_3() -> &str { unimplemented!() }
-   |                      ^ 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 parse_type_3() -> &'static str { unimplemented!() }
-   |                      ~~~~~~~~
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/issues/issue-26996.rs b/src/test/ui/issues/issue-26996.rs
deleted file mode 100644 (file)
index 84037b7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// run-pass
-
-// This test is bogus (i.e., should be check-fail) during the period
-// where #54986 is implemented and #54987 is *not* implemented. For
-// now: just ignore it
-//
-// ignore-test
-
-// This test is checking that the write to `c.0` (which has been moved out of)
-// won't overwrite the state in `c2`.
-//
-// That's a fine thing to test when this code is accepted by the
-// compiler, and this code is being transcribed accordingly into
-// the ui test issue-21232-partial-init-and-use.rs
-
-fn main() {
-    let mut c = (1, "".to_owned());
-    match c {
-        c2 => {
-            c.0 = 2;
-            assert_eq!(c2.0, 1);
-        }
-    }
-}
diff --git a/src/test/ui/issues/issue-2748-b.rs b/src/test/ui/issues/issue-2748-b.rs
deleted file mode 100644 (file)
index 8df735a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-pass
-
-fn thing<'r>(x: &'r [isize]) -> &'r [isize] { x }
-
-pub fn main() {
-    let x = &[1,2,3];
-    let y = x;
-    let z = thing(x);
-    assert_eq!(z[2], x[2]);
-    assert_eq!(z[1], y[1]);
-}
diff --git a/src/test/ui/issues/issue-28324.mir.stderr b/src/test/ui/issues/issue-28324.mir.stderr
deleted file mode 100644 (file)
index aff8bf7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0133]: use of extern static is unsafe and requires unsafe function or block
-  --> $DIR/issue-28324.rs:8:24
-   |
-LL | pub static BAZ: u32 = *&error_message_count;
-   |                        ^^^^^^^^^^^^^^^^^^^^ use of extern static
-   |
-   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/issues/issue-28324.rs b/src/test/ui/issues/issue-28324.rs
deleted file mode 100644 (file)
index fbe83e3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// revisions: mir thir
-// [thir]compile-flags: -Z thir-unsafeck
-
-extern "C" {
-    static error_message_count: u32;
-}
-
-pub static BAZ: u32 = *&error_message_count;
-//~^ ERROR use of extern static is unsafe and requires
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-28324.thir.stderr b/src/test/ui/issues/issue-28324.thir.stderr
deleted file mode 100644 (file)
index c696c35..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0133]: use of extern static is unsafe and requires unsafe function or block
-  --> $DIR/issue-28324.rs:8:25
-   |
-LL | pub static BAZ: u32 = *&error_message_count;
-   |                         ^^^^^^^^^^^^^^^^^^^ use of extern static
-   |
-   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs b/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs
deleted file mode 100644 (file)
index 23fd86a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// run-pass
-
-// Demonstrate the use of the unguarded escape hatch with a type param in negative position
-// to assert that destructor will not access any dead data.
-//
-// Compare with ui/span/issue28498-reject-lifetime-param.rs
-
-// Demonstrate that a type param in negative position causes dropck to reject code
-// that might indirectly access previously dropped value.
-//
-// Compare with run-pass/issue28498-ugeh-with-passed-to-fn.rs
-
-#![feature(dropck_eyepatch)]
-
-#[derive(Debug)]
-struct ScribbleOnDrop(String);
-
-impl Drop for ScribbleOnDrop {
-    fn drop(&mut self) {
-        self.0 = format!("DROPPED");
-    }
-}
-
-struct Foo<T>(u32, T, Box<for <'r> fn(&'r T) -> String>);
-
-unsafe impl<#[may_dangle] T> Drop for Foo<T> {
-    fn drop(&mut self) {
-        // Use of `may_dangle` is sound, because destructor never passes a `self.1`
-        // to the callback (in `self.2`) despite having it available.
-        println!("Dropping Foo({}, _)", self.0);
-    }
-}
-
-fn callback(s: & &ScribbleOnDrop) -> String { format!("{:?}", s) }
-
-fn main() {
-    let (last_dropped, foo0);
-    let (foo1, first_dropped);
-
-    last_dropped = ScribbleOnDrop(format!("last"));
-    first_dropped = ScribbleOnDrop(format!("first"));
-    foo0 = Foo(0, &last_dropped, Box::new(callback));
-    foo1 = Foo(1, &first_dropped, Box::new(callback));
-
-    println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1);
-}
diff --git a/src/test/ui/issues/issue-28871.rs b/src/test/ui/issues/issue-28871.rs
deleted file mode 100644 (file)
index 210c783..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// check-pass
-// Regression test for #28871. The problem is that rustc encountered
-// two ways to project, one from a where clause and one from the where
-// clauses on the trait definition. (In fact, in this case, the where
-// clauses originated from the trait definition as well.) The true
-// cause of the error is that the trait definition where clauses are
-// not being normalized, and hence the two sources are considered in
-// conflict, and not a duplicate. Hacky solution is to prefer where
-// clauses over the data found in the trait definition.
-
-trait T {
-    type T;
-}
-
-struct S;
-impl T for S {
-    type T = S;
-}
-
-trait T2 {
-    type T: Iterator<Item=<S as T>::T>;
-}
-
-fn main() { }
diff --git a/src/test/ui/issues/issue-29084.rs b/src/test/ui/issues/issue-29084.rs
deleted file mode 100644 (file)
index d162526..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-macro_rules! foo {
-    ($d:expr) => {{
-        fn bar(d: u8) { }
-        bar(&mut $d);
-        //~^ ERROR mismatched types
-        //~| expected `u8`, found `&mut u8`
-    }}
-}
-
-fn main() {
-    foo!(0u8);
-    //~^ in this expansion of foo!
-}
diff --git a/src/test/ui/issues/issue-29084.stderr b/src/test/ui/issues/issue-29084.stderr
deleted file mode 100644 (file)
index a973e23..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-29084.rs:4:13
-   |
-LL |         bar(&mut $d);
-   |             ^^^^^^^ expected `u8`, found `&mut u8`
-...
-LL |     foo!(0u8);
-   |     --------- in this macro invocation
-   |
-   = note: this error originates in the macro `foo` (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 E0308`.
diff --git a/src/test/ui/issues/issue-3021-c.rs b/src/test/ui/issues/issue-3021-c.rs
deleted file mode 100644 (file)
index 94ed1fd..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-fn siphash<T>() {
-
-    trait U {
-        fn g(&self, x: T) -> T;  //~ ERROR can't use generic parameters from outer function
-        //~^ ERROR can't use generic parameters from outer function
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-3021-c.stderr b/src/test/ui/issues/issue-3021-c.stderr
deleted file mode 100644 (file)
index 8764ac8..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-error[E0401]: can't use generic parameters from outer function
-  --> $DIR/issue-3021-c.rs:4:24
-   |
-LL | fn siphash<T>() {
-   |            - type parameter from outer function
-...
-LL |         fn g(&self, x: T) -> T;
-   |            -           ^ use of generic parameter from outer function
-   |            |
-   |            help: try using a local generic parameter instead: `g<T>`
-
-error[E0401]: can't use generic parameters from outer function
-  --> $DIR/issue-3021-c.rs:4:30
-   |
-LL | fn siphash<T>() {
-   |            - type parameter from outer function
-...
-LL |         fn g(&self, x: T) -> T;
-   |            -                 ^ use of generic parameter from outer function
-   |            |
-   |            help: try using a local generic parameter instead: `g<T>`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0401`.
diff --git a/src/test/ui/issues/issue-3021.rs b/src/test/ui/issues/issue-3021.rs
deleted file mode 100644 (file)
index a672261..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-trait SipHash {
-    fn reset(&self);
-}
-
-fn siphash(k0 : u64) {
-    struct SipState {
-        v0: u64,
-    }
-
-    impl SipHash for SipState {
-        fn reset(&self) {
-           self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
-        }
-    }
-    panic!();
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-3021.stderr b/src/test/ui/issues/issue-3021.stderr
deleted file mode 100644 (file)
index d5b015e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0434]: can't capture dynamic environment in a fn item
-  --> $DIR/issue-3021.rs:12:22
-   |
-LL |            self.v0 = k0 ^ 0x736f6d6570736575;
-   |                      ^^
-   |
-   = help: use the `|| { ... }` closure form instead
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0434`.
diff --git a/src/test/ui/issues/issue-30225.rs b/src/test/ui/issues/issue-30225.rs
deleted file mode 100644 (file)
index 4231533..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-// Regression test for #30225, which was an ICE that would trigger as
-// a result of a poor interaction between trait result caching and
-// type inference. Specifically, at that time, unification could cause
-// unrelated type variables to become instantiated, if subtyping
-// relationships existed. These relationships are now propagated
-// through obligations and hence everything works out fine.
-
-trait Foo<U,V> : Sized {
-    fn foo(self, u: Option<U>, v: Option<V>) {}
-}
-
-struct A;
-struct B;
-
-impl Foo<A, B> for () {}      // impl A
-impl Foo<u32, u32> for u32 {} // impl B, creating ambiguity
-
-fn toxic() {
-    // cache the resolution <() as Foo<$0,$1>> = impl A
-    let u = None;
-    let v = None;
-    Foo::foo((), u, v);
-}
-
-fn bomb() {
-    let mut u = None; // type is Option<$0>
-    let mut v = None; // type is Option<$1>
-    let mut x = None; // type is Option<$2>
-
-    Foo::foo(x.unwrap(),u,v); // register <$2 as Foo<$0, $1>>
-    u = v; // mark $0 and $1 in a subtype relationship
-    //~^ ERROR mismatched types
-    x = Some(()); // set $2 = (), allowing impl selection
-                  // to proceed for <() as Foo<$0, $1>> = impl A.
-                  // kaboom, this *used* to trigge an ICE
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-30225.stderr b/src/test/ui/issues/issue-30225.stderr
deleted file mode 100644 (file)
index ccd05fa..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-30225.rs:31:9
-   |
-LL |     u = v; // mark $0 and $1 in a subtype relationship
-   |         ^ expected struct `A`, found struct `B`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-30355.rs b/src/test/ui/issues/issue-30355.rs
deleted file mode 100644 (file)
index 6ff5b37..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-pub struct X([u8]);
-
-pub static Y: &'static X = {
-    const Y: &'static [u8] = b"";
-    &X(*Y)
-    //~^ ERROR E0277
-};
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-30355.stderr b/src/test/ui/issues/issue-30355.stderr
deleted file mode 100644 (file)
index 71bbdf5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/issue-30355.rs:5:8
-   |
-LL |     &X(*Y)
-   |        ^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u8]`
-   = note: all function arguments must have a statically known size
-   = help: unsized fn params are gated as an unstable feature
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-31076.rs b/src/test/ui/issues/issue-31076.rs
deleted file mode 100644 (file)
index cdb196d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#![feature(no_core, lang_items)]
-#![no_core]
-
-#[lang="sized"]
-trait Sized {}
-
-#[lang="add"]
-trait Add<T> {}
-
-impl Add<i32> for i32 {}
-
-fn main() {
-    let x = 5 + 6;
-    //~^ ERROR cannot add `i32` to `{integer}`
-    let y = 5i32 + 6i32;
-    //~^ ERROR cannot add `i32` to `i32`
-}
diff --git a/src/test/ui/issues/issue-31076.stderr b/src/test/ui/issues/issue-31076.stderr
deleted file mode 100644 (file)
index ac0d9dc..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0369]: cannot add `i32` to `{integer}`
-  --> $DIR/issue-31076.rs:13:15
-   |
-LL |     let x = 5 + 6;
-   |             - ^ - i32
-   |             |
-   |             {integer}
-
-error[E0369]: cannot add `i32` to `i32`
-  --> $DIR/issue-31076.rs:15:18
-   |
-LL |     let y = 5i32 + 6i32;
-   |             ---- ^ ---- i32
-   |             |
-   |             i32
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/issues/issue-31804.rs b/src/test/ui/issues/issue-31804.rs
deleted file mode 100644 (file)
index d056b77..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// Test that error recovery in the parser to an EOF does not give an infinite
-// spew of errors.
-
-fn main() {
-    let
-} //~ ERROR expected pattern, found `}`
diff --git a/src/test/ui/issues/issue-31804.stderr b/src/test/ui/issues/issue-31804.stderr
deleted file mode 100644 (file)
index 76e68b0..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected pattern, found `}`
-  --> $DIR/issue-31804.rs:6:1
-   |
-LL | }
-   | ^ expected pattern
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-31845.rs b/src/test/ui/issues/issue-31845.rs
deleted file mode 100644 (file)
index f6dc115..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// Checks lexical scopes cannot see through normal module boundaries
-
-fn f() {
-    fn g() {}
-    mod foo {
-        fn h() {
-           g(); //~ ERROR cannot find function `g` in this scope
-        }
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-31845.stderr b/src/test/ui/issues/issue-31845.stderr
deleted file mode 100644 (file)
index 5628193..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0425]: cannot find function `g` in this scope
-  --> $DIR/issue-31845.rs:7:12
-   |
-LL |            g();
-   |            ^ 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/issues/issue-3211.rs b/src/test/ui/issues/issue-3211.rs
deleted file mode 100644 (file)
index 49dd4fa..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// run-pass
-pub fn main() {
-    let mut x = 0;
-    for _ in 0..4096 { x += 1; }
-    assert_eq!(x, 4096);
-    println!("x = {}", x);
-}
diff --git a/src/test/ui/issues/issue-32201.rs b/src/test/ui/issues/issue-32201.rs
deleted file mode 100644 (file)
index f27bb1c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-extern "C" {
-    fn foo(a: i32, ...);
-}
-
-fn bar(_: *const u8) {}
-
-fn main() {
-    unsafe {
-        foo(0, bar);
-        //~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function
-        //~| HELP cast the value to `fn(*const u8)`
-    }
-}
diff --git a/src/test/ui/issues/issue-32201.stderr b/src/test/ui/issues/issue-32201.stderr
deleted file mode 100644 (file)
index cedb587..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0617]: can't pass `fn(*const u8) {bar}` to variadic function
-  --> $DIR/issue-32201.rs:9:16
-   |
-LL |         foo(0, bar);
-   |                ^^^ help: cast the value to `fn(*const u8)`: `bar as fn(*const u8)`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0617`.
diff --git a/src/test/ui/issues/issue-333.rs b/src/test/ui/issues/issue-333.rs
deleted file mode 100644 (file)
index 0753aaa..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// run-pass
-
-fn quux<T>(x: T) -> T { let f = id::<T>; return f(x); }
-
-fn id<T>(x: T) -> T { return x; }
-
-pub fn main() { assert_eq!(quux(10), 10); }
diff --git a/src/test/ui/issues/issue-34028.rs b/src/test/ui/issues/issue-34028.rs
deleted file mode 100644 (file)
index d761c0c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// check-pass
-
-macro_rules! m {
-    () => { #[cfg(any())] fn f() {} }
-}
-
-trait T {}
-impl T for () { m!(); }
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-34171.rs b/src/test/ui/issues/issue-34171.rs
deleted file mode 100644 (file)
index 157c58c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// check-pass
-
-macro_rules! null { ($i:tt) => {} }
-macro_rules! apply_null {
-    ($i:item) => { null! { $i } }
-}
-
-fn main() {
-    apply_null!(#[cfg(all())] fn f() {});
-}
diff --git a/src/test/ui/issues/issue-34255-1.rs b/src/test/ui/issues/issue-34255-1.rs
deleted file mode 100644 (file)
index c70cd8b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-enum Test {
-    Drill {
-        field: i32,
-    }
-}
-
-fn main() {
-    Test::Drill(field: 42);
-    //~^ ERROR invalid `struct` delimiters or `fn` call arguments
-}
diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr
deleted file mode 100644 (file)
index fbff75e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-error: invalid `struct` delimiters or `fn` call arguments
-  --> $DIR/issue-34255-1.rs:8:5
-   |
-LL |     Test::Drill(field: 42);
-   |     ^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: if `Test::Drill` is a struct, use braces as delimiters
-   |
-LL |     Test::Drill { field: 42 };
-   |                 ~           ~
-help: if `Test::Drill` is a function, use the arguments directly
-   |
-LL -     Test::Drill(field: 42);
-LL +     Test::Drill(42);
-   | 
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-35546.rs b/src/test/ui/issues/issue-35546.rs
deleted file mode 100644 (file)
index 004679a..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// build-pass
-#![allow(dead_code)]
-// Regression test for #35546. Check that we are able to codegen
-// this. Before we had problems because of the drop glue signature
-// around dropping a trait object (specifically, when dropping the
-// `value` field of `Node<Send>`).
-
-struct Node<T: ?Sized + Send> {
-    next: Option<Box<Node<dyn Send>>>,
-    value: T,
-}
-
-fn clear(head: &mut Option<Box<Node<dyn Send>>>) {
-    match head.take() {
-        Some(node) => *head = node.next,
-        None => (),
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-37175.rs b/src/test/ui/issues/issue-37175.rs
deleted file mode 100644 (file)
index 9ec9d48..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// run-pass
-macro_rules! m { (<$t:ty>) => { stringify!($t) } }
-fn main() {
-    println!("{}", m!(<Vec<i32>>));
-}
diff --git a/src/test/ui/issues/issue-37366.rs b/src/test/ui/issues/issue-37366.rs
deleted file mode 100644 (file)
index acc2f3e..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// check-pass
-// ignore-emscripten
-
-#![feature(llvm_asm)]
-#![allow(deprecated)] // llvm_asm!
-
-macro_rules! interrupt_handler {
-    () => {
-        unsafe fn _interrupt_handler() {
-            llvm_asm!("pop  eax" :::: "intel");
-        }
-    }
-}
-interrupt_handler!{}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-37550.rs b/src/test/ui/issues/issue-37550.rs
deleted file mode 100644 (file)
index 35b63bd..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-const fn x() {
-    let t = true;
-    let x = || t; //~ ERROR function pointer
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-37550.stderr b/src/test/ui/issues/issue-37550.stderr
deleted file mode 100644 (file)
index 54b60df..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: function pointers cannot appear in constant functions
-  --> $DIR/issue-37550.rs:3:9
-   |
-LL |     let x = || t;
-   |         ^
-   |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
-   = help: add `#![feature(const_fn_fn_ptr_basics)]` 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/issues/issue-37991.rs b/src/test/ui/issues/issue-37991.rs
deleted file mode 100644 (file)
index a6ac4d5..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// run-pass
-
-const fn foo() -> i64 {
-    3
-}
-
-const fn bar(x: i64) -> i64 {
-    x*2
-}
-
-fn main() {
-    let val = &(foo() % 2);
-    assert_eq!(*val, 1);
-
-    let val2 = &(bar(1+1) % 3);
-    assert_eq!(*val2, 1);
-}
diff --git a/src/test/ui/issues/issue-38604.rs b/src/test/ui/issues/issue-38604.rs
deleted file mode 100644 (file)
index 002a3c4..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-trait Q<T:?Sized> {}
-trait Foo where u32: Q<Self> {
-    fn foo(&self);
-}
-
-impl Q<()> for u32 {}
-impl Foo for () {
-    fn foo(&self) {
-        println!("foo!");
-    }
-}
-
-fn main() {
-    let _f: Box<dyn Foo> = //~ ERROR `Foo` cannot be made into an object
-        Box::new(()); //~ ERROR `Foo` cannot be made into an object
-}
diff --git a/src/test/ui/issues/issue-38604.stderr b/src/test/ui/issues/issue-38604.stderr
deleted file mode 100644 (file)
index d41488c..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/issue-38604.rs:14:13
-   |
-LL |     let _f: 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/issue-38604.rs:2:22
-   |
-LL | trait Foo where u32: Q<Self> {
-   |       ---            ^^^^^^^ ...because it uses `Self` as a type parameter
-   |       |
-   |       this trait cannot be made into an object...
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/issue-38604.rs:15:9
-   |
-LL |         Box::new(());
-   |         ^^^^^^^^^^^^ `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/issue-38604.rs:2:22
-   |
-LL | trait Foo where u32: Q<Self> {
-   |       ---            ^^^^^^^ ...because it uses `Self` as a type parameter
-   |       |
-   |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<()>`
-   = note: required by cast to type `Box<dyn Foo>`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/issues/issue-39388.rs b/src/test/ui/issues/issue-39388.rs
deleted file mode 100644 (file)
index a8e31a6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#![allow(unused_macros)]
-
-macro_rules! assign {
-    (($($a:tt)*) = ($($b:tt))*) => { //~ ERROR expected one of: `*`, `+`, or `?`
-        $($a)* = $($b)*
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-39388.stderr b/src/test/ui/issues/issue-39388.stderr
deleted file mode 100644 (file)
index 62e7dff..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected one of: `*`, `+`, or `?`
-  --> $DIR/issue-39388.rs:4:22
-   |
-LL |     (($($a:tt)*) = ($($b:tt))*) => {
-   |                      ^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-3973.rs b/src/test/ui/issues/issue-3973.rs
deleted file mode 100644 (file)
index a5ed5b8..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-struct Point {
-    x: f64,
-    y: f64,
-}
-
-trait ToString_ {
-    fn to_string(&self) -> String;
-}
-
-impl ToString_ for Point {
-    fn new(x: f64, y: f64) -> Point {
-    //~^ ERROR method `new` is not a member of trait `ToString_`
-        Point { x: x, y: y }
-    }
-
-    fn to_string(&self) -> String {
-        format!("({}, {})", self.x, self.y)
-    }
-}
-
-fn main() {
-    let p = Point::new(0.0, 0.0);
-    //~^ ERROR no function or associated item named `new` found for struct `Point`
-    println!("{}", p.to_string());
-}
diff --git a/src/test/ui/issues/issue-3973.stderr b/src/test/ui/issues/issue-3973.stderr
deleted file mode 100644 (file)
index 63282e8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0407]: method `new` is not a member of trait `ToString_`
-  --> $DIR/issue-3973.rs:11:5
-   |
-LL | /     fn new(x: f64, y: f64) -> Point {
-LL | |
-LL | |         Point { x: x, y: y }
-LL | |     }
-   | |_____^ not a member of trait `ToString_`
-
-error[E0599]: no function or associated item named `new` found for struct `Point` in the current scope
-  --> $DIR/issue-3973.rs:22:20
-   |
-LL | struct Point {
-   | ------------ function or associated item `new` not found for this
-...
-LL |     let p = Point::new(0.0, 0.0);
-   |                    ^^^ function or associated item not found in `Point`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0407, E0599.
-For more information about an error, try `rustc --explain E0407`.
diff --git a/src/test/ui/issues/issue-39823.rs b/src/test/ui/issues/issue-39823.rs
deleted file mode 100644 (file)
index 148cf52..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// run-pass
-// aux-build:issue-39823.rs
-
-extern crate issue_39823;
-use issue_39823::{RemoteC, RemoteG};
-
-#[derive(Debug, PartialEq)]
-struct LocalC(u32);
-
-#[derive(Debug, PartialEq)]
-struct LocalG<T>(T);
-
-fn main() {
-    let virtual_localc : &dyn Fn(_) -> LocalC = &LocalC;
-    assert_eq!(virtual_localc(1), LocalC(1));
-
-    let virtual_localg : &dyn Fn(_) -> LocalG<u32> = &LocalG;
-    assert_eq!(virtual_localg(1), LocalG(1));
-
-    let virtual_remotec : &dyn Fn(_) -> RemoteC = &RemoteC;
-    assert_eq!(virtual_remotec(1), RemoteC(1));
-
-    let virtual_remoteg : &dyn Fn(_) -> RemoteG<u32> = &RemoteG;
-    assert_eq!(virtual_remoteg(1), RemoteG(1));
-}
diff --git a/src/test/ui/issues/issue-40770.rs b/src/test/ui/issues/issue-40770.rs
deleted file mode 100644 (file)
index c9713c1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-pass
-#![allow(unused_macros)]
-macro_rules! m {
-    ($e:expr) => {
-        macro_rules! n { () => { $e } }
-    }
-}
-
-fn main() {
-    m!(foo!());
-}
diff --git a/src/test/ui/issues/issue-40962.rs b/src/test/ui/issues/issue-40962.rs
deleted file mode 100644 (file)
index 7b91c06..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// check-pass
-macro_rules! m {
-    ($i:meta) => {
-        #[derive($i)]
-        struct S;
-    }
-}
-
-m!(Clone);
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-42463.rs b/src/test/ui/issues/issue-42463.rs
deleted file mode 100644 (file)
index 51d6ea3..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// run-pass
-use std::ops::{Deref, DerefMut};
-
-struct CheckedDeref<T, F> {
-    value: T,
-    check: F
-}
-
-impl<F: Fn(&T) -> bool, T> Deref for CheckedDeref<T, F> {
-    type Target = T;
-    fn deref(&self) -> &T {
-        assert!((self.check)(&self.value));
-        &self.value
-    }
-}
-
-impl<F: Fn(&T) -> bool, T> DerefMut for CheckedDeref<T, F> {
-    fn deref_mut(&mut self) -> &mut T {
-        assert!((self.check)(&self.value));
-        &mut self.value
-    }
-}
-
-
-fn main() {
-    let mut v = CheckedDeref {
-        value: vec![0],
-        check: |v: &Vec<_>| !v.is_empty()
-    };
-    v.push(1);
-    assert_eq!(*v, vec![0, 1]);
-}
diff --git a/src/test/ui/issues/issue-42679.rs b/src/test/ui/issues/issue-42679.rs
deleted file mode 100644 (file)
index 596309f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// run-pass
-#![feature(box_syntax)]
-#![feature(box_patterns)]
-
-#[derive(Debug, PartialEq)]
-enum Test {
-    Foo(usize),
-    Bar(isize),
-}
-
-fn main() {
-    let a = box Test::Foo(10);
-    let b = box Test::Bar(-20);
-    match (a, b) {
-        (_, box Test::Foo(_)) => unreachable!(),
-        (box Test::Foo(x), b) => {
-            assert_eq!(x, 10);
-            assert_eq!(b, box Test::Bar(-20));
-        },
-        _ => unreachable!(),
-    }
-}
diff --git a/src/test/ui/issues/issue-42747.rs b/src/test/ui/issues/issue-42747.rs
deleted file mode 100644 (file)
index fec6587..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// run-pass
-macro_rules! fooN {
-    ($cur:ident $prev:ty) => {
-        #[allow(dead_code)]
-        enum $cur {
-            Empty,
-            First($prev),
-            Second($prev),
-            Third($prev),
-            Fourth($prev),
-        }
-    }
-}
-
-fooN!(Foo0 ());
-fooN!(Foo1 Foo0);
-fooN!(Foo2 Foo1);
-fooN!(Foo3 Foo2);
-fooN!(Foo4 Foo3);
-fooN!(Foo5 Foo4);
-fooN!(Foo6 Foo5);
-fooN!(Foo7 Foo6);
-fooN!(Foo8 Foo7);
-fooN!(Foo9 Foo8);
-fooN!(Foo10 Foo9);
-fooN!(Foo11 Foo10);
-fooN!(Foo12 Foo11);
-fooN!(Foo13 Foo12);
-fooN!(Foo14 Foo13);
-fooN!(Foo15 Foo14);
-fooN!(Foo16 Foo15);
-fooN!(Foo17 Foo16);
-fooN!(Foo18 Foo17);
-fooN!(Foo19 Foo18);
-fooN!(Foo20 Foo19);
-fooN!(Foo21 Foo20);
-fooN!(Foo22 Foo21);
-fooN!(Foo23 Foo22);
-fooN!(Foo24 Foo23);
-fooN!(Foo25 Foo24);
-fooN!(Foo26 Foo25);
-fooN!(Foo27 Foo26);
-
-fn main() {
-    let _foo = Foo27::Empty;
-}
diff --git a/src/test/ui/issues/issue-43189.rs b/src/test/ui/issues/issue-43189.rs
deleted file mode 100644 (file)
index ce667a5..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// Issue 46112: An extern crate pub re-exporting libcore was causing
-// paths rooted from `std` to be misrendered in the diagnostic output.
-
-// ignore-windows
-// aux-build:xcrate-issue-43189-a.rs
-// aux-build:xcrate-issue-43189-b.rs
-
-extern crate xcrate_issue_43189_b;
-fn main() {
-    ().a();
-    //~^ ERROR no method named `a` found
-}
diff --git a/src/test/ui/issues/issue-43189.stderr b/src/test/ui/issues/issue-43189.stderr
deleted file mode 100644 (file)
index caf7530..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0599]: no method named `a` found for unit type `()` in the current scope
-  --> $DIR/issue-43189.rs:10:8
-   |
-LL |     ().a();
-   |        ^ method not found in `()`
-   |
-  ::: $DIR/auxiliary/xcrate-issue-43189-a.rs:5:8
-   |
-LL |     fn a(&self) {}
-   |        - the method is available for `()` here
-   |
-   = help: items from traits can only be used if the trait is in scope
-help: the following trait is implemented but not in scope; perhaps add a `use` for it:
-   |
-LL | use xcrate_issue_43189_b::xcrate_issue_43189_a::A;
-   |
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-44005.rs b/src/test/ui/issues/issue-44005.rs
deleted file mode 100644 (file)
index ab3b921..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-pub trait Foo<'a> {
-    type Bar;
-    fn foo(&'a self) -> Self::Bar;
-}
-
-impl<'a, 'b, T: 'a> Foo<'a> for &'b T {
-    type Bar = &'a T;
-    fn foo(&'a self) -> &'a T {
-        self
-    }
-}
-
-pub fn uncallable<T, F>(x: T, f: F)
-where
-    T: for<'a> Foo<'a>,
-    F: for<'a> Fn(<T as Foo<'a>>::Bar),
-{
-    f(x.foo());
-}
-
-pub fn catalyst(x: &i32) {
-    broken(x, |_| {})
-}
-
-pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
-    uncallable(x, |y| f(y));
-    //~^ type mismatch
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-44005.stderr b/src/test/ui/issues/issue-44005.stderr
deleted file mode 100644 (file)
index 307e444..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/issue-44005.rs:26:5
-   |
-LL |     uncallable(x, |y| f(y));
-   |     ^^^^^^^^^^    -------- found signature of `for<'r> fn(&'r i32) -> _`
-   |     |
-   |     expected signature of `for<'a> fn(<&i32 as Foo<'a>>::Bar) -> _`
-   |
-note: required by a bound in `uncallable`
-  --> $DIR/issue-44005.rs:16:8
-   |
-LL | pub fn uncallable<T, F>(x: T, f: F)
-   |        ---------- required by a bound in this
-...
-LL |     F: for<'a> Fn(<T as Foo<'a>>::Bar),
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `uncallable`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0631`.
diff --git a/src/test/ui/issues/issue-4401.rs b/src/test/ui/issues/issue-4401.rs
deleted file mode 100644 (file)
index fef73fb..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// run-pass
-pub fn main() {
-    let mut count = 0;
-    for _ in 0..999_999 { count += 1; }
-    assert_eq!(count, 999_999);
-    println!("{}", count);
-}
diff --git a/src/test/ui/issues/issue-4448.rs b/src/test/ui/issues/issue-4448.rs
deleted file mode 100644 (file)
index 27d0326..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-// ignore-emscripten no threads support
-
-use std::sync::mpsc::channel;
-use std::thread;
-
-pub fn main() {
-    let (tx, rx) = channel::<&'static str>();
-
-    let t = thread::spawn(move|| {
-        assert_eq!(rx.recv().unwrap(), "hello, world");
-    });
-
-    tx.send("hello, world").unwrap();
-    t.join().ok().unwrap();
-}
diff --git a/src/test/ui/issues/issue-45124.rs b/src/test/ui/issues/issue-45124.rs
deleted file mode 100644 (file)
index 942014c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// run-pass
-#![allow(unreachable_code)]
-// compile-flags: --edition 2018
-
-#![feature(try_blocks)]
-
-fn main() {
-    let mut a = 0;
-    let () = {
-        let _: Result<(), ()> = try {
-            let _ = Err(())?;
-            return
-        };
-        a += 1;
-    };
-    a += 2;
-    assert_eq!(a, 3);
-}
diff --git a/src/test/ui/issues/issue-45152.rs b/src/test/ui/issues/issue-45152.rs
deleted file mode 100644 (file)
index fb1c9fb..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-#![allow(unused_variables)]
-#![feature(unsize, coerce_unsized)]
-
-#[repr(packed)]
-struct UnalignedPtr<'a, T: ?Sized>
-    where T: 'a,
-{
-    data: &'a T,
-}
-
-fn main() {
-
-    impl<'a, T, U> std::ops::CoerceUnsized<UnalignedPtr<'a, U>> for UnalignedPtr<'a, T>
-        where
-        T: std::marker::Unsize<U> + ?Sized,
-        U: ?Sized,
-    { }
-
-    let arr = [1, 2, 3];
-    let arr_unaligned: UnalignedPtr<[i32; 3]> = UnalignedPtr { data: &arr };
-    let arr_unaligned: UnalignedPtr<[i32]> = arr_unaligned;
-}
diff --git a/src/test/ui/issues/issue-46095.rs b/src/test/ui/issues/issue-46095.rs
deleted file mode 100644 (file)
index 59ddb60..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// run-pass
-struct A;
-
-impl A {
-    fn take_mutably(&mut self) {}
-}
-
-fn identity<T>(t: T) -> T {
-    t
-}
-
-// Issue 46095
-// Built-in indexing should be used even when the index is not
-// trivially an integer
-// Overloaded indexing would cause wrapped to be borrowed mutably
-
-fn main() {
-    let mut a1 = A;
-    let mut a2 = A;
-
-    let wrapped = [&mut a1, &mut a2];
-
-    {
-        wrapped[0 + 1 - 1].take_mutably();
-    }
-
-    {
-        wrapped[identity(0)].take_mutably();
-    }
-}
diff --git a/src/test/ui/issues/issue-46112.rs b/src/test/ui/issues/issue-46112.rs
deleted file mode 100644 (file)
index 0cdd2c2..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// Issue 46112: An extern crate pub re-exporting libcore was causing
-// paths rooted from `std` to be misrendered in the diagnostic output.
-
-// ignore-windows
-// aux-build:xcrate-issue-46112-rexport-core.rs
-
-extern crate xcrate_issue_46112_rexport_core;
-fn test(r: Result<Option<()>, &'static str>) { }
-fn main() { test(Ok(())); }
-//~^ mismatched types
diff --git a/src/test/ui/issues/issue-46112.stderr b/src/test/ui/issues/issue-46112.stderr
deleted file mode 100644 (file)
index ec05fbe..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-46112.rs:9:21
-   |
-LL | fn main() { test(Ok(())); }
-   |                     ^^
-   |                     |
-   |                     expected enum `Option`, found `()`
-   |                     help: try using a variant of the expected enum: `Some(())`
-   |
-   = note:   expected enum `Option<()>`
-           found unit type `()`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-47139-1.rs b/src/test/ui/issues/issue-47139-1.rs
deleted file mode 100644 (file)
index c55fc34..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-// run-pass
-// Regression test for issue #47139:
-//
-// Coherence was encountering an (unnecessary) overflow trying to
-// decide if the two impls of dummy overlap.
-//
-// The overflow went something like:
-//
-// - `&'a ?T: Insertable` ?
-// - let ?T = Option<?U> ?
-// - `Option<?U>: Insertable` ?
-// - `Option<&'a ?U>: Insertable` ?
-// - `&'a ?U: Insertable` ?
-//
-// While somewhere in the middle, a projection would occur, which
-// broke cycle detection.
-//
-// It turned out that this cycle was being kicked off due to some
-// extended diagnostic attempts in coherence, so removing those
-// sidestepped the issue for now.
-
-#![allow(dead_code)]
-
-pub trait Insertable {
-    type Values;
-
-    fn values(self) -> Self::Values;
-}
-
-impl<T> Insertable for Option<T>
-    where
-    T: Insertable,
-    T::Values: Default,
-{
-    type Values = T::Values;
-
-    fn values(self) -> Self::Values {
-        self.map(Insertable::values).unwrap_or_default()
-    }
-}
-
-impl<'a, T> Insertable for &'a Option<T>
-    where
-    Option<&'a T>: Insertable,
-{
-    type Values = <Option<&'a T> as Insertable>::Values;
-
-    fn values(self) -> Self::Values {
-        self.as_ref().values()
-    }
-}
-
-impl<'a, T> Insertable for &'a [T]
-{
-    type Values = Self;
-
-    fn values(self) -> Self::Values {
-        self
-    }
-}
-
-trait Unimplemented { }
-
-trait Dummy { }
-
-struct Foo<T> { t: T }
-
-impl<'a, U> Dummy for Foo<&'a U>
-    where &'a U: Insertable
-{
-}
-
-impl<T> Dummy for T
-    where T: Unimplemented
-{ }
-
-fn main() {
-}
diff --git a/src/test/ui/issues/issue-49040.rs b/src/test/ui/issues/issue-49040.rs
deleted file mode 100644 (file)
index b7a541d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#![allow(unused_variables)]; //~ ERROR expected item, found `;`
-//~^ ERROR `main` function
-fn foo() {}
diff --git a/src/test/ui/issues/issue-49040.stderr b/src/test/ui/issues/issue-49040.stderr
deleted file mode 100644 (file)
index 56befe3..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error: expected item, found `;`
-  --> $DIR/issue-49040.rs:1:28
-   |
-LL | #![allow(unused_variables)];
-   |                            ^ help: remove this semicolon
-
-error[E0601]: `main` function not found in crate `issue_49040`
-  --> $DIR/issue-49040.rs:1:1
-   |
-LL | #![allow(unused_variables)];
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ consider adding a `main` function to `$DIR/issue-49040.rs`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/issues/issue-49579.rs b/src/test/ui/issues/issue-49579.rs
deleted file mode 100644 (file)
index 98de014..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// check-pass
-
-fn fibs(n: u32) -> impl Iterator<Item=u128> {
-    (0 .. n)
-    .scan((0, 1), |st, _| {
-        *st = (st.1, st.0 + st.1);
-        Some(*st)
-    })
-    .map(&|(f, _)| f)
-}
-
-fn main() {
-    println!("{:?}", fibs(10).collect::<Vec<_>>());
-}
diff --git a/src/test/ui/issues/issue-49685.rs b/src/test/ui/issues/issue-49685.rs
deleted file mode 100644 (file)
index fb328d6..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-pass
-// Regression test for #49685: drop elaboration was not revealing the
-// value of `impl Trait` returns, leading to an ICE.
-
-fn main() {
-    let _ = Some(())
-        .into_iter()
-        .flat_map(|_| Some(()).into_iter().flat_map(func));
-}
-
-fn func(_: ()) -> impl Iterator<Item = ()> {
-    Some(()).into_iter().flat_map(|_| vec![])
-}
diff --git a/src/test/ui/issues/issue-50731.rs b/src/test/ui/issues/issue-50731.rs
deleted file mode 100644 (file)
index 209c1e1..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// run-pass
-enum Void {}
-fn foo(_: Result<(Void, u32), (Void, String)>) {}
-fn main() {
-    let _: fn(_) = foo;
-}
diff --git a/src/test/ui/issues/issue-5099.rs b/src/test/ui/issues/issue-5099.rs
deleted file mode 100644 (file)
index b5abccb..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-trait B <A> {
-    fn a() -> A {
-        this.a //~ ERROR cannot find value `this` in this scope
-    }
-    fn b(x: i32) {
-        this.b(x); //~ ERROR cannot find value `this` in this scope
-    }
-    fn c() {
-        let _ = || this.a; //~ ERROR cannot find value `this` in this scope
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-5099.stderr b/src/test/ui/issues/issue-5099.stderr
deleted file mode 100644 (file)
index e9b2a9c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-error[E0425]: cannot find value `this` in this scope
-  --> $DIR/issue-5099.rs:3:9
-   |
-LL |         this.a
-   |         ^^^^ not found in this scope
-   |
-help: you might have meant to use `self` here instead
-   |
-LL |         self.a
-   |         ~~~~
-help: if you meant to use `self`, you are also missing a `self` receiver argument
-   |
-LL |     fn a(&self) -> A {
-   |          +++++
-
-error[E0425]: cannot find value `this` in this scope
-  --> $DIR/issue-5099.rs:6:9
-   |
-LL |         this.b(x);
-   |         ^^^^ not found in this scope
-   |
-help: you might have meant to use `self` here instead
-   |
-LL |         self.b(x);
-   |         ~~~~
-help: if you meant to use `self`, you are also missing a `self` receiver argument
-   |
-LL |     fn b(&self, x: i32) {
-   |          ++++++
-
-error[E0425]: cannot find value `this` in this scope
-  --> $DIR/issue-5099.rs:9:20
-   |
-LL |         let _ = || this.a;
-   |                    ^^^^ not found in this scope
-   |
-help: you might have meant to use `self` here instead
-   |
-LL |         let _ = || self.a;
-   |                    ~~~~
-help: if you meant to use `self`, you are also missing a `self` receiver argument
-   |
-LL |     fn c(&self) {
-   |          +++++
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/issues/issue-50993.rs b/src/test/ui/issues/issue-50993.rs
deleted file mode 100644 (file)
index e6a9451..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// compile-flags: --crate-type dylib --target thumbv7em-none-eabihf
-// needs-llvm-components: arm
-// build-pass
-// error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf`
-
-#![feature(no_core)]
-
-#![no_std]
-#![no_core]
diff --git a/src/test/ui/issues/issue-50993.stderr b/src/test/ui/issues/issue-50993.stderr
deleted file mode 100644 (file)
index 45cbfef..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-warning: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf`
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/issues/issue-51185.rs b/src/test/ui/issues/issue-51185.rs
deleted file mode 100644 (file)
index 52a2b25..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-pass
-fn foo() -> impl Into<for<'a> fn(&'a ())> {
-    (|_| {}) as for<'a> fn(&'a ())
-}
-
-fn main() {
-    foo().into()(&());
-}
diff --git a/src/test/ui/issues/issue-51345.rs b/src/test/ui/issues/issue-51345.rs
deleted file mode 100644 (file)
index 15571e8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-pass
-#![allow(unreachable_code)]
-
-fn main() {
-    let mut v = Vec::new();
-
-    loop { v.push(break) }
-}
diff --git a/src/test/ui/issues/issue-51582.rs b/src/test/ui/issues/issue-51582.rs
deleted file mode 100644 (file)
index 40a70c6..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// run-pass
-#![feature(core_intrinsics)]
-
-#[repr(i8)]
-pub enum Enum {
-    VariantA,
-    VariantB,
-}
-
-fn make_b() -> Enum { Enum::VariantB }
-
-fn main() {
-    assert_eq!(1, make_b() as i8);
-    assert_eq!(1, make_b() as u8);
-    assert_eq!(1, make_b() as i32);
-    assert_eq!(1, make_b() as u32);
-    assert_eq!(1, std::intrinsics::discriminant_value(&make_b()));
-}
diff --git a/src/test/ui/issues/issue-53787-inline-assembler-macro.rs b/src/test/ui/issues/issue-53787-inline-assembler-macro.rs
deleted file mode 100644 (file)
index d9fe7ca..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Regression test for Issue #53787: Fix ICE when creating a label in inline assembler with macros.
-
-// build-fail
-// ignore-emscripten
-
-#![feature(llvm_asm)]
-#![allow(deprecated)] // llvm_asm!
-
-macro_rules! fake_jump {
-    ($id:expr) => {
-        unsafe {
-            llvm_asm!(
-            "
-            jmp $0
-            lea eax, [ebx]
-            xor eax, 0xDEADBEEF
-            retn
-            $0:
-            "::"0"($id)::"volatile", "intel");
-        }
-    };
-}
-
-fn main() {
-    fake_jump!("FirstFunc"); //~ ERROR invalid value for constraint in inline assembly
-    println!("Hello, world!");
-}
diff --git a/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr b/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr
deleted file mode 100644 (file)
index fd755e3..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/issue-53787-inline-assembler-macro.rs:25:16
-   |
-LL |     fake_jump!("FirstFunc");
-   |                ^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0669`.
diff --git a/src/test/ui/issues/issue-54467.rs b/src/test/ui/issues/issue-54467.rs
deleted file mode 100644 (file)
index 734bf27..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// run-pass
-
-pub trait Stream {
-    type Item;
-    type Error;
-}
-
-pub trait ParseError<I> {
-    type Output;
-}
-
-impl ParseError<char> for u32 {
-    type Output = ();
-}
-
-impl Stream for () {
-    type Item = char;
-    type Error = u32;
-}
-
-pub struct Lex<'a, I>
-    where I: Stream,
-          I::Error: ParseError<char>,
-          <<I as Stream>::Error as ParseError<char>>::Output: 'a
-{
-    x: &'a <I::Error as ParseError<char>>::Output
-}
-
-pub struct Reserved<'a, I> where
-    I: Stream<Item=char> + 'a,
-    I::Error: ParseError<I::Item>,
-    <<I as Stream>::Error as ParseError<char>>::Output: 'a
-
-{
-    x: Lex<'a, I>
-}
-
-fn main() {
-    let r: Reserved<()> = Reserved {
-        x: Lex {
-            x: &()
-        }
-    };
-
-    let _v = r.x.x;
-}
diff --git a/src/test/ui/issues/issue-56031.rs b/src/test/ui/issues/issue-56031.rs
deleted file mode 100644 (file)
index b68f568..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-struct T;
-
-impl for T {}
-//~^ ERROR missing trait in a trait impl
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-56031.stderr b/src/test/ui/issues/issue-56031.stderr
deleted file mode 100644 (file)
index 7ee5bc6..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-error: missing trait in a trait impl
-  --> $DIR/issue-56031.rs:3:5
-   |
-LL | impl for T {}
-   |     ^
-   |
-help: add a trait here
-   |
-LL | impl Trait for T {}
-   |      +++++
-help: for an inherent impl, drop this `for`
-   |
-LL - impl for T {}
-LL + impl T {}
-   | 
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-57410-1.rs b/src/test/ui/issues/issue-57410-1.rs
deleted file mode 100644 (file)
index d825cb1..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// check-pass
-
-// Originally from #53925.
-// Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`.
-
-#![deny(unreachable_pub)]
-
-mod foo {
-    mod bar {
-        pub struct Bar;
-    }
-
-    pub use self::bar::Bar;
-}
-
-pub use foo::Bar;
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-57597.rs b/src/test/ui/issues/issue-57597.rs
deleted file mode 100644 (file)
index ebeb3fe..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-// Regression test for #57597.
-//
-// Make sure that nested matchers work correctly rather than causing an infinite loop or crash.
-
-// edition:2018
-
-macro_rules! foo1 {
-    ($($($i:ident)?)+) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo2 {
-    ($($($i:ident)?)*) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo3 {
-    ($($($i:ident)?)?) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo4 {
-    ($($($($i:ident)?)?)?) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo5 {
-    ($($($($i:ident)*)?)?) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo6 {
-    ($($($($i:ident)?)*)?) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo7 {
-    ($($($($i:ident)?)?)*) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo8 {
-    ($($($($i:ident)*)*)?) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo9 {
-    ($($($($i:ident)?)*)*) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo10 {
-    ($($($($i:ident)?)*)+) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo11 {
-    ($($($($i:ident)+)?)*) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-macro_rules! foo12 {
-    ($($($($i:ident)+)*)?) => {};
-    //~^ ERROR repetition matches empty token tree
-}
-
-fn main() {
-    foo1!();
-    foo2!();
-    foo3!();
-    foo4!();
-    foo5!();
-    foo6!();
-    foo7!();
-    foo8!();
-    foo9!();
-    foo10!();
-    foo11!();
-    foo12!();
-}
diff --git a/src/test/ui/issues/issue-57597.stderr b/src/test/ui/issues/issue-57597.stderr
deleted file mode 100644 (file)
index 0a02ac8..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:8:7
-   |
-LL |     ($($($i:ident)?)+) => {};
-   |       ^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:13:7
-   |
-LL |     ($($($i:ident)?)*) => {};
-   |       ^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:18:7
-   |
-LL |     ($($($i:ident)?)?) => {};
-   |       ^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:23:7
-   |
-LL |     ($($($($i:ident)?)?)?) => {};
-   |       ^^^^^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:28:7
-   |
-LL |     ($($($($i:ident)*)?)?) => {};
-   |       ^^^^^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:33:7
-   |
-LL |     ($($($($i:ident)?)*)?) => {};
-   |       ^^^^^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:38:7
-   |
-LL |     ($($($($i:ident)?)?)*) => {};
-   |       ^^^^^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:43:7
-   |
-LL |     ($($($($i:ident)*)*)?) => {};
-   |       ^^^^^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:48:7
-   |
-LL |     ($($($($i:ident)?)*)*) => {};
-   |       ^^^^^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:53:7
-   |
-LL |     ($($($($i:ident)?)*)+) => {};
-   |       ^^^^^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:58:7
-   |
-LL |     ($($($($i:ident)+)?)*) => {};
-   |       ^^^^^^^^^^^^^^^^^^
-
-error: repetition matches empty token tree
-  --> $DIR/issue-57597.rs:63:7
-   |
-LL |     ($($($($i:ident)+)*)?) => {};
-   |       ^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 12 previous errors
-
diff --git a/src/test/ui/issues/issue-58319.rs b/src/test/ui/issues/issue-58319.rs
deleted file mode 100644 (file)
index 757307d..0000000
+++ /dev/null
@@ -1,621 +0,0 @@
-// run-pass
-fn main() {}
-#[derive(Clone)]
-pub struct Little;
-#[derive(Clone)]
-pub struct Big(
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-    Little,
-);
diff --git a/src/test/ui/issues/issue-59029-1.rs b/src/test/ui/issues/issue-59029-1.rs
deleted file mode 100644 (file)
index 8ab47a4..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#![feature(trait_alias)]
-
-trait Svc<Req> { type Res; }
-
-trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
-//~^ ERROR associated type `Res` not found for `Self`
-//~| ERROR associated type `Res` not found for `Self`
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-59029-1.stderr b/src/test/ui/issues/issue-59029-1.stderr
deleted file mode 100644 (file)
index 53cdb8b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0220]: associated type `Res` not found for `Self`
-  --> $DIR/issue-59029-1.rs:5:52
-   |
-LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
-   |                                                    ^^^ associated type `Res` not found
-
-error[E0220]: associated type `Res` not found for `Self`
-  --> $DIR/issue-59029-1.rs:5:52
-   |
-LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
-   |                                                    ^^^ associated type `Res` not found
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0220`.
diff --git a/src/test/ui/issues/issue-59508-1.rs b/src/test/ui/issues/issue-59508-1.rs
deleted file mode 100644 (file)
index 6376c42..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#![allow(dead_code)]
-#![feature(const_generics_defaults)]
-
-// This test checks that generic parameter re-ordering diagnostic suggestions mention that
-// consts come after types and lifetimes when the `const_generics_defaults` feature is enabled.
-// We cannot run rustfix on this test because of the above const generics warning.
-
-struct A;
-
-impl A {
-    pub fn do_things<T, 'a, 'b: 'a>() {
-    //~^ ERROR lifetime parameters must be declared prior to type parameters
-        println!("panic");
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-59508-1.stderr b/src/test/ui/issues/issue-59508-1.stderr
deleted file mode 100644 (file)
index df244f0..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetime parameters must be declared prior to type parameters
-  --> $DIR/issue-59508-1.rs:11:25
-   |
-LL |     pub fn do_things<T, 'a, 'b: 'a>() {
-   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b: 'a, T>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-59508.fixed b/src/test/ui/issues/issue-59508.fixed
deleted file mode 100644 (file)
index b5c60a1..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-rustfix
-
-#![allow(dead_code)]
-
-// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
-
-struct A;
-
-impl A {
-    pub fn do_things<'a, 'b: 'a, T>() {
-    //~^ ERROR lifetime parameters must be declared prior to type parameters
-        println!("panic");
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-59508.rs b/src/test/ui/issues/issue-59508.rs
deleted file mode 100644 (file)
index 0b39c5d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-rustfix
-
-#![allow(dead_code)]
-
-// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
-
-struct A;
-
-impl A {
-    pub fn do_things<T, 'a, 'b: 'a>() {
-    //~^ ERROR lifetime parameters must be declared prior to type parameters
-        println!("panic");
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-59508.stderr b/src/test/ui/issues/issue-59508.stderr
deleted file mode 100644 (file)
index 33e967c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetime parameters must be declared prior to type parameters
-  --> $DIR/issue-59508.rs:10:25
-   |
-LL |     pub fn do_things<T, 'a, 'b: 'a>() {
-   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-60283.rs b/src/test/ui/issues/issue-60283.rs
deleted file mode 100644 (file)
index c63b154..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-pub trait Trait<'a> {
-    type Item;
-}
-
-impl<'a> Trait<'a> for () {
-    type Item = ();
-}
-
-pub fn foo<T, F>(_: T, _: F)
-where
-    T: for<'a> Trait<'a>,
-    F: for<'a> FnMut(<T as Trait<'a>>::Item),
-{
-}
-
-fn main() {
-    foo((), drop)
-    //~^ ERROR type mismatch in function arguments
-    //~| ERROR size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
-}
diff --git a/src/test/ui/issues/issue-60283.stderr b/src/test/ui/issues/issue-60283.stderr
deleted file mode 100644 (file)
index 34893cd..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-error[E0631]: type mismatch in function arguments
-  --> $DIR/issue-60283.rs:17:13
-   |
-LL |     foo((), drop)
-   |     ---     ^^^^
-   |     |       |
-   |     |       expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
-   |     |       found signature of `fn(()) -> _`
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `foo`
-  --> $DIR/issue-60283.rs:12:16
-   |
-LL | pub fn foo<T, F>(_: T, _: F)
-   |        --- required by a bound in this
-...
-LL |     F: for<'a> FnMut(<T as Trait<'a>>::Item),
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
-
-error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
-  --> $DIR/issue-60283.rs:17:13
-   |
-LL |     foo((), drop)
-   |     ---     ^^^^ doesn't have a size known at compile-time
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Sized` is not implemented for `<() as Trait<'_>>::Item`
-note: required by a bound in `std::mem::drop`
-  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-   |
-LL | pub fn drop<T>(_x: T) {}
-   |             ^ required by this bound in `std::mem::drop`
-help: consider further restricting the associated type
-   |
-LL | fn main() where <() as Trait<'_>>::Item: Sized {
-   |           ++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0277, E0631.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-60662.rs b/src/test/ui/issues/issue-60662.rs
deleted file mode 100644 (file)
index b9faa66..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// check-pass
-// compile-flags: -Z unpretty=hir
-
-#![feature(type_alias_impl_trait)]
-
-trait Animal {}
-
-fn main() {
-    pub type ServeFut = impl Animal;
-}
diff --git a/src/test/ui/issues/issue-60662.stdout b/src/test/ui/issues/issue-60662.stdout
deleted file mode 100644 (file)
index 14a49f2..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// check-pass
-// compile-flags: -Z unpretty=hir
-
-#![feature(type_alias_impl_trait)]
-#[prelude_import]
-use ::std::prelude::rust_2015::*;
-#[macro_use]
-extern crate std;
-
-trait Animal { }
-
-fn main() {
-              pub type ServeFut = /*impl Trait*/;
-          }
diff --git a/src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs b/src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs
deleted file mode 100644 (file)
index de7d6a0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Issue 61711: A crate pub re-exporting `crate` was causing an
-// infinite loop.
-
-// edition:2018
-// aux-build:xcrate-issue-61711-b.rs
-// compile-flags:--extern xcrate_issue_61711_b
-
-// build-pass
-
-fn f<F: Fn(xcrate_issue_61711_b::Struct)>(_: F) { }
-fn main() { }
diff --git a/src/test/ui/issues/issue-61882-2.rs b/src/test/ui/issues/issue-61882-2.rs
deleted file mode 100644 (file)
index 1209b54..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-struct A<T>(T);
-
-impl A<&'static u8> {
-    fn f() {
-        let x = 0;
-        Self(&x);
-        //~^ ERROR `x` does not live long enough
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-61882-2.stderr b/src/test/ui/issues/issue-61882-2.stderr
deleted file mode 100644 (file)
index 0b8e134..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0597]: `x` does not live long enough
-  --> $DIR/issue-61882-2.rs:6:14
-   |
-LL |         Self(&x);
-   |              ^^
-   |              |
-   |              borrowed value does not live long enough
-   |              this usage requires that `x` is borrowed for `'static`
-LL |
-LL |     }
-   |     - `x` 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/issues/issue-61882.rs b/src/test/ui/issues/issue-61882.rs
deleted file mode 100644 (file)
index 013398b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-struct A<T>(T);
-
-impl A<bool> {
-    const B: A<u8> = Self(0);
-    //~^ ERROR mismatched types
-    //~| ERROR mismatched types
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-61882.stderr b/src/test/ui/issues/issue-61882.stderr
deleted file mode 100644 (file)
index 09ffe8e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-61882.rs:4:27
-   |
-LL |     const B: A<u8> = Self(0);
-   |                           ^ expected `bool`, found integer
-
-error[E0308]: mismatched types
-  --> $DIR/issue-61882.rs:4:22
-   |
-LL |     const B: A<u8> = Self(0);
-   |                      ^^^^^^^ expected `u8`, found `bool`
-   |
-   = note: expected struct `A<u8>`
-              found struct `A<bool>`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-63364.rs b/src/test/ui/issues/issue-63364.rs
deleted file mode 100644 (file)
index 5223267..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-fn part(_: u16) -> u32 {
-    1
-}
-
-fn main() {
-    for n in 100_000.. {
-    //~^ ERROR: literal out of range for `u16`
-        let _ = part(n);
-    }
-}
diff --git a/src/test/ui/issues/issue-63364.stderr b/src/test/ui/issues/issue-63364.stderr
deleted file mode 100644 (file)
index 0375359..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error: literal out of range for `u16`
-  --> $DIR/issue-63364.rs:6:14
-   |
-LL |     for n in 100_000.. {
-   |              ^^^^^^^
-   |
-   = note: `#[deny(overflowing_literals)]` on by default
-   = note: the literal `100_000` does not fit into the type `u16` whose range is `0..=65535`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-6596-1.rs b/src/test/ui/issues/issue-6596-1.rs
deleted file mode 100644 (file)
index 25f1d65..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-macro_rules! e {
-    ($inp:ident) => (
-        $nonexistent
-        //~^ ERROR expected expression, found `$`
-    );
-}
-
-fn main() {
-    e!(foo);
-}
diff --git a/src/test/ui/issues/issue-6596-1.stderr b/src/test/ui/issues/issue-6596-1.stderr
deleted file mode 100644 (file)
index 7ab3685..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-error: expected expression, found `$`
-  --> $DIR/issue-6596-1.rs:3:9
-   |
-LL |         $nonexistent
-   |         ^^^^^^^^^^^^ expected expression
-...
-LL |     e!(foo);
-   |     ------- in this macro invocation
-   |
-   = note: this error originates in the macro `e` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-6804.rs b/src/test/ui/issues/issue-6804.rs
deleted file mode 100644 (file)
index 0260caa..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Matching against NaN should result in a warning
-
-#![allow(unused)]
-#![deny(illegal_floating_point_literal_pattern)]
-
-const NAN: f64 = f64::NAN;
-
-fn main() {
-    let x = NAN;
-    match x {
-        NAN => {}, //~ ERROR floating-point types cannot be used
-        //~| WARN this was previously accepted by the compiler but is being phased out
-        _ => {},
-    };
-
-    match [x, 1.0] {
-        [NAN, _] => {}, //~ ERROR floating-point types cannot be used
-        //~| WARN this was previously accepted by the compiler but is being phased out
-        _ => {},
-    };
-}
diff --git a/src/test/ui/issues/issue-6804.stderr b/src/test/ui/issues/issue-6804.stderr
deleted file mode 100644 (file)
index 4e2961e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-6804.rs:11:9
-   |
-LL |         NAN => {},
-   |         ^^^
-   |
-note: the lint level is defined here
-  --> $DIR/issue-6804.rs:4:9
-   |
-LL | #![deny(illegal_floating_point_literal_pattern)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-6804.rs:17:10
-   |
-LL |         [NAN, _] => {},
-   |          ^^^
-   |
-   = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/issues/issue-72455.rs b/src/test/ui/issues/issue-72455.rs
deleted file mode 100644 (file)
index b6c3bb2..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// check-pass
-
-pub trait ResultExt {
-    type Ok;
-    fn err_eprint_and_ignore(self) -> Option<Self::Ok>;
-}
-
-impl<O, E> ResultExt for std::result::Result<O, E>
-where
-    E: std::error::Error,
-{
-    type Ok = O;
-    fn err_eprint_and_ignore(self) -> Option<O>
-    where
-        Self: ,
-    {
-        match self {
-            Err(e) => {
-                eprintln!("{}", e);
-                None
-            }
-            Ok(o) => Some(o),
-        }
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-72574-2.rs b/src/test/ui/issues/issue-72574-2.rs
deleted file mode 100644 (file)
index 0ad2db8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-struct Binder(i32, i32, i32);
-
-fn main() {
-    let x = Binder(1, 2, 3);
-    match x {
-        Binder(_a, _x @ ..) => {}
-        _ => {}
-    }
-}
-//~^^^^ ERROR `_x @` is not allowed in a tuple struct
-//~| ERROR: `..` patterns are not allowed here
-//~| ERROR: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr
deleted file mode 100644 (file)
index 05650f0..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-error: `_x @` is not allowed in a tuple struct
-  --> $DIR/issue-72574-2.rs:6:20
-   |
-LL |         Binder(_a, _x @ ..) => {}
-   |                    ^^^^^^^ this is only allowed in slice patterns
-   |
-   = help: remove this and bind each tuple field independently
-help: if you don't need to use the contents of _x, discard the tuple's remaining fields
-   |
-LL |         Binder(_a, ..) => {}
-   |                    ~~
-
-error: `..` patterns are not allowed here
-  --> $DIR/issue-72574-2.rs:6:25
-   |
-LL |         Binder(_a, _x @ ..) => {}
-   |                         ^^
-   |
-   = note: only allowed in tuple, tuple struct, and slice patterns
-
-error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/issue-72574-2.rs:6:16
-   |
-LL | struct Binder(i32, i32, i32);
-   |               ---  ---  --- tuple struct has 3 fields
-...
-LL |         Binder(_a, _x @ ..) => {}
-   |                ^^  ^^^^^^^ expected 3 fields, found 2
-   |
-help: use `_` to explicitly ignore each field
-   |
-LL |         Binder(_a, _x @ .., _) => {}
-   |                           +++
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0023`.
diff --git a/src/test/ui/issues/issue-73541-1.rs b/src/test/ui/issues/issue-73541-1.rs
deleted file mode 100644 (file)
index 7fb0d6c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// edition:2018
-
-fn main() {
-    'a: loop {
-        async {
-            loop {
-                continue 'a
-                //~^ ERROR use of unreachable label `'a`
-            }
-        };
-    }
-}
diff --git a/src/test/ui/issues/issue-73541-1.stderr b/src/test/ui/issues/issue-73541-1.stderr
deleted file mode 100644 (file)
index 80c1fdf..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0767]: use of unreachable label `'a`
-  --> $DIR/issue-73541-1.rs:7:26
-   |
-LL |     'a: loop {
-   |     -- unreachable label defined here
-...
-LL |                 continue 'a
-   |                          ^^ unreachable label `'a`
-   |
-   = note: labels are unreachable through functions, closures, async blocks and modules
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0767`.
diff --git a/src/test/ui/issues/issue-73886.rs b/src/test/ui/issues/issue-73886.rs
deleted file mode 100644 (file)
index 9c0c87a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-fn main() {
-    let _ = &&[0] as &[_];
-    //~^ ERROR non-primitive cast: `&&[i32; 1]` as `&[_]`
-    let _ = 7u32 as Option<_>;
-    //~^ ERROR non-primitive cast: `u32` as `Option<_>`
-}
diff --git a/src/test/ui/issues/issue-73886.stderr b/src/test/ui/issues/issue-73886.stderr
deleted file mode 100644 (file)
index a6f8ba6..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0605]: non-primitive cast: `&&[i32; 1]` as `&[_]`
-  --> $DIR/issue-73886.rs:2:13
-   |
-LL |     let _ = &&[0] as &[_];
-   |             ^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
-
-error[E0605]: non-primitive cast: `u32` as `Option<_>`
-  --> $DIR/issue-73886.rs:4:13
-   |
-LL |     let _ = 7u32 as Option<_>;
-   |             ^^^^^^^^^^^^^^^^^ help: consider using the `From` trait instead: `Option<_>::from(7u32)`
-   |
-   = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0605`.
diff --git a/src/test/ui/issues/issue-74739.rs b/src/test/ui/issues/issue-74739.rs
deleted file mode 100644 (file)
index 0362235..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// compile-flags: -O
-// run-pass
-
-struct Foo {
-    x: i32,
-}
-
-pub fn main() {
-    let mut foo = Foo { x: 42 };
-    let x = &mut foo.x;
-    *x = 13;
-    let y = foo;
-    assert_eq!(y.x, 13); // used to print 42 due to mir-opt bug
-}
diff --git a/src/test/ui/issues/issue-811.rs b/src/test/ui/issues/issue-811.rs
deleted file mode 100644 (file)
index f929d38..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// run-fail
-// error-pattern:quux
-// ignore-emscripten no processes
-
-use std::marker::PhantomData;
-
-fn test00_start(ch: Chan<isize>, message: isize) {
-    send(ch, message);
-}
-
-type TaskId = isize;
-type PortId = isize;
-
-struct Chan<T> {
-    task: TaskId,
-    port: PortId,
-    marker: PhantomData<*mut T>,
-}
-
-fn send<T: Send>(_ch: Chan<T>, _data: T) {
-    panic!();
-}
-
-fn main() {
-    panic!("quux");
-}
diff --git a/src/test/ui/issues/issue-8351-1.rs b/src/test/ui/issues/issue-8351-1.rs
deleted file mode 100644 (file)
index 139f027..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-
-enum E {
-    Foo{f: isize},
-    Bar,
-}
-
-pub fn main() {
-    let e = E::Foo{f: 0};
-    match e {
-        E::Foo{f: 1} => panic!(),
-        E::Foo{..} => (),
-        _ => panic!(),
-    }
-}
diff --git a/src/test/ui/issues/issue-8351-2.rs b/src/test/ui/issues/issue-8351-2.rs
deleted file mode 100644 (file)
index bc66cbb..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-
-enum E {
-    Foo{f: isize, b: bool},
-    Bar,
-}
-
-pub fn main() {
-    let e = E::Foo{f: 0, b: false};
-    match e {
-        E::Foo{f: 1, b: true} => panic!(),
-        E::Foo{b: false, f: 0} => (),
-        _ => panic!(),
-    }
-}
diff --git a/src/test/ui/issues/issue-86865.rs b/src/test/ui/issues/issue-86865.rs
deleted file mode 100644 (file)
index 01e0a20..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-use std::fmt::Write;
-
-fn main() {
-    println!(b"foo");
-    //~^ ERROR format argument must be a string literal
-    //~| HELP consider removing the leading `b`
-    let mut s = String::new();
-    write!(s, b"foo{}", "bar");
-    //~^ ERROR format argument must be a string literal
-    //~| HELP consider removing the leading `b`
-}
diff --git a/src/test/ui/issues/issue-86865.stderr b/src/test/ui/issues/issue-86865.stderr
deleted file mode 100644 (file)
index eed7553..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-error: format argument must be a string literal
-  --> $DIR/issue-86865.rs:4:14
-   |
-LL |     println!(b"foo");
-   |              -^^^^^
-   |              |
-   |              help: consider removing the leading `b`
-
-error: format argument must be a string literal
-  --> $DIR/issue-86865.rs:8:15
-   |
-LL |     write!(s, b"foo{}", "bar");
-   |               -^^^^^^^
-   |               |
-   |               help: consider removing the leading `b`
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/issues/issue-8827.rs b/src/test/ui/issues/issue-8827.rs
deleted file mode 100644 (file)
index 95be761..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// run-pass
-// ignore-emscripten no threads support
-
-use std::thread;
-use std::sync::mpsc::{channel, Receiver};
-
-fn periodical(n: isize) -> Receiver<bool> {
-    let (chan, port) = channel();
-    thread::spawn(move|| {
-        loop {
-            for _ in 1..n {
-                match chan.send(false) {
-                    Ok(()) => {}
-                    Err(..) => break,
-                }
-            }
-            match chan.send(true) {
-                Ok(()) => {}
-                Err(..) => break
-            }
-        }
-    });
-    return port;
-}
-
-fn integers() -> Receiver<isize> {
-    let (chan, port) = channel();
-    thread::spawn(move|| {
-        let mut i = 1;
-        loop {
-            match chan.send(i) {
-                Ok(()) => {}
-                Err(..) => break,
-            }
-            i = i + 1;
-        }
-    });
-    return port;
-}
-
-fn main() {
-    let ints = integers();
-    let threes = periodical(3);
-    let fives = periodical(5);
-    for _ in 1..100 {
-        match (ints.recv().unwrap(), threes.recv().unwrap(), fives.recv().unwrap()) {
-            (_, true, true) => println!("FizzBuzz"),
-            (_, true, false) => println!("Fizz"),
-            (_, false, true) => println!("Buzz"),
-            (i, false, false) => println!("{}", i)
-        }
-    }
-}
diff --git a/src/test/ui/issues/issue-9396.rs b/src/test/ui/issues/issue-9396.rs
deleted file mode 100644 (file)
index 3e7e9a5..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// run-pass
-#![allow(unused_must_use)]
-#![allow(deprecated)]
-// ignore-emscripten no threads support
-
-use std::sync::mpsc::{TryRecvError, channel};
-use std::thread;
-
-pub fn main() {
-    let (tx, rx) = channel();
-    let t = thread::spawn(move||{
-        thread::sleep_ms(10);
-        tx.send(()).unwrap();
-    });
-    loop {
-        match rx.try_recv() {
-            Ok(()) => break,
-            Err(TryRecvError::Empty) => {}
-            Err(TryRecvError::Disconnected) => unreachable!()
-        }
-    }
-    t.join();
-}
index ec54ed005173b148fc37bbe146e4e7736caad086..158317efe4782c9b1e23014e26503f5c76a304d3 100644 (file)
@@ -1,6 +1,5 @@
 // check-pass
 // edition:2021
-// compile-flags: -Zunstable-options
 
 use std::array::IntoIter;
 use std::ops::Deref;
diff --git a/src/test/ui/lambda-var-hygiene.rs b/src/test/ui/lambda-var-hygiene.rs
deleted file mode 100644 (file)
index bf06765..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// run-pass
-// shouldn't affect evaluation of $ex:
-macro_rules! bad_macro {
-    ($ex:expr) => ({(|_x| { $ex }) (9) })
-}
-
-fn takes_x(_x : isize) {
-    assert_eq!(bad_macro!(_x),8);
-}
-fn main() {
-    takes_x(8);
-}
diff --git a/src/test/ui/lang-items/issue-19660.rs b/src/test/ui/lang-items/issue-19660.rs
new file mode 100644 (file)
index 0000000..400ac31
--- /dev/null
@@ -0,0 +1,15 @@
+// error-pattern: requires `copy` lang_item
+
+#![feature(lang_items, start, no_core)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized { }
+
+struct S;
+
+#[start]
+fn main(_: isize, _: *const *const u8) -> isize {
+    let _ = S;
+    0
+}
diff --git a/src/test/ui/lang-items/issue-19660.stderr b/src/test/ui/lang-items/issue-19660.stderr
new file mode 100644 (file)
index 0000000..f5d903f
--- /dev/null
@@ -0,0 +1,4 @@
+error: requires `copy` lang_item
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lang-items/issue-31076.rs b/src/test/ui/lang-items/issue-31076.rs
new file mode 100644 (file)
index 0000000..cdb196d
--- /dev/null
@@ -0,0 +1,17 @@
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized {}
+
+#[lang="add"]
+trait Add<T> {}
+
+impl Add<i32> for i32 {}
+
+fn main() {
+    let x = 5 + 6;
+    //~^ ERROR cannot add `i32` to `{integer}`
+    let y = 5i32 + 6i32;
+    //~^ ERROR cannot add `i32` to `i32`
+}
diff --git a/src/test/ui/lang-items/issue-31076.stderr b/src/test/ui/lang-items/issue-31076.stderr
new file mode 100644 (file)
index 0000000..ac0d9dc
--- /dev/null
@@ -0,0 +1,19 @@
+error[E0369]: cannot add `i32` to `{integer}`
+  --> $DIR/issue-31076.rs:13:15
+   |
+LL |     let x = 5 + 6;
+   |             - ^ - i32
+   |             |
+   |             {integer}
+
+error[E0369]: cannot add `i32` to `i32`
+  --> $DIR/issue-31076.rs:15:18
+   |
+LL |     let y = 5i32 + 6i32;
+   |             ---- ^ ---- i32
+   |             |
+   |             i32
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/lang-items/required-lang-item.rs b/src/test/ui/lang-items/required-lang-item.rs
new file mode 100644 (file)
index 0000000..3b17c5b
--- /dev/null
@@ -0,0 +1,11 @@
+// build-fail
+
+#![feature(lang_items, no_core)]
+#![no_core]
+
+#[lang="copy"] pub trait Copy { }
+#[lang="sized"] pub trait Sized { }
+
+// error-pattern:requires `start` lang_item
+
+fn main() {}
diff --git a/src/test/ui/lang-items/required-lang-item.stderr b/src/test/ui/lang-items/required-lang-item.stderr
new file mode 100644 (file)
index 0000000..83764a9
--- /dev/null
@@ -0,0 +1,4 @@
+error: requires `start` lang_item
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/legacy-const-generics-bad.rs b/src/test/ui/legacy-const-generics-bad.rs
deleted file mode 100644 (file)
index 538eee3..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// aux-build:legacy-const-generics.rs
-
-extern crate legacy_const_generics;
-
-fn foo<const N: usize>() {
-    let a = 1;
-    legacy_const_generics::foo(0, a, 2);
-    //~^ ERROR attempt to use a non-constant value in a constant
-
-    legacy_const_generics::foo(0, N, 2);
-
-    legacy_const_generics::foo(0, N + 1, 2);
-    //~^ ERROR generic parameters may not be used in const operations
-}
-
-fn main() {}
diff --git a/src/test/ui/legacy-const-generics-bad.stderr b/src/test/ui/legacy-const-generics-bad.stderr
deleted file mode 100644 (file)
index 3c78dd6..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/legacy-const-generics-bad.rs:7:35
-   |
-LL |     let a = 1;
-   |     ----- help: consider using `const` instead of `let`: `const a`
-LL |     legacy_const_generics::foo(0, a, 2);
-   |                                   ^ non-constant value
-
-error: generic parameters may not be used in const operations
-  --> $DIR/legacy-const-generics-bad.rs:12:35
-   |
-LL |     legacy_const_generics::foo(0, N + 1, 2);
-   |                                   ^ cannot perform const operation using `N`
-   |
-   = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0435`.
diff --git a/src/test/ui/legacy-const-generics.rs b/src/test/ui/legacy-const-generics.rs
deleted file mode 100644 (file)
index 9abc72d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// aux-build:legacy-const-generics.rs
-// run-pass
-
-#![feature(rustc_attrs)]
-
-extern crate legacy_const_generics;
-
-#[rustc_legacy_const_generics(1)]
-pub fn bar<const Y: usize>(x: usize, z: usize) -> [usize; 3] {
-    [x, Y, z]
-}
-
-fn main() {
-    assert_eq!(legacy_const_generics::foo(0 + 0, 1 + 1, 2 + 2), [0, 2, 4]);
-    assert_eq!(legacy_const_generics::foo::<{1 + 1}>(0 + 0, 2 + 2), [0, 2, 4]);
-    // FIXME: Only works cross-crate
-    //assert_eq!(bar(0, 1, 2), [0, 1, 2]);
-}
diff --git a/src/test/ui/lifetimes/issue-26638.rs b/src/test/ui/lifetimes/issue-26638.rs
new file mode 100644 (file)
index 0000000..72fe428
--- /dev/null
@@ -0,0 +1,10 @@
+fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
+//~^ ERROR missing lifetime specifier [E0106]
+
+fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
+//~^ ERROR missing lifetime specifier [E0106]
+
+fn parse_type_3() -> &str { unimplemented!() }
+//~^ ERROR missing lifetime specifier [E0106]
+
+fn main() {}
diff --git a/src/test/ui/lifetimes/issue-26638.stderr b/src/test/ui/lifetimes/issue-26638.stderr
new file mode 100644 (file)
index 0000000..bb7cdcb
--- /dev/null
@@ -0,0 +1,39 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/issue-26638.rs:1:62
+   |
+LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
+   |                     ------------------------------------     ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from
+help: consider introducing a named lifetime parameter
+   |
+LL | fn parse_type<'a>(iter: Box<dyn Iterator<Item=&str>+'static>) -> &'a str { iter.next() }
+   |              ++++                                                 ++
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/issue-26638.rs:4:40
+   |
+LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
+   |                                        ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
+help: consider using the `'static` lifetime
+   |
+LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &'static str { iter() }
+   |                                        ~~~~~~~~
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/issue-26638.rs:7:22
+   |
+LL | fn parse_type_3() -> &str { unimplemented!() }
+   |                      ^ 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 parse_type_3() -> &'static str { unimplemented!() }
+   |                      ~~~~~~~~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/lifetimes/issue-90170-elision-mismatch.fixed b/src/test/ui/lifetimes/issue-90170-elision-mismatch.fixed
new file mode 100644 (file)
index 0000000..0bc889e
--- /dev/null
@@ -0,0 +1,9 @@
+// run-rustfix
+
+pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } //~ ERROR lifetime mismatch
+
+pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } //~ ERROR lifetime mismatch
+
+pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } //~ ERROR lifetime mismatch
+
+fn main() {}
diff --git a/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr b/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr
new file mode 100644 (file)
index 0000000..a5bc745
--- /dev/null
@@ -0,0 +1,29 @@
+error: lifetime may not live long enough
+  --> $DIR/issue-90170-elision-mismatch.rs:3:40
+   |
+LL | pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); }
+   |                        -        -      ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |                        |        |
+   |                        |        let's call the lifetime of this reference `'1`
+   |                        let's call the lifetime of this reference `'2`
+
+error: lifetime may not live long enough
+  --> $DIR/issue-90170-elision-mismatch.rs:5:44
+   |
+LL | pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); }
+   |                         -           -      ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |                         |           |
+   |                         |           let's call the lifetime of this reference `'1`
+   |                         let's call the lifetime of this reference `'2`
+
+error: lifetime may not live long enough
+  --> $DIR/issue-90170-elision-mismatch.rs:7:63
+   |
+LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); }
+   |                                               -        -      ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |                                               |        |
+   |                                               |        let's call the lifetime of this reference `'1`
+   |                                               let's call the lifetime of this reference `'2`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/lifetimes/issue-90170-elision-mismatch.rs b/src/test/ui/lifetimes/issue-90170-elision-mismatch.rs
new file mode 100644 (file)
index 0000000..1d6573c
--- /dev/null
@@ -0,0 +1,9 @@
+// run-rustfix
+
+pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); } //~ ERROR lifetime mismatch
+
+pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); } //~ ERROR lifetime mismatch
+
+pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); } //~ ERROR lifetime mismatch
+
+fn main() {}
diff --git a/src/test/ui/lifetimes/issue-90170-elision-mismatch.stderr b/src/test/ui/lifetimes/issue-90170-elision-mismatch.stderr
new file mode 100644 (file)
index 0000000..7fa092c
--- /dev/null
@@ -0,0 +1,45 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/issue-90170-elision-mismatch.rs:3:47
+   |
+LL | pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); }
+   |                        ---      ---           ^ ...but data from `y` flows into `x` here
+   |                                 |
+   |                                 these two types are declared with different lifetimes...
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
+   |           ++++              ++          ++
+
+error[E0623]: lifetime mismatch
+  --> $DIR/issue-90170-elision-mismatch.rs:5:51
+   |
+LL | pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); }
+   |                         ------      ---           ^ ...but data from `y` flows into `x` here
+   |                                     |
+   |                                     these two types are declared with different lifetimes...
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
+   |            ++++              ~~          ++
+
+error[E0623]: lifetime mismatch
+  --> $DIR/issue-90170-elision-mismatch.rs:7:70
+   |
+LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); }
+   |                                               ---      ---           ^ ...but data from `y` flows into `x` here
+   |                                                        |
+   |                                                        these two types are declared with different lifetimes...
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
+   |                                                ++          ++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0623`.
index 0aff80c6fbdd3c3fb3f316c75ea0f8a940e7a597..5c793636778ea2c9505bcb81e5f4416c5e7bf838 100644 (file)
@@ -5,6 +5,12 @@ LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
    |                                   ---           --- these two types are declared with different lifetimes...
 LL |     *v = x;
    |          ^ ...but data from `x` flows here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(&mut (ref mut v, w): &mut (&'a u8, &u8), x: &'a u8) {
+   |       ++++                             ++               ++
 
 error: aborting due to previous error
 
index 2e5ff6782d3b65ac0f617879e7cb025caa750893..1a7b4fca1ba7846729a02f714d3d06597142675f 100644 (file)
@@ -5,6 +5,12 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
    |                     ---                 --- these two types are declared with different lifetimes...
 LL |     z.push((x,y));
    |             ^ ...but data flows into `z` here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(z: &mut Vec<(&'a u8,&u8)>, (x, y): (&'a u8, &u8)) {
+   |       ++++               ++                     ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ex3-both-anon-regions-3.rs:2:15
@@ -13,6 +19,12 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
    |                         ---                  --- these two types are declared with different lifetimes...
 LL |     z.push((x,y));
    |               ^ ...but data flows into `z` here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(z: &mut Vec<(&u8,&'a u8)>, (x, y): (&u8, &'a u8)) {
+   |       ++++                   ++                      ++
 
 error: aborting due to 2 previous errors
 
index d2cc3dba6a4336cce5781dd19a8b6249d50f26f8..6ed3528bb9faac790382bea6d763496425066ea0 100644 (file)
@@ -5,6 +5,12 @@ LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
    |                               ---      --- these two types are declared with different lifetimes...
 LL |   y.push(z);
    |          ^ ...but data from `z` flows into `y` here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(x:fn(&u8, &u8), y: Vec<&'a u8>, z: &'a u8) {
+   |       ++++                         ++          ++
 
 error: aborting due to previous error
 
index 2acc4eaf60f557dc1510588e1e5c794dc0b0fb0a..ede1631db271c46593a8f68186fabb5a7a988984 100644 (file)
@@ -5,6 +5,12 @@ LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
    |                     ---  --- these two types are declared with different lifetimes...
 LL |   y.push(z);
    |          ^ ...but data from `z` flows into `y` here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(x:Box<dyn Fn(&'a u8, &'a u8)> , y: Vec<&u8>, z: &u8) {
+   |       ++++               ++      ++
 
 error: aborting due to previous error
 
index b2784827672b8fb165d45c6b5f286673d7cc1589..cf405c0de3f0b40924f451f4cc424696217ec7de 100644 (file)
@@ -5,6 +5,12 @@ LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
    |                    ---      --- these two types are declared with different lifetimes...
 LL |     x.push(y);
    |            ^ ...but data from `y` flows into `x` here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
+   |       ++++              ++          ++
 
 error: aborting due to previous error
 
index 3fab9148392beae16e234badeeae7c8bfcf367ee..3a3d81176d691363bd6488e7bc2d8fb7f78ee668 100644 (file)
@@ -1,6 +1,6 @@
 // --force-warn $LINT causes $LINT (which is deny-by-default) to warn
 // despite $LINT being allowed on command line
-// compile-flags: -A const_err --force-warn const_err -Zunstable-options
+// compile-flags: -A const_err --force-warn const_err
 // check-pass
 
 const C: i32 = 1 / 0;
index 4eb05b538b0baea63e6e4c9c9bdc75272e98d7e1..9736027452a8df0811863d80ea2d3c1cceaa7e9f 100644 (file)
@@ -1,6 +1,6 @@
 // --force-warn $LINT_GROUP causes $LINT (which is warn-by-default) to warn
 // despite $LINT being allowed on command line
-// compile-flags: -A bare-trait-objects --force-warn rust-2018-idioms -Zunstable-options
+// compile-flags: -A bare-trait-objects --force-warn rust-2018-idioms
 // check-pass
 
 pub trait SomeTrait {}
index d2cb3417be68a272c412622ac06afdc40994f8c1..267e7b45f0c2137c3666950640ffc551332c68c2 100644 (file)
@@ -1,6 +1,6 @@
 // --force-warn $LINT causes $LINT (which is warn-by-default) to warn
 // despite being allowed in one submodule (but not the other)
-// compile-flags: --force-warn dead_code -Zunstable-options
+// compile-flags: --force-warn dead_code
 // check-pass
 
 mod one {
index fa25a1f8a842a906fd9c140e61aae4c253c8a77f..d1d4f5602f271eeb0bb1034c5279667cc55f0659 100644 (file)
@@ -1,5 +1,5 @@
 // --force-warn warnings is an error
-// compile-flags: --force-warn warnings -Zunstable-options
+// compile-flags: --force-warn warnings
 // error-pattern: `warnings` lint group is not supported
 
 fn main() {}
index 03f5788b527d3fabfd50bfcfddd9f1325a0874a9..1faeed33704511d900175c73dfe6577a2b283179 100644 (file)
@@ -2,8 +2,6 @@ error[E0602]: `warnings` lint group is not supported with ´--force-warn´
 
 error[E0602]: `warnings` lint group is not supported with ´--force-warn´
 
-error[E0602]: `warnings` lint group is not supported with ´--force-warn´
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0602`.
diff --git a/src/test/ui/lint/issue-14837.rs b/src/test/ui/lint/issue-14837.rs
new file mode 100644 (file)
index 0000000..a83bc41
--- /dev/null
@@ -0,0 +1,11 @@
+// check-pass
+// pretty-expanded FIXME #23616
+
+#[deny(dead_code)]
+pub enum Foo {
+    Bar {
+        baz: isize
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/lint/issue-57410-1.rs b/src/test/ui/lint/issue-57410-1.rs
new file mode 100644 (file)
index 0000000..d825cb1
--- /dev/null
@@ -0,0 +1,18 @@
+// check-pass
+
+// Originally from #53925.
+// Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`.
+
+#![deny(unreachable_pub)]
+
+mod foo {
+    mod bar {
+        pub struct Bar;
+    }
+
+    pub use self::bar::Bar;
+}
+
+pub use foo::Bar;
+
+fn main() {}
diff --git a/src/test/ui/lint/issue-63364.rs b/src/test/ui/lint/issue-63364.rs
new file mode 100644 (file)
index 0000000..5223267
--- /dev/null
@@ -0,0 +1,10 @@
+fn part(_: u16) -> u32 {
+    1
+}
+
+fn main() {
+    for n in 100_000.. {
+    //~^ ERROR: literal out of range for `u16`
+        let _ = part(n);
+    }
+}
diff --git a/src/test/ui/lint/issue-63364.stderr b/src/test/ui/lint/issue-63364.stderr
new file mode 100644 (file)
index 0000000..0375359
--- /dev/null
@@ -0,0 +1,11 @@
+error: literal out of range for `u16`
+  --> $DIR/issue-63364.rs:6:14
+   |
+LL |     for n in 100_000.. {
+   |              ^^^^^^^
+   |
+   = note: `#[deny(overflowing_literals)]` on by default
+   = note: the literal `100_000` does not fit into the type `u16` whose range is `0..=65535`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/issue-90614-accept-allow-text-direction-codepoint-in-comment-lint.rs b/src/test/ui/lint/issue-90614-accept-allow-text-direction-codepoint-in-comment-lint.rs
new file mode 100644 (file)
index 0000000..425e270
--- /dev/null
@@ -0,0 +1,9 @@
+// check-pass
+// Allowing the code lint should work without warning and
+// the text flow char in the comment should be ignored.
+
+#![allow(text_direction_codepoint_in_comment)]
+
+fn main() {
+    // U+2066 LEFT-TO-RIGHT ISOLATE follows:⁦⁦
+}
diff --git a/src/test/ui/lint/must_not_suspend/gated.rs b/src/test/ui/lint/must_not_suspend/gated.rs
new file mode 100644 (file)
index 0000000..acb81b0
--- /dev/null
@@ -0,0 +1,14 @@
+// edition:2018
+#![deny(must_not_suspend)]  //~ ERROR the `must_not_suspend`
+//~| ERROR the `must_not_suspend`
+//~| ERROR the `must_not_suspend`
+
+async fn other() {}
+
+pub async fn uhoh(m: std::sync::Mutex<()>) {
+    let _guard = m.lock().unwrap(); //~ ERROR `MutexGuard` held across
+    other().await;
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/gated.stderr b/src/test/ui/lint/must_not_suspend/gated.stderr
new file mode 100644 (file)
index 0000000..be077de
--- /dev/null
@@ -0,0 +1,54 @@
+error[E0658]: the `must_not_suspend` lint is unstable
+  --> $DIR/gated.rs:2:1
+   |
+LL | #![deny(must_not_suspend)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
+   = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
+
+error[E0658]: the `must_not_suspend` lint is unstable
+  --> $DIR/gated.rs:2:1
+   |
+LL | #![deny(must_not_suspend)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
+   = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
+
+error[E0658]: the `must_not_suspend` lint is unstable
+  --> $DIR/gated.rs:2:1
+   |
+LL | #![deny(must_not_suspend)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
+   = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
+
+error: `MutexGuard` held across a suspend point, but should not be
+  --> $DIR/gated.rs:9:9
+   |
+LL |     let _guard = m.lock().unwrap();
+   |         ^^^^^^
+LL |     other().await;
+   |     ------------- the value is held across this suspend point
+   |
+note: the lint level is defined here
+  --> $DIR/gated.rs:2:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
+note: holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send`
+  --> $DIR/gated.rs:9:9
+   |
+LL |     let _guard = m.lock().unwrap();
+   |         ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+  --> $DIR/gated.rs:9:9
+   |
+LL |     let _guard = m.lock().unwrap();
+   |         ^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/lint/must_not_suspend/issue-89562.rs b/src/test/ui/lint/must_not_suspend/issue-89562.rs
new file mode 100644 (file)
index 0000000..acdb36f
--- /dev/null
@@ -0,0 +1,19 @@
+// edition:2018
+// run-pass
+
+use std::sync::Mutex;
+
+// Copied from the issue. Allow-by-default for now, so run-pass
+pub async fn foo() {
+    let foo = Mutex::new(1);
+    let lock = foo.lock().unwrap();
+
+    // Prevent mutex lock being held across `.await` point.
+    drop(lock);
+
+    bar().await;
+}
+
+async fn bar() {}
+
+fn main() {}
index 596249b2e4e4fa8efd4eebb4b7bea11a3b6359c9..7bb895e7d36438f143181273f304f4d2c017f374 100644 (file)
@@ -1,4 +1,5 @@
 // edition:2018
+#![feature(must_not_suspend)]
 #![deny(must_not_suspend)]
 
 async fn other() {}
index 093f581264f36c3eea29df0367f2453293618c60..dde506c19e72501b9bb7fdce98902506890c2e08 100644 (file)
@@ -1,5 +1,5 @@
 error: `MutexGuard` held across a suspend point, but should not be
-  --> $DIR/mutex.rs:7:9
+  --> $DIR/mutex.rs:8:9
    |
 LL |     let _guard = m.lock().unwrap();
    |         ^^^^^^
@@ -7,17 +7,17 @@ LL |     other().await;
    |     ------------- the value is held across this suspend point
    |
 note: the lint level is defined here
-  --> $DIR/mutex.rs:2:9
+  --> $DIR/mutex.rs:3:9
    |
 LL | #![deny(must_not_suspend)]
    |         ^^^^^^^^^^^^^^^^
 note: holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send`
-  --> $DIR/mutex.rs:7:9
+  --> $DIR/mutex.rs:8:9
    |
 LL |     let _guard = m.lock().unwrap();
    |         ^^^^^^
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/mutex.rs:7:9
+  --> $DIR/mutex.rs:8:9
    |
 LL |     let _guard = m.lock().unwrap();
    |         ^^^^^^
index 50a696ba52322adb11dab5942328ae665f85fb2d..7fdea66a23517d5967e4241685820d499471f4e9 100644 (file)
@@ -1,6 +1,7 @@
 // edition:2018
 // run-pass
 #![feature(must_not_suspend)]
+#![warn(must_not_suspend)]
 
 #[must_not_suspend = "You gotta use Umm's, ya know?"]
 struct Umm {
index 24f52275b430afe1114bc69926318f92970e8335..42374d4acac275f304fab03cccada0f7f85734e9 100644 (file)
@@ -1,19 +1,23 @@
 warning: `Umm` held across a suspend point, but should not be
-  --> $DIR/warn.rs:20:9
+  --> $DIR/warn.rs:21:9
    |
 LL |     let _guard = bar();
    |         ^^^^^^
 LL |     other().await;
    |     ------------- the value is held across this suspend point
    |
-   = note: `#[warn(must_not_suspend)]` on by default
+note: the lint level is defined here
+  --> $DIR/warn.rs:4:9
+   |
+LL | #![warn(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 note: You gotta use Umm's, ya know?
-  --> $DIR/warn.rs:20:9
+  --> $DIR/warn.rs:21:9
    |
 LL |     let _guard = bar();
    |         ^^^^^^
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/warn.rs:20:9
+  --> $DIR/warn.rs:21:9
    |
 LL |     let _guard = bar();
    |         ^^^^^^
diff --git a/src/test/ui/lint/unnecessary-extern-crate.rs b/src/test/ui/lint/unnecessary-extern-crate.rs
new file mode 100644 (file)
index 0000000..67eaaf4
--- /dev/null
@@ -0,0 +1,71 @@
+// edition:2018
+
+#![deny(unused_extern_crates)]
+#![feature(test, rustc_private, crate_visibility_modifier)]
+
+extern crate libc;
+//~^ ERROR unused extern crate
+//~| HELP remove
+extern crate libc as x;
+//~^ ERROR unused extern crate
+//~| HELP remove
+
+extern crate proc_macro;
+
+#[macro_use]
+extern crate test;
+
+pub extern crate test as y;
+
+pub extern crate alloc;
+
+pub(crate) extern crate alloc as a;
+
+crate extern crate alloc as b;
+
+mod foo {
+    pub(in crate::foo) extern crate alloc as c;
+
+    pub(super) extern crate alloc as d;
+
+    extern crate libc;
+    //~^ ERROR unused extern crate
+    //~| HELP remove
+
+    extern crate libc as x;
+    //~^ ERROR unused extern crate
+    //~| HELP remove
+
+    pub extern crate test;
+
+    pub extern crate test as y;
+
+    mod bar {
+        extern crate libc;
+        //~^ ERROR unused extern crate
+        //~| HELP remove
+
+        extern crate libc as x;
+        //~^ ERROR unused extern crate
+        //~| HELP remove
+
+        pub(in crate::foo::bar) extern crate alloc as e;
+
+        fn dummy() {
+            e::string::String::new();
+        }
+    }
+
+    fn dummy() {
+        c::string::String::new();
+        d::string::String::new();
+    }
+}
+
+
+fn main() {
+    a::string::String::new();
+    b::string::String::new();
+
+    proc_macro::TokenStream::new();
+}
diff --git a/src/test/ui/lint/unnecessary-extern-crate.stderr b/src/test/ui/lint/unnecessary-extern-crate.stderr
new file mode 100644 (file)
index 0000000..14ba9d0
--- /dev/null
@@ -0,0 +1,44 @@
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:6:1
+   |
+LL | extern crate libc;
+   | ^^^^^^^^^^^^^^^^^^ help: remove it
+   |
+note: the lint level is defined here
+  --> $DIR/unnecessary-extern-crate.rs:3:9
+   |
+LL | #![deny(unused_extern_crates)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:9:1
+   |
+LL | extern crate libc as x;
+   | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:31:5
+   |
+LL |     extern crate libc;
+   |     ^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:35:5
+   |
+LL |     extern crate libc as x;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:44:9
+   |
+LL |         extern crate libc;
+   |         ^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:48:9
+   |
+LL |         extern crate libc as x;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: aborting due to 6 previous errors
+
index 15ee19755bffc504ab84086542be1f91912eb7f3..c4004540467488bc5319d45436bc5153b6750e72 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --error-format json -Zunstable-options
+// compile-flags: --error-format json
 // run-rustfix
 
 // The output for humans should just highlight the whole span without showing
index d72df21e09ae264c8a253850b77f15b65401bdba..962c8bdd7d78957dcf7c837f8f1685cdbffe8734 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --error-format json -Zunstable-options
+// compile-flags: --error-format json
 // run-rustfix
 
 // The output for humans should just highlight the whole span without showing
index 498c25d2e1c44ed4a2318ef21f6170e9861a2b0c..169fb824021ed6e4eea48bb74b0ce135a10fdfdf 100644 (file)
@@ -1,4 +1,4 @@
-{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":596,"byte_end":597,"line_start":16,"line_end":16,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));
+{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":577,"byte_end":578,"line_start":16,"line_end":16,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));
   --> $DIR/unused_parens_json_suggestion.rs:16:14
    |
 LL |     let _a = (1 / (2 + 3));
index 1d891d328dd5ab3123026c7a3c5e4154c9c9066d..8a57cd57385f31238c90f3327b72924dc5852b48 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --error-format json -Zunstable-options
+// compile-flags: --error-format json
 // run-rustfix
 
 // The output for humans should just highlight the whole span without showing
index 494cd1845063012aa507356732dab1e076c23786..952332d54e9c10f0e94f2a644551502c90b2a37f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --error-format json -Zunstable-options
+// compile-flags: --error-format json
 // run-rustfix
 
 // The output for humans should just highlight the whole span without showing
index 08291b10fcc204f284fe3347f193846bc10c1b51..43367aaa9113b67fbe28c01104edb6dbb8953dc9 100644 (file)
@@ -1,4 +1,4 @@
-{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":500,"byte_end":501,"line_start":17,"line_end":17,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":481,"byte_end":482,"line_start":17,"line_end":17,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:17:8
    |
 LL |     if (_b) {
@@ -16,7 +16,7 @@ LL +     if _b {
    | 
 
 "}
-{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":631,"byte_end":632,"line_start":28,"line_end":28,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":612,"byte_end":613,"line_start":28,"line_end":28,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:28:7
    |
 LL |     if(c) {
@@ -29,7 +29,7 @@ LL +     if c {
    | 
 
 "}
-{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":711,"byte_end":712,"line_start":32,"line_end":32,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":692,"byte_end":693,"line_start":32,"line_end":32,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){
   --> $DIR/unused_parens_remove_json_suggestion.rs:32:8
    |
 LL |     if (c){
@@ -42,7 +42,7 @@ LL +     if c {
    | 
 
 "}
-{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":794,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":807,"byte_end":808,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":794,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":807,"byte_end":808,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
+{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":774,"byte_end":775,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":788,"byte_end":789,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":774,"byte_end":775,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":788,"byte_end":789,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:36:11
    |
 LL |     while (false && true){
@@ -55,7 +55,7 @@ LL +     while false && true {
    | 
 
 "}
-{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":821,"byte_end":822,"line_start":37,"line_end":37,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":802,"byte_end":803,"line_start":37,"line_end":37,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:37:12
    |
 LL |         if (c) {
@@ -68,7 +68,7 @@ LL +         if c {
    | 
 
 "}
-{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":918,"byte_end":919,"line_start":43,"line_end":43,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {
+{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":899,"byte_end":900,"line_start":43,"line_end":43,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:43:10
    |
 LL |     while(true && false) {
@@ -81,7 +81,7 @@ LL +     while true && false {
    | 
 
 "}
-{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":987,"byte_end":988,"line_start":44,"line_end":44,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){
+{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":968,"byte_end":969,"line_start":44,"line_end":44,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){
   --> $DIR/unused_parens_remove_json_suggestion.rs:44:18
    |
 LL |         for _ in (0 .. 3){
@@ -94,7 +94,7 @@ LL +         for _ in 0 .. 3 {
    | 
 
 "}
-{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1088,"byte_end":1089,"line_start":49,"line_end":49,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {
+{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1069,"byte_end":1070,"line_start":49,"line_end":49,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:49:14
    |
 LL |     for _ in (0 .. 3) {
@@ -107,7 +107,7 @@ LL +     for _ in 0 .. 3 {
    | 
 
 "}
-{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1147,"byte_end":1148,"line_start":50,"line_end":50,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {
+{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1128,"byte_end":1129,"line_start":50,"line_end":50,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:50:15
    |
 LL |         while (true && false) {
diff --git a/src/test/ui/lint/warn-ctypes-inhibit.rs b/src/test/ui/lint/warn-ctypes-inhibit.rs
new file mode 100644 (file)
index 0000000..15d8b09
--- /dev/null
@@ -0,0 +1,15 @@
+// run-pass
+
+#![allow(dead_code)]
+// compile-flags:-D improper-ctypes
+
+// pretty-expanded FIXME #23616
+#![allow(improper_ctypes)]
+
+mod libc {
+    extern "C" {
+        pub fn malloc(size: isize) -> *const u8;
+    }
+}
+
+pub fn main() {}
diff --git a/src/test/ui/llvm-asm/issue-23458.rs b/src/test/ui/llvm-asm/issue-23458.rs
new file mode 100644 (file)
index 0000000..d640828
--- /dev/null
@@ -0,0 +1,12 @@
+#![feature(llvm_asm)]
+#![allow(deprecated)] // llvm_asm!
+// compile-flags: -Ccodegen-units=1
+// build-fail
+// only-x86_64
+
+fn main() {
+    unsafe {
+        llvm_asm!("int $3"); //~ ERROR too few operands for instruction
+                             //~| ERROR invalid operand in inline asm
+    }
+}
diff --git a/src/test/ui/llvm-asm/issue-23458.stderr b/src/test/ui/llvm-asm/issue-23458.stderr
new file mode 100644 (file)
index 0000000..69e458f
--- /dev/null
@@ -0,0 +1,20 @@
+error: invalid operand in inline asm: 'int $3'
+  --> $DIR/issue-23458.rs:9:9
+   |
+LL |         llvm_asm!("int $3");
+   |         ^
+
+error: too few operands for instruction
+  --> $DIR/issue-23458.rs:9:9
+   |
+LL |         llvm_asm!("int $3");
+   |         ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     int 
+   |     ^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/llvm-asm/issue-37366.rs b/src/test/ui/llvm-asm/issue-37366.rs
new file mode 100644 (file)
index 0000000..acc2f3e
--- /dev/null
@@ -0,0 +1,16 @@
+// check-pass
+// ignore-emscripten
+
+#![feature(llvm_asm)]
+#![allow(deprecated)] // llvm_asm!
+
+macro_rules! interrupt_handler {
+    () => {
+        unsafe fn _interrupt_handler() {
+            llvm_asm!("pop  eax" :::: "intel");
+        }
+    }
+}
+interrupt_handler!{}
+
+fn main() {}
diff --git a/src/test/ui/llvm-asm/issue-53787-inline-assembler-macro.rs b/src/test/ui/llvm-asm/issue-53787-inline-assembler-macro.rs
new file mode 100644 (file)
index 0000000..d9fe7ca
--- /dev/null
@@ -0,0 +1,27 @@
+// Regression test for Issue #53787: Fix ICE when creating a label in inline assembler with macros.
+
+// build-fail
+// ignore-emscripten
+
+#![feature(llvm_asm)]
+#![allow(deprecated)] // llvm_asm!
+
+macro_rules! fake_jump {
+    ($id:expr) => {
+        unsafe {
+            llvm_asm!(
+            "
+            jmp $0
+            lea eax, [ebx]
+            xor eax, 0xDEADBEEF
+            retn
+            $0:
+            "::"0"($id)::"volatile", "intel");
+        }
+    };
+}
+
+fn main() {
+    fake_jump!("FirstFunc"); //~ ERROR invalid value for constraint in inline assembly
+    println!("Hello, world!");
+}
diff --git a/src/test/ui/llvm-asm/issue-53787-inline-assembler-macro.stderr b/src/test/ui/llvm-asm/issue-53787-inline-assembler-macro.stderr
new file mode 100644 (file)
index 0000000..fd755e3
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0669]: invalid value for constraint in inline assembly
+  --> $DIR/issue-53787-inline-assembler-macro.rs:25:16
+   |
+LL |     fake_jump!("FirstFunc");
+   |                ^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0669`.
diff --git a/src/test/ui/long-while.rs b/src/test/ui/long-while.rs
deleted file mode 100644 (file)
index 529cca7..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// run-pass
-// pretty-expanded FIXME #23616
-
-#![allow(unused_variables)]
-
-pub fn main() {
-    let mut i: isize = 0;
-    while i < 1000000 {
-        i += 1;
-        let x = 3;
-    }
-}
diff --git a/src/test/ui/lto-and-no-bitcode-in-rlib.rs b/src/test/ui/lto-and-no-bitcode-in-rlib.rs
deleted file mode 100644 (file)
index f381240..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-// compile-flags: -C lto -C embed-bitcode=no
-
-fn main() {}
diff --git a/src/test/ui/lto-and-no-bitcode-in-rlib.stderr b/src/test/ui/lto-and-no-bitcode-in-rlib.stderr
deleted file mode 100644 (file)
index 11e370e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-error: options `-C embed-bitcode=no` and `-C lto` are incompatible
-
diff --git a/src/test/ui/lto-duplicate-symbols.rs b/src/test/ui/lto-duplicate-symbols.rs
deleted file mode 100644 (file)
index 268cf26..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// build-fail
-// aux-build:lto-duplicate-symbols1.rs
-// aux-build:lto-duplicate-symbols2.rs
-// error-pattern:Linking globals named 'foo': symbol multiply defined!
-// compile-flags: -C lto
-// no-prefer-dynamic
-
-extern crate lto_duplicate_symbols1;
-extern crate lto_duplicate_symbols2;
-
-fn main() {}
diff --git a/src/test/ui/lto-duplicate-symbols.stderr b/src/test/ui/lto-duplicate-symbols.stderr
deleted file mode 100644 (file)
index e4de04e..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-warning: Linking globals named 'foo': symbol multiply defined!
-
-error: failed to load bc of "lto-duplicate-symbols2.lto_duplicate_symbols2.693a75b4-cgu.0.rcgu.o": 
-
-error: aborting due to previous error; 1 warning emitted
-
diff --git a/src/test/ui/lto-many-codegen-units.rs b/src/test/ui/lto-many-codegen-units.rs
deleted file mode 100644 (file)
index f0f461f..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// run-pass
-// compile-flags: -C lto -C codegen-units=8
-// no-prefer-dynamic
-
-fn main() {
-}
diff --git a/src/test/ui/lto-opt-level-s.rs b/src/test/ui/lto-opt-level-s.rs
deleted file mode 100644 (file)
index a7d9d50..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// compile-flags: -Clinker-plugin-lto -Copt-level=s
-// build-pass
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-
-pub fn foo() {}
diff --git a/src/test/ui/lto-opt-level-z.rs b/src/test/ui/lto-opt-level-z.rs
deleted file mode 100644 (file)
index bf1f5e2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// compile-flags: -Clinker-plugin-lto -Copt-level=z
-// build-pass
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-
-pub fn foo() {}
diff --git a/src/test/ui/lto-rustc-loads-linker-plugin.rs b/src/test/ui/lto-rustc-loads-linker-plugin.rs
deleted file mode 100644 (file)
index 6ef1d45..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// compile-flags: -C lto
-// aux-build:lto-rustc-loads-linker-plugin.rs
-// run-pass
-// no-prefer-dynamic
-
-// This test ensures that if a dependency was compiled with
-// `-Clinker-plugin-lto` then we can compile with `-Clto` and still link against
-// that upstream rlib. This should work because LTO implies we're not actually
-// linking against upstream rlibs since we're generating the object code
-// locally. This test will fail if rustc can't find bytecode in rlibs compiled
-// with `-Clinker-plugin-lto`.
-
-extern crate lto_rustc_loads_linker_plugin;
-
-fn main() {
-    lto_rustc_loads_linker_plugin::foo();
-}
diff --git a/src/test/ui/lto-still-runs-thread-dtors.rs b/src/test/ui/lto-still-runs-thread-dtors.rs
deleted file mode 100644 (file)
index 1c7368b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// run-pass
-// compile-flags: -C lto
-// no-prefer-dynamic
-// ignore-emscripten no threads support
-// revisions: mir thir
-// [thir]compile-flags: -Zthir-unsafeck
-
-use std::thread;
-
-static mut HIT: usize = 0;
-
-thread_local!(static A: Foo = Foo);
-
-struct Foo;
-
-impl Drop for Foo {
-    fn drop(&mut self) {
-        unsafe {
-            HIT += 1;
-        }
-    }
-}
-
-fn main() {
-    unsafe {
-        assert_eq!(HIT, 0);
-        thread::spawn(|| {
-            assert_eq!(HIT, 0);
-            A.with(|_| ());
-            assert_eq!(HIT, 0);
-        }).join().unwrap();
-        assert_eq!(HIT, 1);
-    }
-}
diff --git a/src/test/ui/lto-thin-rustc-loads-linker-plugin.rs b/src/test/ui/lto-thin-rustc-loads-linker-plugin.rs
deleted file mode 100644 (file)
index 4d54ce3..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// compile-flags: -C lto=thin
-// aux-build:lto-rustc-loads-linker-plugin.rs
-// run-pass
-// no-prefer-dynamic
-
-// Same as the adjacent `lto-thin-rustc-loads-linker-plugin.rs` test, only with
-// ThinLTO.
-
-extern crate lto_rustc_loads_linker_plugin;
-
-fn main() {
-    lto_rustc_loads_linker_plugin::foo();
-}
diff --git a/src/test/ui/lto/all-crates.rs b/src/test/ui/lto/all-crates.rs
new file mode 100644 (file)
index 0000000..e910b2a
--- /dev/null
@@ -0,0 +1,8 @@
+// run-pass
+
+// compile-flags: -Clto=thin
+// no-prefer-dynamic
+
+fn main() {
+    println!("hello!");
+}
diff --git a/src/test/ui/lto/auxiliary/dylib.rs b/src/test/ui/lto/auxiliary/dylib.rs
new file mode 100644 (file)
index 0000000..e8b7f8f
--- /dev/null
@@ -0,0 +1,6 @@
+// compile-flags: -Z thinlto -C codegen-units=8
+
+#[inline]
+pub fn foo(b: u8) {
+    b.to_string();
+}
diff --git a/src/test/ui/lto/auxiliary/lto-duplicate-symbols1.rs b/src/test/ui/lto/auxiliary/lto-duplicate-symbols1.rs
new file mode 100644 (file)
index 0000000..ec6d056
--- /dev/null
@@ -0,0 +1,6 @@
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+#[no_mangle]
+pub extern "C" fn foo() {}
diff --git a/src/test/ui/lto/auxiliary/lto-duplicate-symbols2.rs b/src/test/ui/lto/auxiliary/lto-duplicate-symbols2.rs
new file mode 100644 (file)
index 0000000..ec6d056
--- /dev/null
@@ -0,0 +1,6 @@
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+#[no_mangle]
+pub extern "C" fn foo() {}
diff --git a/src/test/ui/lto/auxiliary/lto-rustc-loads-linker-plugin.rs b/src/test/ui/lto/auxiliary/lto-rustc-loads-linker-plugin.rs
new file mode 100644 (file)
index 0000000..d24375b
--- /dev/null
@@ -0,0 +1,6 @@
+// compile-flags: -Clinker-plugin-lto
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+pub fn foo() {}
diff --git a/src/test/ui/lto/auxiliary/msvc-imp-present.rs b/src/test/ui/lto/auxiliary/msvc-imp-present.rs
new file mode 100644 (file)
index 0000000..933af05
--- /dev/null
@@ -0,0 +1,11 @@
+// no-prefer-dynamic
+// compile-flags: -Z thinlto -C codegen-units=8 -C prefer-dynamic
+
+#![crate_type = "rlib"]
+#![crate_type = "dylib"]
+
+pub static A: u32 = 43;
+
+pub mod a {
+    pub static A: u32 = 43;
+}
diff --git a/src/test/ui/lto/auxiliary/thin-lto-inlines-aux.rs b/src/test/ui/lto/auxiliary/thin-lto-inlines-aux.rs
new file mode 100644 (file)
index 0000000..5fd3f19
--- /dev/null
@@ -0,0 +1,7 @@
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+pub fn bar() -> u32 {
+    3
+}
diff --git a/src/test/ui/lto/dylib-works.rs b/src/test/ui/lto/dylib-works.rs
new file mode 100644 (file)
index 0000000..9e0782b
--- /dev/null
@@ -0,0 +1,9 @@
+// run-pass
+
+// aux-build:dylib.rs
+
+extern crate dylib;
+
+fn main() {
+    dylib::foo(1);
+}
diff --git a/src/test/ui/lto/lto-and-no-bitcode-in-rlib.rs b/src/test/ui/lto/lto-and-no-bitcode-in-rlib.rs
new file mode 100644 (file)
index 0000000..f381240
--- /dev/null
@@ -0,0 +1,3 @@
+// compile-flags: -C lto -C embed-bitcode=no
+
+fn main() {}
diff --git a/src/test/ui/lto/lto-and-no-bitcode-in-rlib.stderr b/src/test/ui/lto/lto-and-no-bitcode-in-rlib.stderr
new file mode 100644 (file)
index 0000000..11e370e
--- /dev/null
@@ -0,0 +1,2 @@
+error: options `-C embed-bitcode=no` and `-C lto` are incompatible
+
diff --git a/src/test/ui/lto/lto-duplicate-symbols.rs b/src/test/ui/lto/lto-duplicate-symbols.rs
new file mode 100644 (file)
index 0000000..268cf26
--- /dev/null
@@ -0,0 +1,11 @@
+// build-fail
+// aux-build:lto-duplicate-symbols1.rs
+// aux-build:lto-duplicate-symbols2.rs
+// error-pattern:Linking globals named 'foo': symbol multiply defined!
+// compile-flags: -C lto
+// no-prefer-dynamic
+
+extern crate lto_duplicate_symbols1;
+extern crate lto_duplicate_symbols2;
+
+fn main() {}
diff --git a/src/test/ui/lto/lto-duplicate-symbols.stderr b/src/test/ui/lto/lto-duplicate-symbols.stderr
new file mode 100644 (file)
index 0000000..e4de04e
--- /dev/null
@@ -0,0 +1,6 @@
+warning: Linking globals named 'foo': symbol multiply defined!
+
+error: failed to load bc of "lto-duplicate-symbols2.lto_duplicate_symbols2.693a75b4-cgu.0.rcgu.o": 
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/src/test/ui/lto/lto-many-codegen-units.rs b/src/test/ui/lto/lto-many-codegen-units.rs
new file mode 100644 (file)
index 0000000..f0f461f
--- /dev/null
@@ -0,0 +1,6 @@
+// run-pass
+// compile-flags: -C lto -C codegen-units=8
+// no-prefer-dynamic
+
+fn main() {
+}
diff --git a/src/test/ui/lto/lto-opt-level-s.rs b/src/test/ui/lto/lto-opt-level-s.rs
new file mode 100644 (file)
index 0000000..a7d9d50
--- /dev/null
@@ -0,0 +1,7 @@
+// compile-flags: -Clinker-plugin-lto -Copt-level=s
+// build-pass
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+pub fn foo() {}
diff --git a/src/test/ui/lto/lto-opt-level-z.rs b/src/test/ui/lto/lto-opt-level-z.rs
new file mode 100644 (file)
index 0000000..bf1f5e2
--- /dev/null
@@ -0,0 +1,7 @@
+// compile-flags: -Clinker-plugin-lto -Copt-level=z
+// build-pass
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+pub fn foo() {}
diff --git a/src/test/ui/lto/lto-rustc-loads-linker-plugin.rs b/src/test/ui/lto/lto-rustc-loads-linker-plugin.rs
new file mode 100644 (file)
index 0000000..6ef1d45
--- /dev/null
@@ -0,0 +1,17 @@
+// compile-flags: -C lto
+// aux-build:lto-rustc-loads-linker-plugin.rs
+// run-pass
+// no-prefer-dynamic
+
+// This test ensures that if a dependency was compiled with
+// `-Clinker-plugin-lto` then we can compile with `-Clto` and still link against
+// that upstream rlib. This should work because LTO implies we're not actually
+// linking against upstream rlibs since we're generating the object code
+// locally. This test will fail if rustc can't find bytecode in rlibs compiled
+// with `-Clinker-plugin-lto`.
+
+extern crate lto_rustc_loads_linker_plugin;
+
+fn main() {
+    lto_rustc_loads_linker_plugin::foo();
+}
diff --git a/src/test/ui/lto/lto-still-runs-thread-dtors.rs b/src/test/ui/lto/lto-still-runs-thread-dtors.rs
new file mode 100644 (file)
index 0000000..1c7368b
--- /dev/null
@@ -0,0 +1,34 @@
+// run-pass
+// compile-flags: -C lto
+// no-prefer-dynamic
+// ignore-emscripten no threads support
+// revisions: mir thir
+// [thir]compile-flags: -Zthir-unsafeck
+
+use std::thread;
+
+static mut HIT: usize = 0;
+
+thread_local!(static A: Foo = Foo);
+
+struct Foo;
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        unsafe {
+            HIT += 1;
+        }
+    }
+}
+
+fn main() {
+    unsafe {
+        assert_eq!(HIT, 0);
+        thread::spawn(|| {
+            assert_eq!(HIT, 0);
+            A.with(|_| ());
+            assert_eq!(HIT, 0);
+        }).join().unwrap();
+        assert_eq!(HIT, 1);
+    }
+}
diff --git a/src/test/ui/lto/lto-thin-rustc-loads-linker-plugin.rs b/src/test/ui/lto/lto-thin-rustc-loads-linker-plugin.rs
new file mode 100644 (file)
index 0000000..4d54ce3
--- /dev/null
@@ -0,0 +1,13 @@
+// compile-flags: -C lto=thin
+// aux-build:lto-rustc-loads-linker-plugin.rs
+// run-pass
+// no-prefer-dynamic
+
+// Same as the adjacent `lto-thin-rustc-loads-linker-plugin.rs` test, only with
+// ThinLTO.
+
+extern crate lto_rustc_loads_linker_plugin;
+
+fn main() {
+    lto_rustc_loads_linker_plugin::foo();
+}
diff --git a/src/test/ui/lto/msvc-imp-present.rs b/src/test/ui/lto/msvc-imp-present.rs
new file mode 100644 (file)
index 0000000..5498afb
--- /dev/null
@@ -0,0 +1,22 @@
+// run-pass
+
+// aux-build:msvc-imp-present.rs
+// compile-flags: -Z thinlto -C codegen-units=8
+// no-prefer-dynamic
+
+// On MSVC we have a "hack" where we emit symbols that look like `_imp_$name`
+// for all exported statics. This is done because we apply `dllimport` to all
+// imported constants and this allows everything to actually link correctly.
+//
+// The ThinLTO passes aggressively remove symbols if they can, and this test
+// asserts that the ThinLTO passes don't remove these compiler-generated
+// `_imp_*` symbols. The external library that we link in here is compiled with
+// ThinLTO and multiple codegen units and has a few exported constants. Note
+// that we also namely compile the library as both a dylib and an rlib, but we
+// link the rlib to ensure that we assert those generated symbols exist.
+
+extern crate msvc_imp_present as bar;
+
+fn main() {
+    println!("{}", bar::A);
+}
diff --git a/src/test/ui/lto/thin-lto-global-allocator.rs b/src/test/ui/lto/thin-lto-global-allocator.rs
new file mode 100644 (file)
index 0000000..e00c5ca
--- /dev/null
@@ -0,0 +1,7 @@
+// run-pass
+// compile-flags: -Z thinlto -C codegen-units=2
+
+#[global_allocator]
+static A: std::alloc::System = std::alloc::System;
+
+fn main() {}
diff --git a/src/test/ui/lto/thin-lto-inlines.rs b/src/test/ui/lto/thin-lto-inlines.rs
new file mode 100644 (file)
index 0000000..dca7918
--- /dev/null
@@ -0,0 +1,30 @@
+// run-pass
+
+// compile-flags: -Z thinlto -C codegen-units=8 -O
+// ignore-emscripten can't inspect instructions on emscripten
+
+// We want to assert here that ThinLTO will inline across codegen units. There's
+// not really a great way to do that in general so we sort of hack around it by
+// praying two functions go into separate codegen units and then assuming that
+// if inlining *doesn't* happen the first byte of the functions will differ.
+
+pub fn foo() -> u32 {
+    bar::bar()
+}
+
+mod bar {
+    pub fn bar() -> u32 {
+        3
+    }
+}
+
+fn main() {
+    println!("{} {}", foo(), bar::bar());
+
+    unsafe {
+        let foo = foo as usize as *const u8;
+        let bar = bar::bar as usize as *const u8;
+
+        assert_eq!(*foo, *bar);
+    }
+}
diff --git a/src/test/ui/lto/thin-lto-inlines2.rs b/src/test/ui/lto/thin-lto-inlines2.rs
new file mode 100644 (file)
index 0000000..1eb2965
--- /dev/null
@@ -0,0 +1,28 @@
+// run-pass
+
+// compile-flags: -C codegen-units=8 -O -C lto=thin
+// aux-build:thin-lto-inlines-aux.rs
+// no-prefer-dynamic
+// ignore-emscripten can't inspect instructions on emscripten
+
+// We want to assert here that ThinLTO will inline across codegen units. There's
+// not really a great way to do that in general so we sort of hack around it by
+// praying two functions go into separate codegen units and then assuming that
+// if inlining *doesn't* happen the first byte of the functions will differ.
+
+extern crate thin_lto_inlines_aux as bar;
+
+pub fn foo() -> u32 {
+    bar::bar()
+}
+
+fn main() {
+    println!("{} {}", foo(), bar::bar());
+
+    unsafe {
+        let foo = foo as usize as *const u8;
+        let bar = bar::bar as usize as *const u8;
+
+        assert_eq!(*foo, *bar);
+    }
+}
diff --git a/src/test/ui/lto/weak-works.rs b/src/test/ui/lto/weak-works.rs
new file mode 100644 (file)
index 0000000..163a387
--- /dev/null
@@ -0,0 +1,28 @@
+// run-pass
+
+// compile-flags: -C codegen-units=8 -Z thinlto
+// ignore-windows
+
+#![feature(linkage)]
+
+pub mod foo {
+    #[linkage = "weak"]
+    #[no_mangle]
+    pub extern "C" fn FOO() -> i32 {
+        0
+    }
+}
+
+mod bar {
+    extern "C" {
+        fn FOO() -> i32;
+    }
+
+    pub fn bar() -> i32 {
+        unsafe { FOO() }
+    }
+}
+
+fn main() {
+    bar::bar();
+}
diff --git a/src/test/ui/lub-glb-with-unbound-infer-var.rs b/src/test/ui/lub-glb-with-unbound-infer-var.rs
deleted file mode 100644 (file)
index c9e1170..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-// Test for a specific corner case: when we compute the LUB of two fn
-// types and their parameters have unbound variables. In that case, we
-// wind up relating those two variables. This was causing an ICE in an
-// in-progress PR.
-
-fn main() {
-    let a_f: fn(_) = |_| ();
-    let b_f: fn(_) = |_| ();
-    let c_f = match 22 {
-        0 => a_f,
-        _ => b_f,
-    };
-    c_f(4);
-}
diff --git a/src/test/ui/macros/auxiliary/issue-19163.rs b/src/test/ui/macros/auxiliary/issue-19163.rs
new file mode 100644 (file)
index 0000000..0c0d9e4
--- /dev/null
@@ -0,0 +1,6 @@
+#![crate_type = "lib"]
+
+#[macro_export]
+macro_rules! mywrite {
+    ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*)))
+}
diff --git a/src/test/ui/macros/issue-16098.rs b/src/test/ui/macros/issue-16098.rs
new file mode 100644 (file)
index 0000000..00acc20
--- /dev/null
@@ -0,0 +1,16 @@
+macro_rules! prob1 {
+    (0) => {
+        0
+    };
+    ($n:expr) => {
+        if ($n % 3 == 0) || ($n % 5 == 0) {
+            $n + prob1!($n - 1); //~ ERROR recursion limit reached while expanding `prob1!`
+        } else {
+            prob1!($n - 1);
+        }
+    };
+}
+
+fn main() {
+    println!("Problem 1: {}", prob1!(1000));
+}
diff --git a/src/test/ui/macros/issue-16098.stderr b/src/test/ui/macros/issue-16098.stderr
new file mode 100644 (file)
index 0000000..6428021
--- /dev/null
@@ -0,0 +1,14 @@
+error: recursion limit reached while expanding `prob1!`
+  --> $DIR/issue-16098.rs:7:18
+   |
+LL |             $n + prob1!($n - 1);
+   |                  ^^^^^^^^^^^^^^
+...
+LL |     println!("Problem 1: {}", prob1!(1000));
+   |                               ------------ in this macro invocation
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_16098`)
+   = note: this error originates in the macro `prob1` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/issue-19163.rs b/src/test/ui/macros/issue-19163.rs
new file mode 100644 (file)
index 0000000..d98c591
--- /dev/null
@@ -0,0 +1,11 @@
+// aux-build:issue-19163.rs
+
+#[macro_use] extern crate issue_19163;
+
+use std::io::Write;
+
+fn main() {
+    let mut v = vec![];
+    mywrite!(&v, "Hello world");
+    //~^ ERROR cannot borrow data in a `&` reference as mutable
+}
diff --git a/src/test/ui/macros/issue-19163.stderr b/src/test/ui/macros/issue-19163.stderr
new file mode 100644 (file)
index 0000000..ae1ae14
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow data in a `&` reference as mutable
+  --> $DIR/issue-19163.rs:9:5
+   |
+LL |     mywrite!(&v, "Hello world");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
+   |
+   = note: this error originates in the macro `mywrite` (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 E0596`.
diff --git a/src/test/ui/macros/issue-21356.rs b/src/test/ui/macros/issue-21356.rs
new file mode 100644 (file)
index 0000000..ae62392
--- /dev/null
@@ -0,0 +1,6 @@
+#![allow(unused_macros)]
+
+macro_rules! test { ($wrong:t_ty ..) => () }
+                  //~^ ERROR: invalid fragment specifier `t_ty`
+
+fn main() {}
diff --git a/src/test/ui/macros/issue-21356.stderr b/src/test/ui/macros/issue-21356.stderr
new file mode 100644 (file)
index 0000000..17014c6
--- /dev/null
@@ -0,0 +1,10 @@
+error: invalid fragment specifier `t_ty`
+  --> $DIR/issue-21356.rs:3:22
+   |
+LL | macro_rules! test { ($wrong:t_ty ..) => () }
+   |                      ^^^^^^^^^^^
+   |
+   = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/issue-22463.rs b/src/test/ui/macros/issue-22463.rs
new file mode 100644 (file)
index 0000000..fdf5a2f
--- /dev/null
@@ -0,0 +1,20 @@
+// run-pass
+macro_rules! items {
+    () => {
+        type A = ();
+        fn a() {}
+    }
+}
+
+trait Foo {
+    type A;
+    fn a();
+}
+
+impl Foo for () {
+    items!();
+}
+
+fn main() {
+
+}
diff --git a/src/test/ui/macros/issue-29084.rs b/src/test/ui/macros/issue-29084.rs
new file mode 100644 (file)
index 0000000..d162526
--- /dev/null
@@ -0,0 +1,13 @@
+macro_rules! foo {
+    ($d:expr) => {{
+        fn bar(d: u8) { }
+        bar(&mut $d);
+        //~^ ERROR mismatched types
+        //~| expected `u8`, found `&mut u8`
+    }}
+}
+
+fn main() {
+    foo!(0u8);
+    //~^ in this expansion of foo!
+}
diff --git a/src/test/ui/macros/issue-29084.stderr b/src/test/ui/macros/issue-29084.stderr
new file mode 100644 (file)
index 0000000..a973e23
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-29084.rs:4:13
+   |
+LL |         bar(&mut $d);
+   |             ^^^^^^^ expected `u8`, found `&mut u8`
+...
+LL |     foo!(0u8);
+   |     --------- in this macro invocation
+   |
+   = note: this error originates in the macro `foo` (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 E0308`.
diff --git a/src/test/ui/macros/issue-34171.rs b/src/test/ui/macros/issue-34171.rs
new file mode 100644 (file)
index 0000000..157c58c
--- /dev/null
@@ -0,0 +1,10 @@
+// check-pass
+
+macro_rules! null { ($i:tt) => {} }
+macro_rules! apply_null {
+    ($i:item) => { null! { $i } }
+}
+
+fn main() {
+    apply_null!(#[cfg(all())] fn f() {});
+}
diff --git a/src/test/ui/macros/issue-37175.rs b/src/test/ui/macros/issue-37175.rs
new file mode 100644 (file)
index 0000000..9ec9d48
--- /dev/null
@@ -0,0 +1,5 @@
+// run-pass
+macro_rules! m { (<$t:ty>) => { stringify!($t) } }
+fn main() {
+    println!("{}", m!(<Vec<i32>>));
+}
diff --git a/src/test/ui/macros/issue-39388.rs b/src/test/ui/macros/issue-39388.rs
new file mode 100644 (file)
index 0000000..a8e31a6
--- /dev/null
@@ -0,0 +1,9 @@
+#![allow(unused_macros)]
+
+macro_rules! assign {
+    (($($a:tt)*) = ($($b:tt))*) => { //~ ERROR expected one of: `*`, `+`, or `?`
+        $($a)* = $($b)*
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/macros/issue-39388.stderr b/src/test/ui/macros/issue-39388.stderr
new file mode 100644 (file)
index 0000000..62e7dff
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected one of: `*`, `+`, or `?`
+  --> $DIR/issue-39388.rs:4:22
+   |
+LL |     (($($a:tt)*) = ($($b:tt))*) => {
+   |                      ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/issue-40770.rs b/src/test/ui/macros/issue-40770.rs
new file mode 100644 (file)
index 0000000..c9713c1
--- /dev/null
@@ -0,0 +1,11 @@
+// run-pass
+#![allow(unused_macros)]
+macro_rules! m {
+    ($e:expr) => {
+        macro_rules! n { () => { $e } }
+    }
+}
+
+fn main() {
+    m!(foo!());
+}
diff --git a/src/test/ui/macros/issue-57597.rs b/src/test/ui/macros/issue-57597.rs
new file mode 100644 (file)
index 0000000..ebeb3fe
--- /dev/null
@@ -0,0 +1,80 @@
+// Regression test for #57597.
+//
+// Make sure that nested matchers work correctly rather than causing an infinite loop or crash.
+
+// edition:2018
+
+macro_rules! foo1 {
+    ($($($i:ident)?)+) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo2 {
+    ($($($i:ident)?)*) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo3 {
+    ($($($i:ident)?)?) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo4 {
+    ($($($($i:ident)?)?)?) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo5 {
+    ($($($($i:ident)*)?)?) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo6 {
+    ($($($($i:ident)?)*)?) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo7 {
+    ($($($($i:ident)?)?)*) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo8 {
+    ($($($($i:ident)*)*)?) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo9 {
+    ($($($($i:ident)?)*)*) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo10 {
+    ($($($($i:ident)?)*)+) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo11 {
+    ($($($($i:ident)+)?)*) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+macro_rules! foo12 {
+    ($($($($i:ident)+)*)?) => {};
+    //~^ ERROR repetition matches empty token tree
+}
+
+fn main() {
+    foo1!();
+    foo2!();
+    foo3!();
+    foo4!();
+    foo5!();
+    foo6!();
+    foo7!();
+    foo8!();
+    foo9!();
+    foo10!();
+    foo11!();
+    foo12!();
+}
diff --git a/src/test/ui/macros/issue-57597.stderr b/src/test/ui/macros/issue-57597.stderr
new file mode 100644 (file)
index 0000000..0a02ac8
--- /dev/null
@@ -0,0 +1,74 @@
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:8:7
+   |
+LL |     ($($($i:ident)?)+) => {};
+   |       ^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:13:7
+   |
+LL |     ($($($i:ident)?)*) => {};
+   |       ^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:18:7
+   |
+LL |     ($($($i:ident)?)?) => {};
+   |       ^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:23:7
+   |
+LL |     ($($($($i:ident)?)?)?) => {};
+   |       ^^^^^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:28:7
+   |
+LL |     ($($($($i:ident)*)?)?) => {};
+   |       ^^^^^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:33:7
+   |
+LL |     ($($($($i:ident)?)*)?) => {};
+   |       ^^^^^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:38:7
+   |
+LL |     ($($($($i:ident)?)?)*) => {};
+   |       ^^^^^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:43:7
+   |
+LL |     ($($($($i:ident)*)*)?) => {};
+   |       ^^^^^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:48:7
+   |
+LL |     ($($($($i:ident)?)*)*) => {};
+   |       ^^^^^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:53:7
+   |
+LL |     ($($($($i:ident)?)*)+) => {};
+   |       ^^^^^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:58:7
+   |
+LL |     ($($($($i:ident)+)?)*) => {};
+   |       ^^^^^^^^^^^^^^^^^^
+
+error: repetition matches empty token tree
+  --> $DIR/issue-57597.rs:63:7
+   |
+LL |     ($($($($i:ident)+)*)?) => {};
+   |       ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
diff --git a/src/test/ui/macros/issue-6596-1.rs b/src/test/ui/macros/issue-6596-1.rs
new file mode 100644 (file)
index 0000000..25f1d65
--- /dev/null
@@ -0,0 +1,10 @@
+macro_rules! e {
+    ($inp:ident) => (
+        $nonexistent
+        //~^ ERROR expected expression, found `$`
+    );
+}
+
+fn main() {
+    e!(foo);
+}
diff --git a/src/test/ui/macros/issue-6596-1.stderr b/src/test/ui/macros/issue-6596-1.stderr
new file mode 100644 (file)
index 0000000..7ab3685
--- /dev/null
@@ -0,0 +1,13 @@
+error: expected expression, found `$`
+  --> $DIR/issue-6596-1.rs:3:9
+   |
+LL |         $nonexistent
+   |         ^^^^^^^^^^^^ expected expression
+...
+LL |     e!(foo);
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `e` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/issue-86865.rs b/src/test/ui/macros/issue-86865.rs
new file mode 100644 (file)
index 0000000..01e0a20
--- /dev/null
@@ -0,0 +1,11 @@
+use std::fmt::Write;
+
+fn main() {
+    println!(b"foo");
+    //~^ ERROR format argument must be a string literal
+    //~| HELP consider removing the leading `b`
+    let mut s = String::new();
+    write!(s, b"foo{}", "bar");
+    //~^ ERROR format argument must be a string literal
+    //~| HELP consider removing the leading `b`
+}
diff --git a/src/test/ui/macros/issue-86865.stderr b/src/test/ui/macros/issue-86865.stderr
new file mode 100644 (file)
index 0000000..eed7553
--- /dev/null
@@ -0,0 +1,18 @@
+error: format argument must be a string literal
+  --> $DIR/issue-86865.rs:4:14
+   |
+LL |     println!(b"foo");
+   |              -^^^^^
+   |              |
+   |              help: consider removing the leading `b`
+
+error: format argument must be a string literal
+  --> $DIR/issue-86865.rs:8:15
+   |
+LL |     write!(s, b"foo{}", "bar");
+   |               -^^^^^^^
+   |               |
+   |               help: consider removing the leading `b`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/macros/trace_macros-format.rs b/src/test/ui/macros/trace_macros-format.rs
new file mode 100644 (file)
index 0000000..afca45c
--- /dev/null
@@ -0,0 +1,18 @@
+#![feature(trace_macros)]
+
+fn main() {
+    trace_macros!(); //~ ERROR trace_macros! accepts only `true` or `false`
+    trace_macros!(1); //~ ERROR trace_macros! accepts only `true` or `false`
+    trace_macros!(ident); //~ ERROR trace_macros! accepts only `true` or `false`
+    trace_macros!(for); //~ ERROR trace_macros! accepts only `true` or `false`
+    trace_macros!(true,); //~ ERROR trace_macros! accepts only `true` or `false`
+    trace_macros!(false 1); //~ ERROR trace_macros! accepts only `true` or `false`
+
+
+    // should be fine:
+    macro_rules! expando {
+        ($x: ident) => { trace_macros!($x) }
+    }
+
+    expando!(true);
+}
diff --git a/src/test/ui/macros/trace_macros-format.stderr b/src/test/ui/macros/trace_macros-format.stderr
new file mode 100644 (file)
index 0000000..c320270
--- /dev/null
@@ -0,0 +1,38 @@
+error: trace_macros! accepts only `true` or `false`
+  --> $DIR/trace_macros-format.rs:4:5
+   |
+LL |     trace_macros!();
+   |     ^^^^^^^^^^^^^^^
+
+error: trace_macros! accepts only `true` or `false`
+  --> $DIR/trace_macros-format.rs:5:5
+   |
+LL |     trace_macros!(1);
+   |     ^^^^^^^^^^^^^^^^
+
+error: trace_macros! accepts only `true` or `false`
+  --> $DIR/trace_macros-format.rs:6:5
+   |
+LL |     trace_macros!(ident);
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: trace_macros! accepts only `true` or `false`
+  --> $DIR/trace_macros-format.rs:7:5
+   |
+LL |     trace_macros!(for);
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: trace_macros! accepts only `true` or `false`
+  --> $DIR/trace_macros-format.rs:8:5
+   |
+LL |     trace_macros!(true,);
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: trace_macros! accepts only `true` or `false`
+  --> $DIR/trace_macros-format.rs:9:5
+   |
+LL |     trace_macros!(false 1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs b/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs
new file mode 100644 (file)
index 0000000..1e41312
--- /dev/null
@@ -0,0 +1,20 @@
+// run-pass
+
+#![feature(marker_trait_attr)]
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+#[marker]
+trait MyMarker {}
+
+impl<T> MyMarker for T {}
+impl<T> MyMarker for Vec<T> {}
+
+fn foo<T: MyMarker>(t: T) -> T {
+    t
+}
+
+fn main() {
+    assert_eq!(1, foo(1));
+    assert_eq!(2.0, foo(2.0));
+    assert_eq!(vec![1], foo(vec![1]));
+}
diff --git a/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr b/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr
new file mode 100644 (file)
index 0000000..fca9866
--- /dev/null
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/overlap-doesnt-conflict-with-specialization.rs:4:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/marker_trait_attr/overlap-permitted-for-annotated-marker-traits.rs b/src/test/ui/marker_trait_attr/overlap-permitted-for-annotated-marker-traits.rs
new file mode 100644 (file)
index 0000000..3833139
--- /dev/null
@@ -0,0 +1,26 @@
+// run-pass
+// Tests for RFC 1268: we allow overlapping impls of marker traits,
+// that is, traits with #[marker]. In this case, a type `T` is
+// `MyMarker` if it is either `Debug` or `Display`.
+
+#![feature(marker_trait_attr)]
+
+use std::fmt::{Debug, Display};
+
+#[marker] trait MyMarker {}
+
+impl<T: Debug> MyMarker for T {}
+impl<T: Display> MyMarker for T {}
+
+fn foo<T: MyMarker>(t: T) -> T {
+    t
+}
+
+fn main() {
+    // Debug && Display:
+    assert_eq!(1, foo(1));
+    assert_eq!(2.0, foo(2.0));
+
+    // Debug && !Display:
+    assert_eq!(vec![1], foo(vec![1]));
+}
diff --git a/src/test/ui/match/issue-11940.rs b/src/test/ui/match/issue-11940.rs
new file mode 100644 (file)
index 0000000..6815c87
--- /dev/null
@@ -0,0 +1,11 @@
+// run-pass
+
+const TEST_STR: &'static str = "abcd";
+
+fn main() {
+    let s = "abcd";
+    match s {
+        TEST_STR => (),
+        _ => unreachable!()
+    }
+}
diff --git a/src/test/ui/match/issue-18060.rs b/src/test/ui/match/issue-18060.rs
new file mode 100644 (file)
index 0000000..b5f3d0f
--- /dev/null
@@ -0,0 +1,8 @@
+// run-pass
+// Regression test for #18060: match arms were matching in the wrong order.
+
+fn main() {
+    assert_eq!(2, match (1, 3) { (0, 2..=5) => 1, (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 });
+    assert_eq!(2, match (1, 3) {                  (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 });
+    assert_eq!(2, match (1, 7) { (0, 2..=5) => 1, (1, 7) => 2, (_, 2..=5) => 3, (_, _) => 4 });
+}
diff --git a/src/test/ui/match/issue-26251.rs b/src/test/ui/match/issue-26251.rs
new file mode 100644 (file)
index 0000000..a3e26a4
--- /dev/null
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(overlapping_range_endpoints)]
+
+fn main() {
+    let x = 'a';
+
+    let y = match x {
+        'a'..='b' if false => "one",
+        'a' => "two",
+        'a'..='b' => "three",
+        _ => panic!("what?"),
+    };
+
+    assert_eq!(y, "two");
+}
diff --git a/src/test/ui/match/issue-26996.rs b/src/test/ui/match/issue-26996.rs
new file mode 100644 (file)
index 0000000..84037b7
--- /dev/null
@@ -0,0 +1,24 @@
+// run-pass
+
+// This test is bogus (i.e., should be check-fail) during the period
+// where #54986 is implemented and #54987 is *not* implemented. For
+// now: just ignore it
+//
+// ignore-test
+
+// This test is checking that the write to `c.0` (which has been moved out of)
+// won't overwrite the state in `c2`.
+//
+// That's a fine thing to test when this code is accepted by the
+// compiler, and this code is being transcribed accordingly into
+// the ui test issue-21232-partial-init-and-use.rs
+
+fn main() {
+    let mut c = (1, "".to_owned());
+    match c {
+        c2 => {
+            c.0 = 2;
+            assert_eq!(c2.0, 1);
+        }
+    }
+}
diff --git a/src/test/ui/match/issue-42679.rs b/src/test/ui/match/issue-42679.rs
new file mode 100644 (file)
index 0000000..596309f
--- /dev/null
@@ -0,0 +1,22 @@
+// run-pass
+#![feature(box_syntax)]
+#![feature(box_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum Test {
+    Foo(usize),
+    Bar(isize),
+}
+
+fn main() {
+    let a = box Test::Foo(10);
+    let b = box Test::Bar(-20);
+    match (a, b) {
+        (_, box Test::Foo(_)) => unreachable!(),
+        (box Test::Foo(x), b) => {
+            assert_eq!(x, 10);
+            assert_eq!(b, box Test::Bar(-20));
+        },
+        _ => unreachable!(),
+    }
+}
index f5497c1d16de61257a39b1df56029f20477a283d..9143a8cdd59bc915e1daff145d699adcb6fa5cd6 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 // edition:2021
-// compile-flags: -Zunstable-options
 
 // regression test for https://github.com/rust-lang/rust/pull/85678
 
diff --git a/src/test/ui/mir-dataflow/indirect-mutation-offset.rs b/src/test/ui/mir-dataflow/indirect-mutation-offset.rs
deleted file mode 100644 (file)
index 374a9f7..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-// compile-flags: -Zunleash-the-miri-inside-of-you
-
-// This test demonstrates a shortcoming of the `MaybeMutBorrowedLocals` analysis. It does not
-// handle code that takes a reference to one field of a struct, then use pointer arithmetic to
-// transform it to another field of that same struct that may have interior mutability. For now,
-// this is UB, but this may change in the future. See [rust-lang/unsafe-code-guidelines#134].
-//
-// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
-
-#![feature(core_intrinsics, rustc_attrs, const_raw_ptr_deref)]
-
-use std::cell::UnsafeCell;
-use std::intrinsics::rustc_peek;
-
-#[repr(C)]
-struct PartialInteriorMut {
-    zst: [i32; 0],
-    cell: UnsafeCell<i32>,
-}
-
-#[rustc_mir(rustc_peek_indirectly_mutable,stop_after_dataflow)]
-const BOO: i32 = {
-    let x = PartialInteriorMut {
-        zst: [],
-        cell: UnsafeCell::new(0),
-    };
-
-    let p_zst: *const _ = &x.zst ; // Doesn't cause `x` to get marked as indirectly mutable.
-
-    let rmut_cell = unsafe {
-        // Take advantage of the fact that `zst` and `cell` are at the same location in memory.
-        // This trick would work with any size type if miri implemented `ptr::offset`.
-        let p_cell = p_zst as *const UnsafeCell<i32>;
-
-        let pmut_cell = (*p_cell).get();
-        &mut *pmut_cell
-    };
-
-    *rmut_cell = 42;  // Mutates `x` indirectly even though `x` is not marked indirectly mutable!!!
-    let val = *rmut_cell;
-    rustc_peek(x); //~ ERROR rustc_peek: bit not set
-
-    val
-};
-
-fn main() {
-    println!("{}", BOO);
-}
diff --git a/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr b/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr
deleted file mode 100644 (file)
index 1d5287c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-error: rustc_peek: bit not set
-  --> $DIR/indirect-mutation-offset.rs:41:5
-   |
-LL |     rustc_peek(x);
-   |     ^^^^^^^^^^^^^
-
-error: stop_after_dataflow ended compilation
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/mir/issue-74739.rs b/src/test/ui/mir/issue-74739.rs
new file mode 100644 (file)
index 0000000..0362235
--- /dev/null
@@ -0,0 +1,14 @@
+// compile-flags: -O
+// run-pass
+
+struct Foo {
+    x: i32,
+}
+
+pub fn main() {
+    let mut foo = Foo { x: 42 };
+    let x = &mut foo.x;
+    *x = 13;
+    let y = foo;
+    assert_eq!(y.x, 13); // used to print 42 due to mir-opt bug
+}
diff --git a/src/test/ui/mut-vstore-expr.rs b/src/test/ui/mut-vstore-expr.rs
deleted file mode 100644 (file)
index 75b309a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// run-pass
-// pretty-expanded FIXME #23616
-
-pub fn main() {
-    let _x: &mut [isize] = &mut [ 1, 2, 3 ];
-}
diff --git a/src/test/ui/negative.rs b/src/test/ui/negative.rs
deleted file mode 100644 (file)
index 9601e91..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-pass
-
-pub fn main() {
-    match -5 {
-      -5 => {}
-      _ => { panic!() }
-    }
-}
diff --git a/src/test/ui/nested_item_main.rs b/src/test/ui/nested_item_main.rs
deleted file mode 100644 (file)
index 2fe00ae..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// run-pass
-// aux-build:nested_item.rs
-
-
-extern crate nested_item;
-
-pub fn main() {
-    assert_eq!(2, nested_item::foo::<()>());
-    assert_eq!(2, nested_item::foo::<isize>());
-}
diff --git a/src/test/ui/never_type/diverging-tuple-parts-39485.rs b/src/test/ui/never_type/diverging-tuple-parts-39485.rs
new file mode 100644 (file)
index 0000000..0cde611
--- /dev/null
@@ -0,0 +1,15 @@
+// After #39485, this test used to pass, but that change was reverted
+// due to numerous inference failures like #39808, so it now fails
+// again. #39485 made it so that diverging types never propagate
+// upward; but we now do propagate such types upward in many more
+// cases.
+
+fn g() {
+    &panic!() //~ ERROR mismatched types
+}
+
+fn f() -> isize {
+    (return 1, return 2) //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/never_type/diverging-tuple-parts-39485.stderr b/src/test/ui/never_type/diverging-tuple-parts-39485.stderr
new file mode 100644 (file)
index 0000000..32967b3
--- /dev/null
@@ -0,0 +1,32 @@
+error[E0308]: mismatched types
+  --> $DIR/diverging-tuple-parts-39485.rs:8:5
+   |
+LL |     &panic!()
+   |     ^^^^^^^^^ expected `()`, found reference
+   |
+   = note: expected unit type `()`
+              found reference `&_`
+help: try adding a return type
+   |
+LL | fn g() -> &_ {
+   |        +++++
+help: consider removing the borrow
+   |
+LL -     &panic!()
+LL +     panic!()
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/diverging-tuple-parts-39485.rs:12:5
+   |
+LL | fn f() -> isize {
+   |           ----- expected `isize` because of return type
+LL |     (return 1, return 2)
+   |     ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found tuple
+   |
+   = note: expected type `isize`
+             found tuple `(!, !)`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/new-box.rs b/src/test/ui/new-box.rs
deleted file mode 100644 (file)
index 96a3b19..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// run-pass
-
-fn f(x: Box<isize>) {
-    let y: &isize = &*x;
-    println!("{}", *x);
-    println!("{}", *y);
-}
-
-trait Trait {
-    fn printme(&self);
-}
-
-struct Struct;
-
-impl Trait for Struct {
-    fn printme(&self) {
-        println!("hello world!");
-    }
-}
-
-fn g(x: Box<dyn Trait>) {
-    x.printme();
-    let y: &dyn Trait = &*x;
-    y.printme();
-}
-
-fn main() {
-    f(Box::new(1234));
-    g(Box::new(Struct) as Box<dyn Trait>);
-}
diff --git a/src/test/ui/nil-decl-in-foreign.rs b/src/test/ui/nil-decl-in-foreign.rs
deleted file mode 100644 (file)
index f3be948..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// run-pass
-
-#![allow(improper_ctypes)]
-#![allow(dead_code)]
-// Issue #901
-// pretty-expanded FIXME #23616
-
-mod libc {
-    extern "C" {
-        pub fn printf(x: ());
-    }
-}
-
-pub fn main() {}
diff --git a/src/test/ui/numbers-arithmetic/unary-minus-suffix-inference.rs b/src/test/ui/numbers-arithmetic/unary-minus-suffix-inference.rs
new file mode 100644 (file)
index 0000000..a4d0a84
--- /dev/null
@@ -0,0 +1,23 @@
+// run-pass
+
+pub fn main() {
+    let a = 1;
+    let a_neg: i8 = -a;
+    println!("{}", a_neg);
+
+    let b = 1;
+    let b_neg: i16 = -b;
+    println!("{}", b_neg);
+
+    let c = 1;
+    let c_neg: i32 = -c;
+    println!("{}", c_neg);
+
+    let d = 1;
+    let d_neg: i64 = -d;
+    println!("{}", d_neg);
+
+    let e = 1;
+    let e_neg: isize = -e;
+    println!("{}", e_neg);
+}
diff --git a/src/test/ui/object-does-not-impl-trait.rs b/src/test/ui/object-does-not-impl-trait.rs
deleted file mode 100644 (file)
index b3b6798..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// Test that an object type `Box<Foo>` is not considered to implement the
-// trait `Foo`. Issue #5087.
-
-trait Foo {}
-fn take_foo<F:Foo>(f: F) {}
-fn take_object(f: Box<dyn Foo>) { take_foo(f); }
-//~^ ERROR `Box<dyn Foo>: Foo` is not satisfied
-fn main() {}
diff --git a/src/test/ui/object-does-not-impl-trait.stderr b/src/test/ui/object-does-not-impl-trait.stderr
deleted file mode 100644 (file)
index f1dd508..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0277]: the trait bound `Box<dyn Foo>: Foo` is not satisfied
-  --> $DIR/object-does-not-impl-trait.rs:6:44
-   |
-LL | fn take_object(f: Box<dyn Foo>) { take_foo(f); }
-   |                                   -------- ^ the trait `Foo` is not implemented for `Box<dyn Foo>`
-   |                                   |
-   |                                   required by a bound introduced by this call
-   |
-note: required by a bound in `take_foo`
-  --> $DIR/object-does-not-impl-trait.rs:5:15
-   |
-LL | fn take_foo<F:Foo>(f: F) {}
-   |               ^^^ required by this bound in `take_foo`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/overlap-doesnt-conflict-with-specialization.rs b/src/test/ui/overlap-doesnt-conflict-with-specialization.rs
deleted file mode 100644 (file)
index 1e41312..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// run-pass
-
-#![feature(marker_trait_attr)]
-#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
-
-#[marker]
-trait MyMarker {}
-
-impl<T> MyMarker for T {}
-impl<T> MyMarker for Vec<T> {}
-
-fn foo<T: MyMarker>(t: T) -> T {
-    t
-}
-
-fn main() {
-    assert_eq!(1, foo(1));
-    assert_eq!(2.0, foo(2.0));
-    assert_eq!(vec![1], foo(vec![1]));
-}
diff --git a/src/test/ui/overlap-doesnt-conflict-with-specialization.stderr b/src/test/ui/overlap-doesnt-conflict-with-specialization.stderr
deleted file mode 100644 (file)
index fca9866..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/overlap-doesnt-conflict-with-specialization.rs:4:12
-   |
-LL | #![feature(specialization)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
-   = help: consider using `min_specialization` instead, which is more stable and complete
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/overlap-permitted-for-annotated-marker-traits.rs b/src/test/ui/overlap-permitted-for-annotated-marker-traits.rs
deleted file mode 100644 (file)
index 3833139..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// run-pass
-// Tests for RFC 1268: we allow overlapping impls of marker traits,
-// that is, traits with #[marker]. In this case, a type `T` is
-// `MyMarker` if it is either `Debug` or `Display`.
-
-#![feature(marker_trait_attr)]
-
-use std::fmt::{Debug, Display};
-
-#[marker] trait MyMarker {}
-
-impl<T: Debug> MyMarker for T {}
-impl<T: Display> MyMarker for T {}
-
-fn foo<T: MyMarker>(t: T) -> T {
-    t
-}
-
-fn main() {
-    // Debug && Display:
-    assert_eq!(1, foo(1));
-    assert_eq!(2.0, foo(2.0));
-
-    // Debug && !Display:
-    assert_eq!(vec![1], foo(vec![1]));
-}
diff --git a/src/test/ui/packed/issue-46152.rs b/src/test/ui/packed/issue-46152.rs
new file mode 100644 (file)
index 0000000..fb1c9fb
--- /dev/null
@@ -0,0 +1,24 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![feature(unsize, coerce_unsized)]
+
+#[repr(packed)]
+struct UnalignedPtr<'a, T: ?Sized>
+    where T: 'a,
+{
+    data: &'a T,
+}
+
+fn main() {
+
+    impl<'a, T, U> std::ops::CoerceUnsized<UnalignedPtr<'a, U>> for UnalignedPtr<'a, T>
+        where
+        T: std::marker::Unsize<U> + ?Sized,
+        U: ?Sized,
+    { }
+
+    let arr = [1, 2, 3];
+    let arr_unaligned: UnalignedPtr<[i32; 3]> = UnalignedPtr { data: &arr };
+    let arr_unaligned: UnalignedPtr<[i32]> = arr_unaligned;
+}
diff --git a/src/test/ui/parser/bastion-of-the-turbofish.rs b/src/test/ui/parser/bastion-of-the-turbofish.rs
new file mode 100644 (file)
index 0000000..e128570
--- /dev/null
@@ -0,0 +1,43 @@
+// check-pass
+
+// Bastion of the Turbofish
+// ------------------------
+// Beware travellers, lest you venture into waters callous and unforgiving,
+// where hope must be abandoned, ere it is cruelly torn from you. For here
+// stands the bastion of the Turbofish: an impenetrable fortress holding
+// unshaking against those who would dare suggest the supererogation of the
+// Turbofish.
+//
+// Once I was young and foolish and had the impudence to imagine that I could
+// shake free from the coils by which that creature had us tightly bound. I
+// dared to suggest that there was a better way: a brighter future, in which
+// Rustaceans both new and old could be rid of that vile beast. But alas! In
+// my foolhardiness my ignorance was unveiled and my dreams were dashed
+// unforgivingly against the rock of syntactic ambiguity.
+//
+// This humble program, small and insignificant though it might seem,
+// demonstrates that to which we had previously cast a blind eye: an ambiguity
+// in permitting generic arguments to be provided without the consent of the
+// Great Turbofish. Should you be so naïve as to try to revolt against its
+// mighty clutches, here shall its wrath be indomitably displayed. This
+// program must pass for all eternity: forever watched by the guardian angel
+// which gave this beast its name, and stands fundamentally at odds with the
+// impetuous rebellion against the Turbofish.
+//
+// My heart aches in sorrow, for I know I am defeated. Let this be a warning
+// to all those who come after: for they too must overcome the impassible
+// hurdle of defeating the great beast, championed by a resolute winged
+// guardian.
+//
+// Here stands the Bastion of the Turbofish, a memorial to Anna Harren,
+// Guardian Angel of these Hallowed Grounds. <3
+
+// See https://github.com/rust-lang/rust/pull/53562
+// and https://github.com/rust-lang/rfcs/pull/2527
+// and https://twitter.com/garblefart/status/1393236602856611843
+// for context.
+
+fn main() {
+    let (the, guardian, stands, resolute) = ("the", "Turbofish", "remains", "undefeated");
+    let _: (bool, bool) = (the<guardian, stands>(resolute));
+}
diff --git a/src/test/ui/parser/issue-13483.rs b/src/test/ui/parser/issue-13483.rs
new file mode 100644 (file)
index 0000000..a2fd926
--- /dev/null
@@ -0,0 +1,17 @@
+fn main() {
+    if true {
+    } else if { //~ ERROR missing condition
+    //~^ ERROR mismatched types
+    } else {
+    }
+}
+
+fn foo() {
+    if true {
+    } else if { //~ ERROR missing condition
+    //~^ ERROR mismatched types
+    }
+    bar();
+}
+
+fn bar() {}
diff --git a/src/test/ui/parser/issue-13483.stderr b/src/test/ui/parser/issue-13483.stderr
new file mode 100644 (file)
index 0000000..5fd05b1
--- /dev/null
@@ -0,0 +1,33 @@
+error: missing condition for `if` expression
+  --> $DIR/issue-13483.rs:3:14
+   |
+LL |     } else if {
+   |              ^ expected if condition here
+
+error: missing condition for `if` expression
+  --> $DIR/issue-13483.rs:11:14
+   |
+LL |     } else if {
+   |              ^ expected if condition here
+
+error[E0308]: mismatched types
+  --> $DIR/issue-13483.rs:3:15
+   |
+LL |       } else if {
+   |  _______________^
+LL | |
+LL | |     } else {
+   | |_____^ expected `bool`, found `()`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-13483.rs:11:15
+   |
+LL |       } else if {
+   |  _______________^
+LL | |
+LL | |     }
+   | |_____^ expected `bool`, found `()`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issue-20616-4.rs b/src/test/ui/parser/issue-20616-4.rs
new file mode 100644 (file)
index 0000000..a71f47c
--- /dev/null
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+type Type_4<T> = Type_1_<'static,, T>;
+//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issue-20616-4.stderr b/src/test/ui/parser/issue-20616-4.stderr
new file mode 100644 (file)
index 0000000..2b3b75f
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `,`
+  --> $DIR/issue-20616-4.rs:16:34
+   |
+LL | type Type_4<T> = Type_1_<'static,, T>;
+   |                                  ^ expected one of `>`, a const expression, lifetime, or type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-20616-5.rs b/src/test/ui/parser/issue-20616-5.rs
new file mode 100644 (file)
index 0000000..b96d09d
--- /dev/null
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+type Type_5<'a> = Type_1_<'a, (),,>;
+//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issue-20616-5.stderr b/src/test/ui/parser/issue-20616-5.stderr
new file mode 100644 (file)
index 0000000..1ec1dbd
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `,`
+  --> $DIR/issue-20616-5.rs:22:34
+   |
+LL | type Type_5<'a> = Type_1_<'a, (),,>;
+   |                                  ^ expected one of `>`, a const expression, lifetime, or type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-20616-6.rs b/src/test/ui/parser/issue-20616-6.rs
new file mode 100644 (file)
index 0000000..a2c45ec
--- /dev/null
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+type Type_6 = Type_5_<'a,,>;
+//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issue-20616-6.stderr b/src/test/ui/parser/issue-20616-6.stderr
new file mode 100644 (file)
index 0000000..7401abd
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `,`
+  --> $DIR/issue-20616-6.rs:25:26
+   |
+LL | type Type_6 = Type_5_<'a,,>;
+   |                          ^ expected one of `>`, a const expression, lifetime, or type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-20616-7.rs b/src/test/ui/parser/issue-20616-7.rs
new file mode 100644 (file)
index 0000000..67209c0
--- /dev/null
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+type Type_7 = Box<(),,>;
+//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issue-20616-7.stderr b/src/test/ui/parser/issue-20616-7.stderr
new file mode 100644 (file)
index 0000000..e2c3efe
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `,`
+  --> $DIR/issue-20616-7.rs:28:22
+   |
+LL | type Type_7 = Box<(),,>;
+   |                      ^ expected one of `>`, a const expression, lifetime, or type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-21475.rs b/src/test/ui/parser/issue-21475.rs
new file mode 100644 (file)
index 0000000..b028fca
--- /dev/null
@@ -0,0 +1,19 @@
+// run-pass
+#![allow(unused_imports, overlapping_range_endpoints)]
+// pretty-expanded FIXME #23616
+
+use m::{START, END};
+
+fn main() {
+    match 42 {
+        m::START..=m::END => {},
+        0..=m::END => {},
+        m::START..=59 => {},
+        _  => {},
+    }
+}
+
+mod m {
+  pub const START: u32 = 4;
+  pub const END:   u32 = 14;
+}
diff --git a/src/test/ui/parser/issue-31804.rs b/src/test/ui/parser/issue-31804.rs
new file mode 100644 (file)
index 0000000..d056b77
--- /dev/null
@@ -0,0 +1,6 @@
+// Test that error recovery in the parser to an EOF does not give an infinite
+// spew of errors.
+
+fn main() {
+    let
+} //~ ERROR expected pattern, found `}`
diff --git a/src/test/ui/parser/issue-31804.stderr b/src/test/ui/parser/issue-31804.stderr
new file mode 100644 (file)
index 0000000..76e68b0
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected pattern, found `}`
+  --> $DIR/issue-31804.rs:6:1
+   |
+LL | }
+   | ^ expected pattern
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-34255-1.rs b/src/test/ui/parser/issue-34255-1.rs
new file mode 100644 (file)
index 0000000..c70cd8b
--- /dev/null
@@ -0,0 +1,10 @@
+enum Test {
+    Drill {
+        field: i32,
+    }
+}
+
+fn main() {
+    Test::Drill(field: 42);
+    //~^ ERROR invalid `struct` delimiters or `fn` call arguments
+}
diff --git a/src/test/ui/parser/issue-34255-1.stderr b/src/test/ui/parser/issue-34255-1.stderr
new file mode 100644 (file)
index 0000000..fbff75e
--- /dev/null
@@ -0,0 +1,18 @@
+error: invalid `struct` delimiters or `fn` call arguments
+  --> $DIR/issue-34255-1.rs:8:5
+   |
+LL |     Test::Drill(field: 42);
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: if `Test::Drill` is a struct, use braces as delimiters
+   |
+LL |     Test::Drill { field: 42 };
+   |                 ~           ~
+help: if `Test::Drill` is a function, use the arguments directly
+   |
+LL -     Test::Drill(field: 42);
+LL +     Test::Drill(42);
+   | 
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-49040.rs b/src/test/ui/parser/issue-49040.rs
new file mode 100644 (file)
index 0000000..b7a541d
--- /dev/null
@@ -0,0 +1,3 @@
+#![allow(unused_variables)]; //~ ERROR expected item, found `;`
+//~^ ERROR `main` function
+fn foo() {}
diff --git a/src/test/ui/parser/issue-49040.stderr b/src/test/ui/parser/issue-49040.stderr
new file mode 100644 (file)
index 0000000..56befe3
--- /dev/null
@@ -0,0 +1,15 @@
+error: expected item, found `;`
+  --> $DIR/issue-49040.rs:1:28
+   |
+LL | #![allow(unused_variables)];
+   |                            ^ help: remove this semicolon
+
+error[E0601]: `main` function not found in crate `issue_49040`
+  --> $DIR/issue-49040.rs:1:1
+   |
+LL | #![allow(unused_variables)];
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ consider adding a `main` function to `$DIR/issue-49040.rs`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/parser/issue-56031.rs b/src/test/ui/parser/issue-56031.rs
new file mode 100644 (file)
index 0000000..b68f568
--- /dev/null
@@ -0,0 +1,6 @@
+struct T;
+
+impl for T {}
+//~^ ERROR missing trait in a trait impl
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-56031.stderr b/src/test/ui/parser/issue-56031.stderr
new file mode 100644 (file)
index 0000000..7ee5bc6
--- /dev/null
@@ -0,0 +1,18 @@
+error: missing trait in a trait impl
+  --> $DIR/issue-56031.rs:3:5
+   |
+LL | impl for T {}
+   |     ^
+   |
+help: add a trait here
+   |
+LL | impl Trait for T {}
+   |      +++++
+help: for an inherent impl, drop this `for`
+   |
+LL - impl for T {}
+LL + impl T {}
+   | 
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/unicode-control-codepoints.rs b/src/test/ui/parser/unicode-control-codepoints.rs
new file mode 100644 (file)
index 0000000..5af0b58
--- /dev/null
@@ -0,0 +1,39 @@
+fn main() {
+    // if access_level != "us‫e‪r" { // Check if admin
+    //~^ ERROR unicode codepoint changing visible direction of text present in comment
+    println!("us\u{202B}e\u{202A}r");
+    println!("{:?}", r#"us\u{202B}e\u{202A}r"#);
+    println!("{:?}", b"us\u{202B}e\u{202A}r");
+    //~^ ERROR unicode escape in byte string
+    //~| ERROR unicode escape in byte string
+    println!("{:?}", br##"us\u{202B}e\u{202A}r"##);
+
+    println!("{:?}", "/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only ");
+    //~^ ERROR unicode codepoint changing visible direction of text present in literal
+
+    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
+    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
+    println!("{:?}", '‮');
+    //~^ ERROR unicode codepoint changing visible direction of text present in literal
+}
+
+//"/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only */"
+//~^ ERROR unicode codepoint changing visible direction of text present in comment
+
+/**  '‮'); */fn foo() {}
+//~^ ERROR unicode codepoint changing visible direction of text present in doc comment
+
+/**
+ *
+ *  '‮'); */fn bar() {}
+//~^^^ ERROR unicode codepoint changing visible direction of text present in doc comment
diff --git a/src/test/ui/parser/unicode-control-codepoints.stderr b/src/test/ui/parser/unicode-control-codepoints.stderr
new file mode 100644 (file)
index 0000000..71509fe
--- /dev/null
@@ -0,0 +1,192 @@
+error: unicode escape in byte string
+  --> $DIR/unicode-control-codepoints.rs:6:26
+   |
+LL |     println!("{:?}", b"us\u{202B}e\u{202A}r");
+   |                          ^^^^^^^^ unicode escape in byte string
+   |
+   = help: unicode escape sequences cannot be used as a byte or in a byte string
+
+error: unicode escape in byte string
+  --> $DIR/unicode-control-codepoints.rs:6:35
+   |
+LL |     println!("{:?}", b"us\u{202B}e\u{202A}r");
+   |                                   ^^^^^^^^ unicode escape in byte string
+   |
+   = help: unicode escape sequences cannot be used as a byte or in a byte string
+
+error: non-ASCII character in byte constant
+  --> $DIR/unicode-control-codepoints.rs:16:26
+   |
+LL |     println!("{:?}", b"/* } if isAdmin  begin admins only ");
+   |                          ^ byte constant 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
+  --> $DIR/unicode-control-codepoints.rs:16:30
+   |
+LL |     println!("{:?}", b"/* } if isAdmin  begin admins only ");
+   |                             ^ byte constant 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
+  --> $DIR/unicode-control-codepoints.rs:16:41
+   |
+LL |     println!("{:?}", b"/* } if isAdmin  begin admins only ");
+   |                                       ^ byte constant 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
+  --> $DIR/unicode-control-codepoints.rs:16:43
+   |
+LL |     println!("{:?}", b"/* } if isAdmin  begin admins only ");
+   |                                        ^ byte constant 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
+  --> $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
+  --> $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
+  --> $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
+  --> $DIR/unicode-control-codepoints.rs:21:46
+   |
+LL |     println!("{:?}", br##"/* } if isAdmin  begin admins only "##);
+   |                                           ^ must be ASCII but is '\u{2066}'
+
+error: unicode codepoint changing visible direction of text present in comment
+  --> $DIR/unicode-control-codepoints.rs:2:5
+   |
+LL |     // if access_level != "user" { // Check if admin
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^
+   |     |                        ||
+   |     |                        |'\u{202a}'
+   |     |                        '\u{202b}'
+   |     this comment contains invisible unicode text flow control codepoints
+   |
+   = note: `#[deny(text_direction_codepoint_in_comment)]` on by default
+   = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+   = help: if their presence wasn't intentional, you can remove them
+
+error: unicode codepoint changing visible direction of text present in comment
+  --> $DIR/unicode-control-codepoints.rs:30:1
+   |
+LL | //"/* } if isAdmin  begin admins only */"
+   | ^^^^^-^^-^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^
+   | |    |  |         ||
+   | |    |  |         |'\u{2066}'
+   | |    |  |         '\u{2069}'
+   | |    |  '\u{2066}'
+   | |    '\u{202e}'
+   | this comment contains invisible unicode text flow control codepoints
+   |
+   = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+   = help: if their presence wasn't intentional, you can remove them
+
+error: unicode codepoint changing visible direction of text present in literal
+  --> $DIR/unicode-control-codepoints.rs:11:22
+   |
+LL |     println!("{:?}", "/* } if isAdmin  begin admins only ");
+   |                      ^^^-^^-^^^^^^^^^--^^^^^^^^^^^^^^^^^^^
+   |                      |  |  |         ||
+   |                      |  |  |         |'\u{2066}'
+   |                      |  |  |         '\u{2069}'
+   |                      |  |  '\u{2066}'
+   |                      |  '\u{202e}'
+   |                      this literal contains invisible unicode text flow control codepoints
+   |
+   = note: `#[deny(text_direction_codepoint_in_literal)]` on by default
+   = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+   = help: if their presence wasn't intentional, you can remove them
+help: if you want to keep them but make them visible in your source code, you can escape them
+   |
+LL |     println!("{:?}", "/*\u{202e} } \u{2066}if isAdmin\u{2069} \u{2066} begin admins only ");
+   |                         ~~~~~~~~   ~~~~~~~~          ~~~~~~~~ ~~~~~~~~
+
+error: unicode codepoint changing visible direction of text present in literal
+  --> $DIR/unicode-control-codepoints.rs:14:22
+   |
+LL |     println!("{:?}", r##"/* } if isAdmin  begin admins only "##);
+   |                      ^^^^^^-^^-^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^
+   |                      |     |  |         ||
+   |                      |     |  |         |'\u{2066}'
+   |                      |     |  |         '\u{2069}'
+   |                      |     |  '\u{2066}'
+   |                      |     '\u{202e}'
+   |                      this literal contains invisible unicode text flow control codepoints
+   |
+   = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+   = help: if their presence wasn't intentional, you can remove them
+help: if you want to keep them but make them visible in your source code, you can escape them
+   |
+LL |     println!("{:?}", r##"/*\u{202e} } \u{2066}if isAdmin\u{2069} \u{2066} begin admins only "##);
+   |                            ~~~~~~~~   ~~~~~~~~          ~~~~~~~~ ~~~~~~~~
+
+error: unicode codepoint changing visible direction of text present in literal
+  --> $DIR/unicode-control-codepoints.rs:26:22
+   |
+LL |     println!("{:?}", '');
+   |                      ^-
+   |                      ||
+   |                      |'\u{202e}'
+   |                      this literal contains an invisible unicode text flow control codepoint
+   |
+   = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+   = help: if their presence wasn't intentional, you can remove them
+help: if you want to keep them but make them visible in your source code, you can escape them
+   |
+LL |     println!("{:?}", '\u{202e}');
+   |                       ~~~~~~~~
+
+error: unicode codepoint changing visible direction of text present in doc comment
+  --> $DIR/unicode-control-codepoints.rs:33:1
+   |
+LL | /**  ''); */fn foo() {}
+   | ^^^^^^^^^^^^ this doc comment contains an invisible unicode text flow control codepoint
+   |
+   = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+   = note: if their presence wasn't intentional, you can remove them
+   = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}'
+
+error: unicode codepoint changing visible direction of text present in doc comment
+  --> $DIR/unicode-control-codepoints.rs:36:1
+   |
+LL | / /**
+LL | |  *
+LL | |  *  ''); */fn bar() {}
+   | |___________^ this doc comment contains an invisible unicode text flow control codepoint
+   |
+   = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+   = note: if their presence wasn't intentional, you can remove them
+   = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}'
+
+error: aborting due to 17 previous errors
+
diff --git a/src/test/ui/pattern/issue-11577.rs b/src/test/ui/pattern/issue-11577.rs
new file mode 100644 (file)
index 0000000..70177c5
--- /dev/null
@@ -0,0 +1,18 @@
+// run-pass
+// Destructuring struct variants would ICE where regular structs wouldn't
+
+enum Foo {
+    VBar { num: isize }
+}
+
+struct SBar { num: isize }
+
+pub fn main() {
+    let vbar = Foo::VBar { num: 1 };
+    let Foo::VBar { num } = vbar;
+    assert_eq!(num, 1);
+
+    let sbar = SBar { num: 2 };
+    let SBar { num } = sbar;
+    assert_eq!(num, 2);
+}
diff --git a/src/test/ui/pattern/issue-15080.rs b/src/test/ui/pattern/issue-15080.rs
new file mode 100644 (file)
index 0000000..4dd6981
--- /dev/null
@@ -0,0 +1,22 @@
+// run-pass
+
+fn main() {
+    let mut x: &[_] = &[1, 2, 3, 4];
+
+    let mut result = vec![];
+    loop {
+        x = match *x {
+            [1, n, 3, ref rest @ ..] => {
+                result.push(n);
+                rest
+            }
+            [n, ref rest @ ..] => {
+                result.push(n);
+                rest
+            }
+            [] =>
+                break
+        }
+    }
+    assert_eq!(result, [2, 4]);
+}
diff --git a/src/test/ui/pattern/issue-72574-2.rs b/src/test/ui/pattern/issue-72574-2.rs
new file mode 100644 (file)
index 0000000..0ad2db8
--- /dev/null
@@ -0,0 +1,12 @@
+struct Binder(i32, i32, i32);
+
+fn main() {
+    let x = Binder(1, 2, 3);
+    match x {
+        Binder(_a, _x @ ..) => {}
+        _ => {}
+    }
+}
+//~^^^^ ERROR `_x @` is not allowed in a tuple struct
+//~| ERROR: `..` patterns are not allowed here
+//~| ERROR: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
diff --git a/src/test/ui/pattern/issue-72574-2.stderr b/src/test/ui/pattern/issue-72574-2.stderr
new file mode 100644 (file)
index 0000000..05650f0
--- /dev/null
@@ -0,0 +1,37 @@
+error: `_x @` is not allowed in a tuple struct
+  --> $DIR/issue-72574-2.rs:6:20
+   |
+LL |         Binder(_a, _x @ ..) => {}
+   |                    ^^^^^^^ this is only allowed in slice patterns
+   |
+   = help: remove this and bind each tuple field independently
+help: if you don't need to use the contents of _x, discard the tuple's remaining fields
+   |
+LL |         Binder(_a, ..) => {}
+   |                    ~~
+
+error: `..` patterns are not allowed here
+  --> $DIR/issue-72574-2.rs:6:25
+   |
+LL |         Binder(_a, _x @ ..) => {}
+   |                         ^^
+   |
+   = note: only allowed in tuple, tuple struct, and slice patterns
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
+  --> $DIR/issue-72574-2.rs:6:16
+   |
+LL | struct Binder(i32, i32, i32);
+   |               ---  ---  --- tuple struct has 3 fields
+...
+LL |         Binder(_a, _x @ ..) => {}
+   |                ^^  ^^^^^^^ expected 3 fields, found 2
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         Binder(_a, _x @ .., _) => {}
+   |                           +++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0023`.
diff --git a/src/test/ui/pattern/issue-8351-1.rs b/src/test/ui/pattern/issue-8351-1.rs
new file mode 100644 (file)
index 0000000..139f027
--- /dev/null
@@ -0,0 +1,16 @@
+// run-pass
+#![allow(dead_code)]
+
+enum E {
+    Foo{f: isize},
+    Bar,
+}
+
+pub fn main() {
+    let e = E::Foo{f: 0};
+    match e {
+        E::Foo{f: 1} => panic!(),
+        E::Foo{..} => (),
+        _ => panic!(),
+    }
+}
diff --git a/src/test/ui/pattern/issue-8351-2.rs b/src/test/ui/pattern/issue-8351-2.rs
new file mode 100644 (file)
index 0000000..bc66cbb
--- /dev/null
@@ -0,0 +1,16 @@
+// run-pass
+#![allow(dead_code)]
+
+enum E {
+    Foo{f: isize, b: bool},
+    Bar,
+}
+
+pub fn main() {
+    let e = E::Foo{f: 0, b: false};
+    match e {
+        E::Foo{f: 1, b: true} => panic!(),
+        E::Foo{b: false, f: 0} => (),
+        _ => panic!(),
+    }
+}
index f926eee9d92b282deddff6f52ff1437bc6edb05e..ec8666f93f096392d13343e876983af073e7bba8 100644 (file)
@@ -1,5 +1,6 @@
 // aux-crate:priv:priv_dep=priv_dep.rs
 // aux-build:pub_dep.rs
+// compile-flags: -Zunstable-options
 #![deny(exported_private_dependencies)]
 
 // This crate is a private dependency
index e6b4d33f10316e4ee36e8644e0de76f4f9a2a819..f64b8569015d8fc881c2c50dd5d44cdd20a21b04 100644 (file)
@@ -1,23 +1,23 @@
 error: type `OtherType` from private dependency 'priv_dep' in public interface
-  --> $DIR/pub-priv1.rs:20:5
+  --> $DIR/pub-priv1.rs:21:5
    |
 LL |     pub field: OtherType,
    |     ^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/pub-priv1.rs:3:9
+  --> $DIR/pub-priv1.rs:4:9
    |
 LL | #![deny(exported_private_dependencies)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: type `OtherType` from private dependency 'priv_dep' in public interface
-  --> $DIR/pub-priv1.rs:27:5
+  --> $DIR/pub-priv1.rs:28:5
    |
 LL |     pub fn pub_fn(param: OtherType) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
-  --> $DIR/pub-priv1.rs:34:5
+  --> $DIR/pub-priv1.rs:35:5
    |
 LL |     type Foo: OtherTrait;
    |     ^^^^^^^^^^^^^^^^^^^^^
index 93551ebaf82d598416d68dcc58bfea5953f904d2..6186b941ef69f6c6f5fee030212c203c3aa6ed8e 100644 (file)
@@ -1,3 +1,5 @@
+// ignore-tidy-linelength
+
 use proc_macro::Literal;
 
 pub fn test() {
@@ -8,6 +10,14 @@ pub fn test() {
 fn test_display_literal() {
     assert_eq!(Literal::isize_unsuffixed(-10).to_string(), "-10");
     assert_eq!(Literal::isize_suffixed(-10).to_string(), "-10isize");
+    assert_eq!(Literal::f32_unsuffixed(-10.0).to_string(), "-10.0");
+    assert_eq!(Literal::f32_suffixed(-10.0).to_string(), "-10f32");
+    assert_eq!(Literal::f64_unsuffixed(-10.0).to_string(), "-10.0");
+    assert_eq!(Literal::f64_suffixed(-10.0).to_string(), "-10f64");
+    assert_eq!(
+        Literal::f64_unsuffixed(1e100).to_string(),
+        "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0",
+    );
 }
 
 fn test_parse_literal() {
diff --git a/src/test/ui/process/issue-14456.rs b/src/test/ui/process/issue-14456.rs
new file mode 100644 (file)
index 0000000..52a56eb
--- /dev/null
@@ -0,0 +1,37 @@
+// run-pass
+#![allow(unused_mut)]
+// ignore-emscripten no processes
+// ignore-sgx no processes
+
+use std::env;
+use std::io::prelude::*;
+use std::io;
+use std::process::{Command, Stdio};
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() > 1 && args[1] == "child" {
+        return child()
+    }
+
+    test();
+}
+
+fn child() {
+    writeln!(&mut io::stdout(), "foo").unwrap();
+    writeln!(&mut io::stderr(), "bar").unwrap();
+    let mut stdin = io::stdin();
+    let mut s = String::new();
+    stdin.lock().read_line(&mut s).unwrap();
+    assert_eq!(s.len(), 0);
+}
+
+fn test() {
+    let args: Vec<String> = env::args().collect();
+    let mut p = Command::new(&args[0]).arg("child")
+                                     .stdin(Stdio::piped())
+                                     .stdout(Stdio::piped())
+                                     .stderr(Stdio::piped())
+                                     .spawn().unwrap();
+    assert!(p.wait().unwrap().success());
+}
diff --git a/src/test/ui/process/issue-16272.rs b/src/test/ui/process/issue-16272.rs
new file mode 100644 (file)
index 0000000..5cf3fd9
--- /dev/null
@@ -0,0 +1,23 @@
+// run-pass
+// ignore-emscripten no processes
+// ignore-sgx no processes
+
+use std::process::Command;
+use std::env;
+
+fn main() {
+    let len = env::args().len();
+
+    if len == 1 {
+        test();
+    } else {
+        assert_eq!(len, 3);
+    }
+}
+
+fn test() {
+    let status = Command::new(&env::current_exe().unwrap())
+                         .arg("foo").arg("")
+                         .status().unwrap();
+    assert!(status.success());
+}
diff --git a/src/test/ui/process/issue-20091.rs b/src/test/ui/process/issue-20091.rs
new file mode 100644 (file)
index 0000000..86cc79d
--- /dev/null
@@ -0,0 +1,24 @@
+// run-pass
+#![allow(stable_features)]
+
+// ignore-emscripten no processes
+// ignore-sgx no processes
+
+#![feature(os)]
+
+#[cfg(unix)]
+fn main() {
+    use std::process::Command;
+    use std::env;
+    use std::os::unix::prelude::*;
+    use std::ffi::OsStr;
+
+    if env::args().len() == 1 {
+        assert!(Command::new(&env::current_exe().unwrap())
+                        .arg(<OsStr as OsStrExt>::from_bytes(b"\xff"))
+                        .status().unwrap().success())
+    }
+}
+
+#[cfg(windows)]
+fn main() {}
diff --git a/src/test/ui/process/signal-exit-status.rs b/src/test/ui/process/signal-exit-status.rs
new file mode 100644 (file)
index 0000000..0963dcc
--- /dev/null
@@ -0,0 +1,18 @@
+// run-pass
+// ignore-emscripten no processes
+// ignore-sgx no processes
+// ignore-windows
+
+use std::env;
+use std::process::Command;
+
+pub fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() >= 2 && args[1] == "signal" {
+        // Raise a segfault.
+        unsafe { *(1 as *mut isize) = 0; }
+    } else {
+        let status = Command::new(&args[0]).arg("signal").status().unwrap();
+        assert!(status.code().is_none());
+    }
+}
diff --git a/src/test/ui/regions/issue-21520.rs b/src/test/ui/regions/issue-21520.rs
new file mode 100644 (file)
index 0000000..ab4ac72
--- /dev/null
@@ -0,0 +1,22 @@
+// check-pass
+#![allow(dead_code)]
+// Test that the requirement (in `Bar`) that `T::Bar : 'static` does
+// not wind up propagating to `T`.
+
+// pretty-expanded FIXME #23616
+
+pub trait Foo {
+    type Bar;
+
+    fn foo(&self) -> Self;
+}
+
+pub struct Static<T:'static>(T);
+
+struct Bar<T:Foo>
+    where T::Bar : 'static
+{
+    x: Static<Option<T::Bar>>
+}
+
+fn main() { }
diff --git a/src/test/ui/regions/issue-26448-1.rs b/src/test/ui/regions/issue-26448-1.rs
new file mode 100644 (file)
index 0000000..7d2d75b
--- /dev/null
@@ -0,0 +1,13 @@
+// run-pass
+
+pub trait Foo<T> {
+    fn foo(self) -> T;
+}
+
+impl<'a, T> Foo<T> for &'a str where &'a str: Into<T> {
+    fn foo(self) -> T {
+        panic!();
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/regions/issue-26448-2.rs b/src/test/ui/regions/issue-26448-2.rs
new file mode 100644 (file)
index 0000000..c60e06c
--- /dev/null
@@ -0,0 +1,21 @@
+// check-pass
+
+pub struct Bar<T> {
+    items: Vec<&'static str>,
+    inner: T,
+}
+
+pub trait IntoBar<T> {
+    fn into_bar(self) -> Bar<T>;
+}
+
+impl<'a, T> IntoBar<T> for &'a str where &'a str: Into<T> {
+    fn into_bar(self) -> Bar<T> {
+        Bar {
+            items: Vec::new(),
+            inner: self.into(),
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/regions/issue-26448-3.rs b/src/test/ui/regions/issue-26448-3.rs
new file mode 100644 (file)
index 0000000..d48022c
--- /dev/null
@@ -0,0 +1,25 @@
+// check-pass
+
+pub struct Item {
+    _inner: &'static str,
+}
+
+pub struct Bar<T> {
+    items: Vec<Item>,
+    inner: T,
+}
+
+pub trait IntoBar<T> {
+    fn into_bar(self) -> Bar<T>;
+}
+
+impl<'a, T> IntoBar<T> for &'a str where &'a str: Into<T> {
+    fn into_bar(self) -> Bar<T> {
+        Bar {
+            items: Vec::new(),
+            inner: self.into(),
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/required-lang-item.rs b/src/test/ui/required-lang-item.rs
deleted file mode 100644 (file)
index 3b17c5b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// build-fail
-
-#![feature(lang_items, no_core)]
-#![no_core]
-
-#[lang="copy"] pub trait Copy { }
-#[lang="sized"] pub trait Sized { }
-
-// error-pattern:requires `start` lang_item
-
-fn main() {}
diff --git a/src/test/ui/required-lang-item.stderr b/src/test/ui/required-lang-item.stderr
deleted file mode 100644 (file)
index 83764a9..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-error: requires `start` lang_item
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/resolve/editions-crate-root-2015.rs b/src/test/ui/resolve/editions-crate-root-2015.rs
new file mode 100644 (file)
index 0000000..4c890e3
--- /dev/null
@@ -0,0 +1,21 @@
+// edition:2015
+
+mod inner {
+    fn global_inner(_: ::nonexistant::Foo) {
+        //~^ ERROR failed to resolve: maybe a missing crate `nonexistant`?
+    }
+    fn crate_inner(_: crate::nonexistant::Foo) {
+        //~^ ERROR failed to resolve: maybe a missing crate `nonexistant`?
+    }
+
+    fn bare_global(_: ::nonexistant) {
+        //~^ ERROR cannot find type `nonexistant` in the crate root
+    }
+    fn bare_crate(_: crate::nonexistant) {
+        //~^ ERROR cannot find type `nonexistant` in the crate root
+    }
+}
+
+fn main() {
+
+}
diff --git a/src/test/ui/resolve/editions-crate-root-2015.stderr b/src/test/ui/resolve/editions-crate-root-2015.stderr
new file mode 100644 (file)
index 0000000..f8d65fe
--- /dev/null
@@ -0,0 +1,28 @@
+error[E0433]: failed to resolve: maybe a missing crate `nonexistant`?
+  --> $DIR/editions-crate-root-2015.rs:4:26
+   |
+LL |     fn global_inner(_: ::nonexistant::Foo) {
+   |                          ^^^^^^^^^^^ maybe a missing crate `nonexistant`?
+
+error[E0433]: failed to resolve: maybe a missing crate `nonexistant`?
+  --> $DIR/editions-crate-root-2015.rs:7:30
+   |
+LL |     fn crate_inner(_: crate::nonexistant::Foo) {
+   |                              ^^^^^^^^^^^ maybe a missing crate `nonexistant`?
+
+error[E0412]: cannot find type `nonexistant` in the crate root
+  --> $DIR/editions-crate-root-2015.rs:11:25
+   |
+LL |     fn bare_global(_: ::nonexistant) {
+   |                         ^^^^^^^^^^^ not found in the crate root
+
+error[E0412]: cannot find type `nonexistant` in the crate root
+  --> $DIR/editions-crate-root-2015.rs:14:29
+   |
+LL |     fn bare_crate(_: crate::nonexistant) {
+   |                             ^^^^^^^^^^^ not found in the crate root
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0412, E0433.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/resolve/issue-12796.rs b/src/test/ui/resolve/issue-12796.rs
new file mode 100644 (file)
index 0000000..942d6b9
--- /dev/null
@@ -0,0 +1,9 @@
+trait Trait {
+    fn outer(&self) {
+        fn inner(_: &Self) {
+            //~^ ERROR can't use generic parameters from outer function
+        }
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/resolve/issue-12796.stderr b/src/test/ui/resolve/issue-12796.stderr
new file mode 100644 (file)
index 0000000..a01fd2d
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/issue-12796.rs:3:22
+   |
+LL |         fn inner(_: &Self) {
+   |                      ^^^^
+   |                      |
+   |                      use of generic parameter from outer function
+   |                      can't use `Self` here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0401`.
diff --git a/src/test/ui/resolve/issue-23716.rs b/src/test/ui/resolve/issue-23716.rs
new file mode 100644 (file)
index 0000000..e9139c0
--- /dev/null
@@ -0,0 +1,17 @@
+static foo: i32 = 0;
+
+fn bar(foo: i32) {}
+//~^ ERROR function parameters cannot shadow statics
+//~| cannot be named the same as a static
+
+mod submod {
+    pub static answer: i32 = 42;
+}
+
+use self::submod::answer;
+
+fn question(answer: i32) {}
+//~^ ERROR function parameters cannot shadow statics
+//~| cannot be named the same as a static
+fn main() {
+}
diff --git a/src/test/ui/resolve/issue-23716.stderr b/src/test/ui/resolve/issue-23716.stderr
new file mode 100644 (file)
index 0000000..e7bebfb
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0530]: function parameters cannot shadow statics
+  --> $DIR/issue-23716.rs:3:8
+   |
+LL | static foo: i32 = 0;
+   | -------------------- the static `foo` is defined here
+LL | 
+LL | fn bar(foo: i32) {}
+   |        ^^^ cannot be named the same as a static
+
+error[E0530]: function parameters cannot shadow statics
+  --> $DIR/issue-23716.rs:13:13
+   |
+LL | use self::submod::answer;
+   |     -------------------- the static `answer` is imported here
+LL | 
+LL | fn question(answer: i32) {}
+   |             ^^^^^^ cannot be named the same as a static
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0530`.
diff --git a/src/test/ui/resolve/issue-3021-c.rs b/src/test/ui/resolve/issue-3021-c.rs
new file mode 100644 (file)
index 0000000..94ed1fd
--- /dev/null
@@ -0,0 +1,9 @@
+fn siphash<T>() {
+
+    trait U {
+        fn g(&self, x: T) -> T;  //~ ERROR can't use generic parameters from outer function
+        //~^ ERROR can't use generic parameters from outer function
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-3021-c.stderr b/src/test/ui/resolve/issue-3021-c.stderr
new file mode 100644 (file)
index 0000000..8764ac8
--- /dev/null
@@ -0,0 +1,25 @@
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/issue-3021-c.rs:4:24
+   |
+LL | fn siphash<T>() {
+   |            - type parameter from outer function
+...
+LL |         fn g(&self, x: T) -> T;
+   |            -           ^ use of generic parameter from outer function
+   |            |
+   |            help: try using a local generic parameter instead: `g<T>`
+
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/issue-3021-c.rs:4:30
+   |
+LL | fn siphash<T>() {
+   |            - type parameter from outer function
+...
+LL |         fn g(&self, x: T) -> T;
+   |            -                 ^ use of generic parameter from outer function
+   |            |
+   |            help: try using a local generic parameter instead: `g<T>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0401`.
diff --git a/src/test/ui/resolve/issue-3021.rs b/src/test/ui/resolve/issue-3021.rs
new file mode 100644 (file)
index 0000000..a672261
--- /dev/null
@@ -0,0 +1,18 @@
+trait SipHash {
+    fn reset(&self);
+}
+
+fn siphash(k0 : u64) {
+    struct SipState {
+        v0: u64,
+    }
+
+    impl SipHash for SipState {
+        fn reset(&self) {
+           self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
+        }
+    }
+    panic!();
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-3021.stderr b/src/test/ui/resolve/issue-3021.stderr
new file mode 100644 (file)
index 0000000..d5b015e
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0434]: can't capture dynamic environment in a fn item
+  --> $DIR/issue-3021.rs:12:22
+   |
+LL |            self.v0 = k0 ^ 0x736f6d6570736575;
+   |                      ^^
+   |
+   = help: use the `|| { ... }` closure form instead
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0434`.
diff --git a/src/test/ui/resolve/issue-31845.rs b/src/test/ui/resolve/issue-31845.rs
new file mode 100644 (file)
index 0000000..f6dc115
--- /dev/null
@@ -0,0 +1,12 @@
+// Checks lexical scopes cannot see through normal module boundaries
+
+fn f() {
+    fn g() {}
+    mod foo {
+        fn h() {
+           g(); //~ ERROR cannot find function `g` in this scope
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-31845.stderr b/src/test/ui/resolve/issue-31845.stderr
new file mode 100644 (file)
index 0000000..5628193
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0425]: cannot find function `g` in this scope
+  --> $DIR/issue-31845.rs:7:12
+   |
+LL |            g();
+   |            ^ 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/resolve/issue-5099.rs b/src/test/ui/resolve/issue-5099.rs
new file mode 100644 (file)
index 0000000..b5abccb
--- /dev/null
@@ -0,0 +1,13 @@
+trait B <A> {
+    fn a() -> A {
+        this.a //~ ERROR cannot find value `this` in this scope
+    }
+    fn b(x: i32) {
+        this.b(x); //~ ERROR cannot find value `this` in this scope
+    }
+    fn c() {
+        let _ = || this.a; //~ ERROR cannot find value `this` in this scope
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-5099.stderr b/src/test/ui/resolve/issue-5099.stderr
new file mode 100644 (file)
index 0000000..e9b2a9c
--- /dev/null
@@ -0,0 +1,48 @@
+error[E0425]: cannot find value `this` in this scope
+  --> $DIR/issue-5099.rs:3:9
+   |
+LL |         this.a
+   |         ^^^^ not found in this scope
+   |
+help: you might have meant to use `self` here instead
+   |
+LL |         self.a
+   |         ~~~~
+help: if you meant to use `self`, you are also missing a `self` receiver argument
+   |
+LL |     fn a(&self) -> A {
+   |          +++++
+
+error[E0425]: cannot find value `this` in this scope
+  --> $DIR/issue-5099.rs:6:9
+   |
+LL |         this.b(x);
+   |         ^^^^ not found in this scope
+   |
+help: you might have meant to use `self` here instead
+   |
+LL |         self.b(x);
+   |         ~~~~
+help: if you meant to use `self`, you are also missing a `self` receiver argument
+   |
+LL |     fn b(&self, x: i32) {
+   |          ++++++
+
+error[E0425]: cannot find value `this` in this scope
+  --> $DIR/issue-5099.rs:9:20
+   |
+LL |         let _ = || this.a;
+   |                    ^^^^ not found in this scope
+   |
+help: you might have meant to use `self` here instead
+   |
+LL |         let _ = || self.a;
+   |                    ~~~~
+help: if you meant to use `self`, you are also missing a `self` receiver argument
+   |
+LL |     fn c(&self) {
+   |          +++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.rs
new file mode 100644 (file)
index 0000000..0260caa
--- /dev/null
@@ -0,0 +1,21 @@
+// Matching against NaN should result in a warning
+
+#![allow(unused)]
+#![deny(illegal_floating_point_literal_pattern)]
+
+const NAN: f64 = f64::NAN;
+
+fn main() {
+    let x = NAN;
+    match x {
+        NAN => {}, //~ ERROR floating-point types cannot be used
+        //~| WARN this was previously accepted by the compiler but is being phased out
+        _ => {},
+    };
+
+    match [x, 1.0] {
+        [NAN, _] => {}, //~ ERROR floating-point types cannot be used
+        //~| WARN this was previously accepted by the compiler but is being phased out
+        _ => {},
+    };
+}
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr
new file mode 100644 (file)
index 0000000..4e2961e
--- /dev/null
@@ -0,0 +1,25 @@
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-6804.rs:11:9
+   |
+LL |         NAN => {},
+   |         ^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-6804.rs:4:9
+   |
+LL | #![deny(illegal_floating_point_literal_pattern)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-6804.rs:17:10
+   |
+LL |         [NAN, _] => {},
+   |          ^^^
+   |
+   = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: aborting due to 2 previous errors
+
index 3a9fd69322869518567d41a2e18f556ac1cdbc88..a63b6fcf2627ab8294f0a0e050b63a466c3bdf16 100644 (file)
@@ -1,6 +1,5 @@
 // check-pass
 // edition:2021
-// compile-flags: -Zunstable-options
 
 fn main() {
     let _: u16 = 123i32.try_into().unwrap();
index e026f01e93fb038027d0b773c7a4ff53f709e42e..eed2f313abe6ec70ced488c3246db67e05f4dab7 100644 (file)
@@ -1,6 +1,6 @@
 // check-pass
 // run-rustfix
-// compile-flags: -Z unstable-options --edition 2018
+// edition:2018
 
 #![warn(rust_2021_prefixes_incompatible_syntax)]
 
index d24f29634806d9d70cee029979f0a6258a7b8869..0565db793df66accbff7d51319f204b0fb307197 100644 (file)
@@ -1,6 +1,6 @@
 // check-pass
 // run-rustfix
-// compile-flags: -Z unstable-options --edition 2018
+// edition:2018
 
 #![warn(rust_2021_prefixes_incompatible_syntax)]
 
diff --git a/src/test/ui/self/issue-61882-2.rs b/src/test/ui/self/issue-61882-2.rs
new file mode 100644 (file)
index 0000000..1209b54
--- /dev/null
@@ -0,0 +1,11 @@
+struct A<T>(T);
+
+impl A<&'static u8> {
+    fn f() {
+        let x = 0;
+        Self(&x);
+        //~^ ERROR `x` does not live long enough
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/self/issue-61882-2.stderr b/src/test/ui/self/issue-61882-2.stderr
new file mode 100644 (file)
index 0000000..0b8e134
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0597]: `x` does not live long enough
+  --> $DIR/issue-61882-2.rs:6:14
+   |
+LL |         Self(&x);
+   |              ^^
+   |              |
+   |              borrowed value does not live long enough
+   |              this usage requires that `x` is borrowed for `'static`
+LL |
+LL |     }
+   |     - `x` 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/self/issue-61882.rs b/src/test/ui/self/issue-61882.rs
new file mode 100644 (file)
index 0000000..013398b
--- /dev/null
@@ -0,0 +1,9 @@
+struct A<T>(T);
+
+impl A<bool> {
+    const B: A<u8> = Self(0);
+    //~^ ERROR mismatched types
+    //~| ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/self/issue-61882.stderr b/src/test/ui/self/issue-61882.stderr
new file mode 100644 (file)
index 0000000..09ffe8e
--- /dev/null
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-61882.rs:4:27
+   |
+LL |     const B: A<u8> = Self(0);
+   |                           ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/issue-61882.rs:4:22
+   |
+LL |     const B: A<u8> = Self(0);
+   |                      ^^^^^^^ expected `u8`, found `bool`
+   |
+   = note: expected struct `A<u8>`
+              found struct `A<bool>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/signal-exit-status.rs b/src/test/ui/signal-exit-status.rs
deleted file mode 100644 (file)
index 0963dcc..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// run-pass
-// ignore-emscripten no processes
-// ignore-sgx no processes
-// ignore-windows
-
-use std::env;
-use std::process::Command;
-
-pub fn main() {
-    let args: Vec<String> = env::args().collect();
-    if args.len() >= 2 && args[1] == "signal" {
-        // Raise a segfault.
-        unsafe { *(1 as *mut isize) = 0; }
-    } else {
-        let status = Command::new(&args[0]).arg("signal").status().unwrap();
-        assert!(status.code().is_none());
-    }
-}
diff --git a/src/test/ui/specialization/transmute-specialization.rs b/src/test/ui/specialization/transmute-specialization.rs
new file mode 100644 (file)
index 0000000..499334d
--- /dev/null
@@ -0,0 +1,15 @@
+// run-pass
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Specializable { type Output; }
+
+impl<T> Specializable for T {
+    default type Output = u16;
+}
+
+fn main() {
+    unsafe {
+        std::mem::transmute::<u16, <() as Specializable>::Output>(0);
+    }
+}
diff --git a/src/test/ui/specialization/transmute-specialization.stderr b/src/test/ui/specialization/transmute-specialization.stderr
new file mode 100644 (file)
index 0000000..a0ea724
--- /dev/null
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/transmute-specialization.rs:3:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/static/auxiliary/nested_item.rs b/src/test/ui/static/auxiliary/nested_item.rs
new file mode 100644 (file)
index 0000000..9db9d19
--- /dev/null
@@ -0,0 +1,30 @@
+// original problem
+pub fn foo<T>() -> isize {
+    {
+        static foo: isize = 2;
+        foo
+    }
+}
+
+// issue 8134
+struct Foo;
+impl Foo {
+    pub fn foo<T>(&self) {
+        static X: usize = 1;
+    }
+}
+
+// issue 8134
+pub struct Parser<T>(T);
+impl<T: std::iter::Iterator<Item=char>> Parser<T> {
+    fn in_doctype(&mut self) {
+        static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E'];
+    }
+}
+
+struct Bar;
+impl Foo {
+    pub fn bar<T>(&self) {
+        static X: usize = 1;
+    }
+}
diff --git a/src/test/ui/static/nested_item_main.rs b/src/test/ui/static/nested_item_main.rs
new file mode 100644 (file)
index 0000000..2fe00ae
--- /dev/null
@@ -0,0 +1,10 @@
+// run-pass
+// aux-build:nested_item.rs
+
+
+extern crate nested_item;
+
+pub fn main() {
+    assert_eq!(2, nested_item::foo::<()>());
+    assert_eq!(2, nested_item::foo::<isize>());
+}
diff --git a/src/test/ui/statics/issue-14227.mir.stderr b/src/test/ui/statics/issue-14227.mir.stderr
new file mode 100644 (file)
index 0000000..8e7a251
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/issue-14227.rs:7:21
+   |
+LL | static CRASH: u32 = symbol;
+   |                     ^^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/statics/issue-14227.rs b/src/test/ui/statics/issue-14227.rs
new file mode 100644 (file)
index 0000000..5f866ec
--- /dev/null
@@ -0,0 +1,10 @@
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+extern "C" {
+    pub static symbol: u32;
+}
+static CRASH: u32 = symbol;
+//~^ ERROR use of extern static is unsafe and requires
+
+fn main() {}
diff --git a/src/test/ui/statics/issue-14227.thir.stderr b/src/test/ui/statics/issue-14227.thir.stderr
new file mode 100644 (file)
index 0000000..8e7a251
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/issue-14227.rs:7:21
+   |
+LL | static CRASH: u32 = symbol;
+   |                     ^^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/structs-enums/issue-50731.rs b/src/test/ui/structs-enums/issue-50731.rs
new file mode 100644 (file)
index 0000000..209c1e1
--- /dev/null
@@ -0,0 +1,6 @@
+// run-pass
+enum Void {}
+fn foo(_: Result<(Void, u32), (Void, String)>) {}
+fn main() {
+    let _: fn(_) = foo;
+}
diff --git a/src/test/ui/structured-compare.rs b/src/test/ui/structured-compare.rs
deleted file mode 100644 (file)
index 63d30c4..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// run-pass
-
-#![allow(non_camel_case_types)]
-
-
-#[derive(Copy, Clone, Debug)]
-enum foo { large, small, }
-
-impl PartialEq for foo {
-    fn eq(&self, other: &foo) -> bool {
-        ((*self) as usize) == ((*other) as usize)
-    }
-    fn ne(&self, other: &foo) -> bool { !(*self).eq(other) }
-}
-
-pub fn main() {
-    let a = (1, 2, 3);
-    let b = (1, 2, 3);
-    assert_eq!(a, b);
-    assert!((a != (1, 2, 4)));
-    assert!((a < (1, 2, 4)));
-    assert!((a <= (1, 2, 4)));
-    assert!(((1, 2, 4) > a));
-    assert!(((1, 2, 4) >= a));
-    let x = foo::large;
-    let y = foo::small;
-    assert!((x != y));
-    assert_eq!(x, foo::large);
-    assert!((x != foo::small));
-}
diff --git a/src/test/ui/suggestions/boxed-variant-field.rs b/src/test/ui/suggestions/boxed-variant-field.rs
new file mode 100644 (file)
index 0000000..d8f7fac
--- /dev/null
@@ -0,0 +1,16 @@
+enum Ty {
+    Unit,
+    List(Box<Ty>),
+}
+
+fn foo(x: Ty) -> Ty {
+    match x {
+        Ty::Unit => Ty::Unit,
+        Ty::List(elem) => foo(elem),
+        //~^ ERROR mismatched types
+        //~| HELP try dereferencing the `Box`
+        //~| HELP try using a variant of the expected enum
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/boxed-variant-field.stderr b/src/test/ui/suggestions/boxed-variant-field.stderr
new file mode 100644 (file)
index 0000000..d4ccb2c
--- /dev/null
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+  --> $DIR/boxed-variant-field.rs:9:31
+   |
+LL |         Ty::List(elem) => foo(elem),
+   |                               ^^^^ expected enum `Ty`, found struct `Box`
+   |
+   = note: expected enum `Ty`
+            found struct `Box<Ty>`
+help: try dereferencing the `Box`
+   |
+LL |         Ty::List(elem) => foo(*elem),
+   |                               +
+help: try using a variant of the expected enum
+   |
+LL |         Ty::List(elem) => foo(Ty::List(elem)),
+   |                               ~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/undeclared-module-alloc.rs b/src/test/ui/suggestions/undeclared-module-alloc.rs
new file mode 100644 (file)
index 0000000..1defa1c
--- /dev/null
@@ -0,0 +1,5 @@
+// edition:2018
+
+use alloc::rc::Rc; //~ ERROR failed to resolve: use of undeclared crate or module `alloc`
+
+fn main() {}
diff --git a/src/test/ui/suggestions/undeclared-module-alloc.stderr b/src/test/ui/suggestions/undeclared-module-alloc.stderr
new file mode 100644 (file)
index 0000000..39169df
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `alloc`
+  --> $DIR/undeclared-module-alloc.rs:3:5
+   |
+LL | use alloc::rc::Rc;
+   |     ^^^^^ use of undeclared crate or module `alloc`
+   |
+   = help: add `extern crate alloc` to use the `alloc` crate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/supported-cast.rs b/src/test/ui/supported-cast.rs
deleted file mode 100644 (file)
index ff41ce6..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-// run-pass
-
-pub fn main() {
-  let f = 1_usize as *const String;
-  println!("{:?}", f as isize);
-  println!("{:?}", f as usize);
-  println!("{:?}", f as i8);
-  println!("{:?}", f as i16);
-  println!("{:?}", f as i32);
-  println!("{:?}", f as i64);
-  println!("{:?}", f as u8);
-  println!("{:?}", f as u16);
-  println!("{:?}", f as u32);
-  println!("{:?}", f as u64);
-
-  println!("{:?}", 1 as isize);
-  println!("{:?}", 1 as usize);
-  println!("{:?}", 1 as *const String);
-  println!("{:?}", 1 as i8);
-  println!("{:?}", 1 as i16);
-  println!("{:?}", 1 as i32);
-  println!("{:?}", 1 as i64);
-  println!("{:?}", 1 as u8);
-  println!("{:?}", 1 as u16);
-  println!("{:?}", 1 as u32);
-  println!("{:?}", 1 as u64);
-  println!("{:?}", 1 as f32);
-  println!("{:?}", 1 as f64);
-
-  println!("{:?}", 1_usize as isize);
-  println!("{:?}", 1_usize as usize);
-  println!("{:?}", 1_usize as *const String);
-  println!("{:?}", 1_usize as i8);
-  println!("{:?}", 1_usize as i16);
-  println!("{:?}", 1_usize as i32);
-  println!("{:?}", 1_usize as i64);
-  println!("{:?}", 1_usize as u8);
-  println!("{:?}", 1_usize as u16);
-  println!("{:?}", 1_usize as u32);
-  println!("{:?}", 1_usize as u64);
-  println!("{:?}", 1_usize as f32);
-  println!("{:?}", 1_usize as f64);
-
-  println!("{:?}", 1i8 as isize);
-  println!("{:?}", 1i8 as usize);
-  println!("{:?}", 1i8 as *const String);
-  println!("{:?}", 1i8 as i8);
-  println!("{:?}", 1i8 as i16);
-  println!("{:?}", 1i8 as i32);
-  println!("{:?}", 1i8 as i64);
-  println!("{:?}", 1i8 as u8);
-  println!("{:?}", 1i8 as u16);
-  println!("{:?}", 1i8 as u32);
-  println!("{:?}", 1i8 as u64);
-  println!("{:?}", 1i8 as f32);
-  println!("{:?}", 1i8 as f64);
-
-  println!("{:?}", 1u8 as isize);
-  println!("{:?}", 1u8 as usize);
-  println!("{:?}", 1u8 as *const String);
-  println!("{:?}", 1u8 as i8);
-  println!("{:?}", 1u8 as i16);
-  println!("{:?}", 1u8 as i32);
-  println!("{:?}", 1u8 as i64);
-  println!("{:?}", 1u8 as u8);
-  println!("{:?}", 1u8 as u16);
-  println!("{:?}", 1u8 as u32);
-  println!("{:?}", 1u8 as u64);
-  println!("{:?}", 1u8 as f32);
-  println!("{:?}", 1u8 as f64);
-
-  println!("{:?}", 1i16 as isize);
-  println!("{:?}", 1i16 as usize);
-  println!("{:?}", 1i16 as *const String);
-  println!("{:?}", 1i16 as i8);
-  println!("{:?}", 1i16 as i16);
-  println!("{:?}", 1i16 as i32);
-  println!("{:?}", 1i16 as i64);
-  println!("{:?}", 1i16 as u8);
-  println!("{:?}", 1i16 as u16);
-  println!("{:?}", 1i16 as u32);
-  println!("{:?}", 1i16 as u64);
-  println!("{:?}", 1i16 as f32);
-  println!("{:?}", 1i16 as f64);
-
-  println!("{:?}", 1u16 as isize);
-  println!("{:?}", 1u16 as usize);
-  println!("{:?}", 1u16 as *const String);
-  println!("{:?}", 1u16 as i8);
-  println!("{:?}", 1u16 as i16);
-  println!("{:?}", 1u16 as i32);
-  println!("{:?}", 1u16 as i64);
-  println!("{:?}", 1u16 as u8);
-  println!("{:?}", 1u16 as u16);
-  println!("{:?}", 1u16 as u32);
-  println!("{:?}", 1u16 as u64);
-  println!("{:?}", 1u16 as f32);
-  println!("{:?}", 1u16 as f64);
-
-  println!("{:?}", 1i32 as isize);
-  println!("{:?}", 1i32 as usize);
-  println!("{:?}", 1i32 as *const String);
-  println!("{:?}", 1i32 as i8);
-  println!("{:?}", 1i32 as i16);
-  println!("{:?}", 1i32 as i32);
-  println!("{:?}", 1i32 as i64);
-  println!("{:?}", 1i32 as u8);
-  println!("{:?}", 1i32 as u16);
-  println!("{:?}", 1i32 as u32);
-  println!("{:?}", 1i32 as u64);
-  println!("{:?}", 1i32 as f32);
-  println!("{:?}", 1i32 as f64);
-
-  println!("{:?}", 1u32 as isize);
-  println!("{:?}", 1u32 as usize);
-  println!("{:?}", 1u32 as *const String);
-  println!("{:?}", 1u32 as i8);
-  println!("{:?}", 1u32 as i16);
-  println!("{:?}", 1u32 as i32);
-  println!("{:?}", 1u32 as i64);
-  println!("{:?}", 1u32 as u8);
-  println!("{:?}", 1u32 as u16);
-  println!("{:?}", 1u32 as u32);
-  println!("{:?}", 1u32 as u64);
-  println!("{:?}", 1u32 as f32);
-  println!("{:?}", 1u32 as f64);
-
-  println!("{:?}", 1i64 as isize);
-  println!("{:?}", 1i64 as usize);
-  println!("{:?}", 1i64 as *const String);
-  println!("{:?}", 1i64 as i8);
-  println!("{:?}", 1i64 as i16);
-  println!("{:?}", 1i64 as i32);
-  println!("{:?}", 1i64 as i64);
-  println!("{:?}", 1i64 as u8);
-  println!("{:?}", 1i64 as u16);
-  println!("{:?}", 1i64 as u32);
-  println!("{:?}", 1i64 as u64);
-  println!("{:?}", 1i64 as f32);
-  println!("{:?}", 1i64 as f64);
-
-  println!("{:?}", 1u64 as isize);
-  println!("{:?}", 1u64 as usize);
-  println!("{:?}", 1u64 as *const String);
-  println!("{:?}", 1u64 as i8);
-  println!("{:?}", 1u64 as i16);
-  println!("{:?}", 1u64 as i32);
-  println!("{:?}", 1u64 as i64);
-  println!("{:?}", 1u64 as u8);
-  println!("{:?}", 1u64 as u16);
-  println!("{:?}", 1u64 as u32);
-  println!("{:?}", 1u64 as u64);
-  println!("{:?}", 1u64 as f32);
-  println!("{:?}", 1u64 as f64);
-
-  println!("{:?}", 1u64 as isize);
-  println!("{:?}", 1u64 as usize);
-  println!("{:?}", 1u64 as *const String);
-  println!("{:?}", 1u64 as i8);
-  println!("{:?}", 1u64 as i16);
-  println!("{:?}", 1u64 as i32);
-  println!("{:?}", 1u64 as i64);
-  println!("{:?}", 1u64 as u8);
-  println!("{:?}", 1u64 as u16);
-  println!("{:?}", 1u64 as u32);
-  println!("{:?}", 1u64 as u64);
-  println!("{:?}", 1u64 as f32);
-  println!("{:?}", 1u64 as f64);
-
-  println!("{:?}", true as isize);
-  println!("{:?}", true as usize);
-  println!("{:?}", true as i8);
-  println!("{:?}", true as i16);
-  println!("{:?}", true as i32);
-  println!("{:?}", true as i64);
-  println!("{:?}", true as u8);
-  println!("{:?}", true as u16);
-  println!("{:?}", true as u32);
-  println!("{:?}", true as u64);
-
-  println!("{:?}", 1f32 as isize);
-  println!("{:?}", 1f32 as usize);
-  println!("{:?}", 1f32 as i8);
-  println!("{:?}", 1f32 as i16);
-  println!("{:?}", 1f32 as i32);
-  println!("{:?}", 1f32 as i64);
-  println!("{:?}", 1f32 as u8);
-  println!("{:?}", 1f32 as u16);
-  println!("{:?}", 1f32 as u32);
-  println!("{:?}", 1f32 as u64);
-  println!("{:?}", 1f32 as f32);
-  println!("{:?}", 1f32 as f64);
-
-  println!("{:?}", 1f64 as isize);
-  println!("{:?}", 1f64 as usize);
-  println!("{:?}", 1f64 as i8);
-  println!("{:?}", 1f64 as i16);
-  println!("{:?}", 1f64 as i32);
-  println!("{:?}", 1f64 as i64);
-  println!("{:?}", 1f64 as u8);
-  println!("{:?}", 1f64 as u16);
-  println!("{:?}", 1f64 as u32);
-  println!("{:?}", 1f64 as u64);
-  println!("{:?}", 1f64 as f32);
-  println!("{:?}", 1f64 as f64);
-}
diff --git a/src/test/ui/svh/auxiliary/changing-crates-a1.rs b/src/test/ui/svh/auxiliary/changing-crates-a1.rs
new file mode 100644 (file)
index 0000000..bc0559b
--- /dev/null
@@ -0,0 +1,3 @@
+#![crate_name = "a"]
+
+pub fn foo<T>() {}
diff --git a/src/test/ui/svh/auxiliary/changing-crates-a2.rs b/src/test/ui/svh/auxiliary/changing-crates-a2.rs
new file mode 100644 (file)
index 0000000..fafc6d5
--- /dev/null
@@ -0,0 +1,3 @@
+#![crate_name = "a"]
+
+pub fn foo<T>() { println!("hello!"); }
diff --git a/src/test/ui/svh/auxiliary/changing-crates-b.rs b/src/test/ui/svh/auxiliary/changing-crates-b.rs
new file mode 100644 (file)
index 0000000..f9ce29e
--- /dev/null
@@ -0,0 +1,5 @@
+#![crate_name = "b"]
+
+extern crate a;
+
+pub fn foo() { a::foo::<isize>(); }
diff --git a/src/test/ui/svh/changing-crates.rs b/src/test/ui/svh/changing-crates.rs
new file mode 100644 (file)
index 0000000..60c043b
--- /dev/null
@@ -0,0 +1,12 @@
+// ignore-msvc FIXME #31306
+
+// note that these aux-build directives must be in this order
+// aux-build:changing-crates-a1.rs
+// aux-build:changing-crates-b.rs
+// aux-build:changing-crates-a2.rs
+// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2"
+
+extern crate a;
+extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
+
+fn main() {}
diff --git a/src/test/ui/svh/changing-crates.stderr b/src/test/ui/svh/changing-crates.stderr
new file mode 100644 (file)
index 0000000..cc62a4d
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0460]: found possibly newer version of crate `a` which `b` depends on
+  --> $DIR/changing-crates.rs:10:1
+   |
+LL | extern crate b;
+   | ^^^^^^^^^^^^^^^
+   |
+   = note: perhaps that crate needs to be recompiled?
+   = note: the following crate versions were found:
+           crate `a`: $PATH_a
+           crate `b`: $PATH_b
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/syntax-trait-polarity.rs b/src/test/ui/syntax-trait-polarity.rs
deleted file mode 100644 (file)
index ed29474..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#![feature(negative_impls)]
-
-use std::marker::Send;
-
-struct TestType;
-
-impl !TestType {}
-//~^ ERROR inherent impls cannot be negative
-
-trait TestTrait {}
-
-unsafe impl !Send for TestType {}
-//~^ ERROR negative impls cannot be unsafe
-impl !TestTrait for TestType {}
-
-struct TestType2<T>(T);
-
-impl<T> !TestType2<T> {}
-//~^ ERROR inherent impls cannot be negative
-
-unsafe impl<T> !Send for TestType2<T> {}
-//~^ ERROR negative impls cannot be unsafe
-impl<T> !TestTrait for TestType2<T> {}
-
-fn main() {}
diff --git a/src/test/ui/syntax-trait-polarity.stderr b/src/test/ui/syntax-trait-polarity.stderr
deleted file mode 100644 (file)
index 1fd40fb..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-error: inherent impls cannot be negative
-  --> $DIR/syntax-trait-polarity.rs:7:7
-   |
-LL | impl !TestType {}
-   |      -^^^^^^^^ inherent impl for this type
-   |      |
-   |      negative because of this
-
-error[E0198]: negative impls cannot be unsafe
-  --> $DIR/syntax-trait-polarity.rs:12:13
-   |
-LL | unsafe impl !Send for TestType {}
-   | ------      -^^^^
-   | |           |
-   | |           negative because of this
-   | unsafe because of this
-
-error: inherent impls cannot be negative
-  --> $DIR/syntax-trait-polarity.rs:18:10
-   |
-LL | impl<T> !TestType2<T> {}
-   |         -^^^^^^^^^^^^ inherent impl for this type
-   |         |
-   |         negative because of this
-
-error[E0198]: negative impls cannot be unsafe
-  --> $DIR/syntax-trait-polarity.rs:21:16
-   |
-LL | unsafe impl<T> !Send for TestType2<T> {}
-   | ------         -^^^^
-   | |              |
-   | |              negative because of this
-   | unsafe because of this
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0198`.
diff --git a/src/test/ui/terminate-in-initializer.rs b/src/test/ui/terminate-in-initializer.rs
deleted file mode 100644 (file)
index c9cb932..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// run-pass
-// ignore-emscripten no threads support
-
-// Issue #787
-// Don't try to clean up uninitialized locals
-
-
-use std::thread;
-
-fn test_break() { loop { let _x: Box<isize> = break; } }
-
-fn test_cont() { let mut i = 0; while i < 1 { i += 1; let _x: Box<isize> = continue; } }
-
-fn test_ret() { let _x: Box<isize> = return; }
-
-fn test_panic() {
-    fn f() { let _x: Box<isize> = panic!(); }
-    thread::spawn(move|| f() ).join().unwrap_err();
-}
-
-fn test_panic_indirect() {
-    fn f() -> ! { panic!(); }
-    fn g() { let _x: Box<isize> = f(); }
-    thread::spawn(move|| g() ).join().unwrap_err();
-}
-
-pub fn main() {
-    test_break();
-    test_cont();
-    test_ret();
-    test_panic();
-    test_panic_indirect();
-}
index 869b372965966ffaebb6b17d83db3dbed5cb2e13..65d90678040d5ff094278cde42b3bb483ad2d067 100644 (file)
@@ -6,6 +6,10 @@ LL |     want_foo(b);
    |
    = note: expected struct `Foo`
               found struct `Box<Foo>`
+help: try dereferencing the `Box`
+   |
+LL |     want_foo(*b);
+   |              +
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/test-attrs/issue-20823.rs b/src/test/ui/test-attrs/issue-20823.rs
new file mode 100644 (file)
index 0000000..9e209d5
--- /dev/null
@@ -0,0 +1,5 @@
+// run-pass
+// compile-flags: --test
+
+#[test]
+pub fn foo() {}
diff --git a/src/test/ui/thin-lto-global-allocator.rs b/src/test/ui/thin-lto-global-allocator.rs
deleted file mode 100644 (file)
index e00c5ca..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// run-pass
-// compile-flags: -Z thinlto -C codegen-units=2
-
-#[global_allocator]
-static A: std::alloc::System = std::alloc::System;
-
-fn main() {}
diff --git a/src/test/ui/thinlto/all-crates.rs b/src/test/ui/thinlto/all-crates.rs
deleted file mode 100644 (file)
index e910b2a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-pass
-
-// compile-flags: -Clto=thin
-// no-prefer-dynamic
-
-fn main() {
-    println!("hello!");
-}
diff --git a/src/test/ui/thinlto/auxiliary/dylib.rs b/src/test/ui/thinlto/auxiliary/dylib.rs
deleted file mode 100644 (file)
index e8b7f8f..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// compile-flags: -Z thinlto -C codegen-units=8
-
-#[inline]
-pub fn foo(b: u8) {
-    b.to_string();
-}
diff --git a/src/test/ui/thinlto/auxiliary/msvc-imp-present.rs b/src/test/ui/thinlto/auxiliary/msvc-imp-present.rs
deleted file mode 100644 (file)
index 933af05..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// no-prefer-dynamic
-// compile-flags: -Z thinlto -C codegen-units=8 -C prefer-dynamic
-
-#![crate_type = "rlib"]
-#![crate_type = "dylib"]
-
-pub static A: u32 = 43;
-
-pub mod a {
-    pub static A: u32 = 43;
-}
diff --git a/src/test/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs b/src/test/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs
deleted file mode 100644 (file)
index 5fd3f19..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-
-pub fn bar() -> u32 {
-    3
-}
diff --git a/src/test/ui/thinlto/dylib-works.rs b/src/test/ui/thinlto/dylib-works.rs
deleted file mode 100644 (file)
index 9e0782b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// run-pass
-
-// aux-build:dylib.rs
-
-extern crate dylib;
-
-fn main() {
-    dylib::foo(1);
-}
diff --git a/src/test/ui/thinlto/msvc-imp-present.rs b/src/test/ui/thinlto/msvc-imp-present.rs
deleted file mode 100644 (file)
index 5498afb..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// run-pass
-
-// aux-build:msvc-imp-present.rs
-// compile-flags: -Z thinlto -C codegen-units=8
-// no-prefer-dynamic
-
-// On MSVC we have a "hack" where we emit symbols that look like `_imp_$name`
-// for all exported statics. This is done because we apply `dllimport` to all
-// imported constants and this allows everything to actually link correctly.
-//
-// The ThinLTO passes aggressively remove symbols if they can, and this test
-// asserts that the ThinLTO passes don't remove these compiler-generated
-// `_imp_*` symbols. The external library that we link in here is compiled with
-// ThinLTO and multiple codegen units and has a few exported constants. Note
-// that we also namely compile the library as both a dylib and an rlib, but we
-// link the rlib to ensure that we assert those generated symbols exist.
-
-extern crate msvc_imp_present as bar;
-
-fn main() {
-    println!("{}", bar::A);
-}
diff --git a/src/test/ui/thinlto/thin-lto-inlines.rs b/src/test/ui/thinlto/thin-lto-inlines.rs
deleted file mode 100644 (file)
index dca7918..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// run-pass
-
-// compile-flags: -Z thinlto -C codegen-units=8 -O
-// ignore-emscripten can't inspect instructions on emscripten
-
-// We want to assert here that ThinLTO will inline across codegen units. There's
-// not really a great way to do that in general so we sort of hack around it by
-// praying two functions go into separate codegen units and then assuming that
-// if inlining *doesn't* happen the first byte of the functions will differ.
-
-pub fn foo() -> u32 {
-    bar::bar()
-}
-
-mod bar {
-    pub fn bar() -> u32 {
-        3
-    }
-}
-
-fn main() {
-    println!("{} {}", foo(), bar::bar());
-
-    unsafe {
-        let foo = foo as usize as *const u8;
-        let bar = bar::bar as usize as *const u8;
-
-        assert_eq!(*foo, *bar);
-    }
-}
diff --git a/src/test/ui/thinlto/thin-lto-inlines2.rs b/src/test/ui/thinlto/thin-lto-inlines2.rs
deleted file mode 100644 (file)
index 1eb2965..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// run-pass
-
-// compile-flags: -C codegen-units=8 -O -C lto=thin
-// aux-build:thin-lto-inlines-aux.rs
-// no-prefer-dynamic
-// ignore-emscripten can't inspect instructions on emscripten
-
-// We want to assert here that ThinLTO will inline across codegen units. There's
-// not really a great way to do that in general so we sort of hack around it by
-// praying two functions go into separate codegen units and then assuming that
-// if inlining *doesn't* happen the first byte of the functions will differ.
-
-extern crate thin_lto_inlines_aux as bar;
-
-pub fn foo() -> u32 {
-    bar::bar()
-}
-
-fn main() {
-    println!("{} {}", foo(), bar::bar());
-
-    unsafe {
-        let foo = foo as usize as *const u8;
-        let bar = bar::bar as usize as *const u8;
-
-        assert_eq!(*foo, *bar);
-    }
-}
diff --git a/src/test/ui/thinlto/weak-works.rs b/src/test/ui/thinlto/weak-works.rs
deleted file mode 100644 (file)
index 163a387..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// run-pass
-
-// compile-flags: -C codegen-units=8 -Z thinlto
-// ignore-windows
-
-#![feature(linkage)]
-
-pub mod foo {
-    #[linkage = "weak"]
-    #[no_mangle]
-    pub extern "C" fn FOO() -> i32 {
-        0
-    }
-}
-
-mod bar {
-    extern "C" {
-        fn FOO() -> i32;
-    }
-
-    pub fn bar() -> i32 {
-        unsafe { FOO() }
-    }
-}
-
-fn main() {
-    bar::bar();
-}
diff --git a/src/test/ui/threads-sendsync/issue-24313.rs b/src/test/ui/threads-sendsync/issue-24313.rs
new file mode 100644 (file)
index 0000000..c28b4ca
--- /dev/null
@@ -0,0 +1,32 @@
+// run-pass
+// ignore-emscripten no threads
+// ignore-sgx no processes
+
+use std::thread;
+use std::env;
+use std::process::Command;
+
+struct Handle(i32);
+
+impl Drop for Handle {
+    fn drop(&mut self) { panic!(); }
+}
+
+thread_local!(static HANDLE: Handle = Handle(0));
+
+fn main() {
+    let args = env::args().collect::<Vec<_>>();
+    if args.len() == 1 {
+        let out = Command::new(&args[0]).arg("test").output().unwrap();
+        let stderr = std::str::from_utf8(&out.stderr).unwrap();
+        assert!(stderr.contains("panicked at 'explicit panic'"),
+                "bad failure message:\n{}\n", stderr);
+    } else {
+        // TLS dtors are not always run on process exit
+        thread::spawn(|| {
+            HANDLE.with(|h| {
+                println!("{}", h.0);
+            });
+        }).join().unwrap();
+    }
+}
diff --git a/src/test/ui/threads-sendsync/issue-4448.rs b/src/test/ui/threads-sendsync/issue-4448.rs
new file mode 100644 (file)
index 0000000..27d0326
--- /dev/null
@@ -0,0 +1,16 @@
+// run-pass
+// ignore-emscripten no threads support
+
+use std::sync::mpsc::channel;
+use std::thread;
+
+pub fn main() {
+    let (tx, rx) = channel::<&'static str>();
+
+    let t = thread::spawn(move|| {
+        assert_eq!(rx.recv().unwrap(), "hello, world");
+    });
+
+    tx.send("hello, world").unwrap();
+    t.join().ok().unwrap();
+}
diff --git a/src/test/ui/threads-sendsync/issue-8827.rs b/src/test/ui/threads-sendsync/issue-8827.rs
new file mode 100644 (file)
index 0000000..95be761
--- /dev/null
@@ -0,0 +1,53 @@
+// run-pass
+// ignore-emscripten no threads support
+
+use std::thread;
+use std::sync::mpsc::{channel, Receiver};
+
+fn periodical(n: isize) -> Receiver<bool> {
+    let (chan, port) = channel();
+    thread::spawn(move|| {
+        loop {
+            for _ in 1..n {
+                match chan.send(false) {
+                    Ok(()) => {}
+                    Err(..) => break,
+                }
+            }
+            match chan.send(true) {
+                Ok(()) => {}
+                Err(..) => break
+            }
+        }
+    });
+    return port;
+}
+
+fn integers() -> Receiver<isize> {
+    let (chan, port) = channel();
+    thread::spawn(move|| {
+        let mut i = 1;
+        loop {
+            match chan.send(i) {
+                Ok(()) => {}
+                Err(..) => break,
+            }
+            i = i + 1;
+        }
+    });
+    return port;
+}
+
+fn main() {
+    let ints = integers();
+    let threes = periodical(3);
+    let fives = periodical(5);
+    for _ in 1..100 {
+        match (ints.recv().unwrap(), threes.recv().unwrap(), fives.recv().unwrap()) {
+            (_, true, true) => println!("FizzBuzz"),
+            (_, true, false) => println!("Fizz"),
+            (_, false, true) => println!("Buzz"),
+            (i, false, false) => println!("{}", i)
+        }
+    }
+}
diff --git a/src/test/ui/threads-sendsync/issue-9396.rs b/src/test/ui/threads-sendsync/issue-9396.rs
new file mode 100644 (file)
index 0000000..3e7e9a5
--- /dev/null
@@ -0,0 +1,23 @@
+// run-pass
+#![allow(unused_must_use)]
+#![allow(deprecated)]
+// ignore-emscripten no threads support
+
+use std::sync::mpsc::{TryRecvError, channel};
+use std::thread;
+
+pub fn main() {
+    let (tx, rx) = channel();
+    let t = thread::spawn(move||{
+        thread::sleep_ms(10);
+        tx.send(()).unwrap();
+    });
+    loop {
+        match rx.try_recv() {
+            Ok(()) => break,
+            Err(TryRecvError::Empty) => {}
+            Err(TryRecvError::Disconnected) => unreachable!()
+        }
+    }
+    t.join();
+}
diff --git a/src/test/ui/threads-sendsync/trivial-message.rs b/src/test/ui/threads-sendsync/trivial-message.rs
new file mode 100644 (file)
index 0000000..5831e86
--- /dev/null
@@ -0,0 +1,16 @@
+// run-pass
+
+#![allow(unused_must_use)]
+/*
+  This is about the simplest program that can successfully send a
+  message.
+ */
+
+use std::sync::mpsc::channel;
+
+pub fn main() {
+    let (tx, rx) = channel();
+    tx.send(42);
+    let r = rx.recv();
+    println!("{:?}", r);
+}
diff --git a/src/test/ui/threads-sendsync/yield2.rs b/src/test/ui/threads-sendsync/yield2.rs
new file mode 100644 (file)
index 0000000..376faab
--- /dev/null
@@ -0,0 +1,8 @@
+// run-pass
+
+use std::thread;
+
+pub fn main() {
+    let mut i: isize = 0;
+    while i < 100 { i = i + 1; println!("{}", i); thread::yield_now(); }
+}
diff --git a/src/test/ui/trace_macros-format.rs b/src/test/ui/trace_macros-format.rs
deleted file mode 100644 (file)
index afca45c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#![feature(trace_macros)]
-
-fn main() {
-    trace_macros!(); //~ ERROR trace_macros! accepts only `true` or `false`
-    trace_macros!(1); //~ ERROR trace_macros! accepts only `true` or `false`
-    trace_macros!(ident); //~ ERROR trace_macros! accepts only `true` or `false`
-    trace_macros!(for); //~ ERROR trace_macros! accepts only `true` or `false`
-    trace_macros!(true,); //~ ERROR trace_macros! accepts only `true` or `false`
-    trace_macros!(false 1); //~ ERROR trace_macros! accepts only `true` or `false`
-
-
-    // should be fine:
-    macro_rules! expando {
-        ($x: ident) => { trace_macros!($x) }
-    }
-
-    expando!(true);
-}
diff --git a/src/test/ui/trace_macros-format.stderr b/src/test/ui/trace_macros-format.stderr
deleted file mode 100644 (file)
index c320270..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-error: trace_macros! accepts only `true` or `false`
-  --> $DIR/trace_macros-format.rs:4:5
-   |
-LL |     trace_macros!();
-   |     ^^^^^^^^^^^^^^^
-
-error: trace_macros! accepts only `true` or `false`
-  --> $DIR/trace_macros-format.rs:5:5
-   |
-LL |     trace_macros!(1);
-   |     ^^^^^^^^^^^^^^^^
-
-error: trace_macros! accepts only `true` or `false`
-  --> $DIR/trace_macros-format.rs:6:5
-   |
-LL |     trace_macros!(ident);
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: trace_macros! accepts only `true` or `false`
-  --> $DIR/trace_macros-format.rs:7:5
-   |
-LL |     trace_macros!(for);
-   |     ^^^^^^^^^^^^^^^^^^
-
-error: trace_macros! accepts only `true` or `false`
-  --> $DIR/trace_macros-format.rs:8:5
-   |
-LL |     trace_macros!(true,);
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: trace_macros! accepts only `true` or `false`
-  --> $DIR/trace_macros-format.rs:9:5
-   |
-LL |     trace_macros!(false 1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 6 previous errors
-
diff --git a/src/test/ui/traits/issue-24010.rs b/src/test/ui/traits/issue-24010.rs
new file mode 100644 (file)
index 0000000..f181853
--- /dev/null
@@ -0,0 +1,14 @@
+// run-pass
+
+trait Foo: Fn(i32) -> i32 + Send {}
+
+impl<T: ?Sized + Fn(i32) -> i32 + Send> Foo for T {}
+
+fn wants_foo(f: Box<dyn Foo>) -> i32 {
+    f(42)
+}
+
+fn main() {
+    let f = Box::new(|x| x);
+    assert_eq!(wants_foo(f), 42);
+}
diff --git a/src/test/ui/traits/issue-38604.rs b/src/test/ui/traits/issue-38604.rs
new file mode 100644 (file)
index 0000000..002a3c4
--- /dev/null
@@ -0,0 +1,16 @@
+trait Q<T:?Sized> {}
+trait Foo where u32: Q<Self> {
+    fn foo(&self);
+}
+
+impl Q<()> for u32 {}
+impl Foo for () {
+    fn foo(&self) {
+        println!("foo!");
+    }
+}
+
+fn main() {
+    let _f: Box<dyn Foo> = //~ ERROR `Foo` cannot be made into an object
+        Box::new(()); //~ ERROR `Foo` cannot be made into an object
+}
diff --git a/src/test/ui/traits/issue-38604.stderr b/src/test/ui/traits/issue-38604.stderr
new file mode 100644 (file)
index 0000000..d41488c
--- /dev/null
@@ -0,0 +1,33 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/issue-38604.rs:14:13
+   |
+LL |     let _f: 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/issue-38604.rs:2:22
+   |
+LL | trait Foo where u32: Q<Self> {
+   |       ---            ^^^^^^^ ...because it uses `Self` as a type parameter
+   |       |
+   |       this trait cannot be made into an object...
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/issue-38604.rs:15:9
+   |
+LL |         Box::new(());
+   |         ^^^^^^^^^^^^ `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/issue-38604.rs:2:22
+   |
+LL | trait Foo where u32: Q<Self> {
+   |       ---            ^^^^^^^ ...because it uses `Self` as a type parameter
+   |       |
+   |       this trait cannot be made into an object...
+   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<()>`
+   = note: required by cast to type `Box<dyn Foo>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/traits/issue-3973.rs b/src/test/ui/traits/issue-3973.rs
new file mode 100644 (file)
index 0000000..a5ed5b8
--- /dev/null
@@ -0,0 +1,25 @@
+struct Point {
+    x: f64,
+    y: f64,
+}
+
+trait ToString_ {
+    fn to_string(&self) -> String;
+}
+
+impl ToString_ for Point {
+    fn new(x: f64, y: f64) -> Point {
+    //~^ ERROR method `new` is not a member of trait `ToString_`
+        Point { x: x, y: y }
+    }
+
+    fn to_string(&self) -> String {
+        format!("({}, {})", self.x, self.y)
+    }
+}
+
+fn main() {
+    let p = Point::new(0.0, 0.0);
+    //~^ ERROR no function or associated item named `new` found for struct `Point`
+    println!("{}", p.to_string());
+}
diff --git a/src/test/ui/traits/issue-3973.stderr b/src/test/ui/traits/issue-3973.stderr
new file mode 100644 (file)
index 0000000..63282e8
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0407]: method `new` is not a member of trait `ToString_`
+  --> $DIR/issue-3973.rs:11:5
+   |
+LL | /     fn new(x: f64, y: f64) -> Point {
+LL | |
+LL | |         Point { x: x, y: y }
+LL | |     }
+   | |_____^ not a member of trait `ToString_`
+
+error[E0599]: no function or associated item named `new` found for struct `Point` in the current scope
+  --> $DIR/issue-3973.rs:22:20
+   |
+LL | struct Point {
+   | ------------ function or associated item `new` not found for this
+...
+LL |     let p = Point::new(0.0, 0.0);
+   |                    ^^^ function or associated item not found in `Point`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0407, E0599.
+For more information about an error, try `rustc --explain E0407`.
diff --git a/src/test/ui/traits/issue-59029-1.rs b/src/test/ui/traits/issue-59029-1.rs
new file mode 100644 (file)
index 0000000..8ab47a4
--- /dev/null
@@ -0,0 +1,9 @@
+#![feature(trait_alias)]
+
+trait Svc<Req> { type Res; }
+
+trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
+//~^ ERROR associated type `Res` not found for `Self`
+//~| ERROR associated type `Res` not found for `Self`
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-59029-1.stderr b/src/test/ui/traits/issue-59029-1.stderr
new file mode 100644 (file)
index 0000000..53cdb8b
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0220]: associated type `Res` not found for `Self`
+  --> $DIR/issue-59029-1.rs:5:52
+   |
+LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
+   |                                                    ^^^ associated type `Res` not found
+
+error[E0220]: associated type `Res` not found for `Self`
+  --> $DIR/issue-59029-1.rs:5:52
+   |
+LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
+   |                                                    ^^^ associated type `Res` not found
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/src/test/ui/traits/issue-72455.rs b/src/test/ui/traits/issue-72455.rs
new file mode 100644 (file)
index 0000000..b6c3bb2
--- /dev/null
@@ -0,0 +1,27 @@
+// check-pass
+
+pub trait ResultExt {
+    type Ok;
+    fn err_eprint_and_ignore(self) -> Option<Self::Ok>;
+}
+
+impl<O, E> ResultExt for std::result::Result<O, E>
+where
+    E: std::error::Error,
+{
+    type Ok = O;
+    fn err_eprint_and_ignore(self) -> Option<O>
+    where
+        Self: ,
+    {
+        match self {
+            Err(e) => {
+                eprintln!("{}", e);
+                None
+            }
+            Ok(o) => Some(o),
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/object-does-not-impl-trait.rs b/src/test/ui/traits/object-does-not-impl-trait.rs
new file mode 100644 (file)
index 0000000..b3b6798
--- /dev/null
@@ -0,0 +1,8 @@
+// Test that an object type `Box<Foo>` is not considered to implement the
+// trait `Foo`. Issue #5087.
+
+trait Foo {}
+fn take_foo<F:Foo>(f: F) {}
+fn take_object(f: Box<dyn Foo>) { take_foo(f); }
+//~^ ERROR `Box<dyn Foo>: Foo` is not satisfied
+fn main() {}
diff --git a/src/test/ui/traits/object-does-not-impl-trait.stderr b/src/test/ui/traits/object-does-not-impl-trait.stderr
new file mode 100644 (file)
index 0000000..f1dd508
--- /dev/null
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `Box<dyn Foo>: Foo` is not satisfied
+  --> $DIR/object-does-not-impl-trait.rs:6:44
+   |
+LL | fn take_object(f: Box<dyn Foo>) { take_foo(f); }
+   |                                   -------- ^ the trait `Foo` is not implemented for `Box<dyn Foo>`
+   |                                   |
+   |                                   required by a bound introduced by this call
+   |
+note: required by a bound in `take_foo`
+  --> $DIR/object-does-not-impl-trait.rs:5:15
+   |
+LL | fn take_foo<F:Foo>(f: F) {}
+   |               ^^^ required by this bound in `take_foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/traits/syntax-trait-polarity.rs b/src/test/ui/traits/syntax-trait-polarity.rs
new file mode 100644 (file)
index 0000000..ed29474
--- /dev/null
@@ -0,0 +1,25 @@
+#![feature(negative_impls)]
+
+use std::marker::Send;
+
+struct TestType;
+
+impl !TestType {}
+//~^ ERROR inherent impls cannot be negative
+
+trait TestTrait {}
+
+unsafe impl !Send for TestType {}
+//~^ ERROR negative impls cannot be unsafe
+impl !TestTrait for TestType {}
+
+struct TestType2<T>(T);
+
+impl<T> !TestType2<T> {}
+//~^ ERROR inherent impls cannot be negative
+
+unsafe impl<T> !Send for TestType2<T> {}
+//~^ ERROR negative impls cannot be unsafe
+impl<T> !TestTrait for TestType2<T> {}
+
+fn main() {}
diff --git a/src/test/ui/traits/syntax-trait-polarity.stderr b/src/test/ui/traits/syntax-trait-polarity.stderr
new file mode 100644 (file)
index 0000000..1fd40fb
--- /dev/null
@@ -0,0 +1,37 @@
+error: inherent impls cannot be negative
+  --> $DIR/syntax-trait-polarity.rs:7:7
+   |
+LL | impl !TestType {}
+   |      -^^^^^^^^ inherent impl for this type
+   |      |
+   |      negative because of this
+
+error[E0198]: negative impls cannot be unsafe
+  --> $DIR/syntax-trait-polarity.rs:12:13
+   |
+LL | unsafe impl !Send for TestType {}
+   | ------      -^^^^
+   | |           |
+   | |           negative because of this
+   | unsafe because of this
+
+error: inherent impls cannot be negative
+  --> $DIR/syntax-trait-polarity.rs:18:10
+   |
+LL | impl<T> !TestType2<T> {}
+   |         -^^^^^^^^^^^^ inherent impl for this type
+   |         |
+   |         negative because of this
+
+error[E0198]: negative impls cannot be unsafe
+  --> $DIR/syntax-trait-polarity.rs:21:16
+   |
+LL | unsafe impl<T> !Send for TestType2<T> {}
+   | ------         -^^^^
+   | |              |
+   | |              negative because of this
+   | unsafe because of this
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0198`.
diff --git a/src/test/ui/transmute-specialization.rs b/src/test/ui/transmute-specialization.rs
deleted file mode 100644 (file)
index 499334d..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-
-#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
-
-trait Specializable { type Output; }
-
-impl<T> Specializable for T {
-    default type Output = u16;
-}
-
-fn main() {
-    unsafe {
-        std::mem::transmute::<u16, <() as Specializable>::Output>(0);
-    }
-}
diff --git a/src/test/ui/transmute-specialization.stderr b/src/test/ui/transmute-specialization.stderr
deleted file mode 100644 (file)
index a0ea724..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/transmute-specialization.rs:3:12
-   |
-LL | #![feature(specialization)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
-   = help: consider using `min_specialization` instead, which is more stable and complete
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/trivial-message.rs b/src/test/ui/trivial-message.rs
deleted file mode 100644 (file)
index 5831e86..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-
-#![allow(unused_must_use)]
-/*
-  This is about the simplest program that can successfully send a
-  message.
- */
-
-use std::sync::mpsc::channel;
-
-pub fn main() {
-    let (tx, rx) = channel();
-    tx.send(42);
-    let r = rx.recv();
-    println!("{:?}", r);
-}
diff --git a/src/test/ui/try-block/issue-45124.rs b/src/test/ui/try-block/issue-45124.rs
new file mode 100644 (file)
index 0000000..942014c
--- /dev/null
@@ -0,0 +1,18 @@
+// run-pass
+#![allow(unreachable_code)]
+// compile-flags: --edition 2018
+
+#![feature(try_blocks)]
+
+fn main() {
+    let mut a = 0;
+    let () = {
+        let _: Result<(), ()> = try {
+            let _ = Err(())?;
+            return
+        };
+        a += 1;
+    };
+    a += 2;
+    assert_eq!(a, 3);
+}
diff --git a/src/test/ui/try-macro-suggestion.rs b/src/test/ui/try-macro-suggestion.rs
deleted file mode 100644 (file)
index 635ceac..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// compile-flags: --edition 2018
-fn foo() -> Result<(), ()> {
-    Ok(try!()); //~ ERROR use of deprecated `try` macro
-    Ok(try!(Ok(()))) //~ ERROR use of deprecated `try` macro
-}
-
-fn main() {
-    let _ = foo();
-}
diff --git a/src/test/ui/try-macro-suggestion.stderr b/src/test/ui/try-macro-suggestion.stderr
deleted file mode 100644 (file)
index c7dde7e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-error: use of deprecated `try` macro
-  --> $DIR/try-macro-suggestion.rs:3:8
-   |
-LL |     Ok(try!());
-   |        ^^^^^^
-   |
-   = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated
-help: you can still access the deprecated `try!()` macro using the "raw identifier" syntax
-   |
-LL |     Ok(r#try!());
-   |        ++
-
-error: use of deprecated `try` macro
-  --> $DIR/try-macro-suggestion.rs:4:8
-   |
-LL |     Ok(try!(Ok(())))
-   |        ^^^^^^^^^^^^
-   |
-   = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated
-help: you can use the `?` operator instead
-   |
-LL -     Ok(try!(Ok(())))
-LL +     Ok(Ok(())?)
-   | 
-help: alternatively, you can still access the deprecated `try!()` macro using the "raw identifier" syntax
-   |
-LL |     Ok(r#try!(Ok(())))
-   |        ++
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/type-alias-impl-trait/issue-60662.rs b/src/test/ui/type-alias-impl-trait/issue-60662.rs
new file mode 100644 (file)
index 0000000..b9faa66
--- /dev/null
@@ -0,0 +1,10 @@
+// check-pass
+// compile-flags: -Z unpretty=hir
+
+#![feature(type_alias_impl_trait)]
+
+trait Animal {}
+
+fn main() {
+    pub type ServeFut = impl Animal;
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-60662.stdout b/src/test/ui/type-alias-impl-trait/issue-60662.stdout
new file mode 100644 (file)
index 0000000..14a49f2
--- /dev/null
@@ -0,0 +1,14 @@
+// check-pass
+// compile-flags: -Z unpretty=hir
+
+#![feature(type_alias_impl_trait)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+trait Animal { }
+
+fn main() {
+              pub type ServeFut = /*impl Trait*/;
+          }
diff --git a/src/test/ui/type-inference/issue-30225.rs b/src/test/ui/type-inference/issue-30225.rs
new file mode 100644 (file)
index 0000000..4231533
--- /dev/null
@@ -0,0 +1,38 @@
+// Regression test for #30225, which was an ICE that would trigger as
+// a result of a poor interaction between trait result caching and
+// type inference. Specifically, at that time, unification could cause
+// unrelated type variables to become instantiated, if subtyping
+// relationships existed. These relationships are now propagated
+// through obligations and hence everything works out fine.
+
+trait Foo<U,V> : Sized {
+    fn foo(self, u: Option<U>, v: Option<V>) {}
+}
+
+struct A;
+struct B;
+
+impl Foo<A, B> for () {}      // impl A
+impl Foo<u32, u32> for u32 {} // impl B, creating ambiguity
+
+fn toxic() {
+    // cache the resolution <() as Foo<$0,$1>> = impl A
+    let u = None;
+    let v = None;
+    Foo::foo((), u, v);
+}
+
+fn bomb() {
+    let mut u = None; // type is Option<$0>
+    let mut v = None; // type is Option<$1>
+    let mut x = None; // type is Option<$2>
+
+    Foo::foo(x.unwrap(),u,v); // register <$2 as Foo<$0, $1>>
+    u = v; // mark $0 and $1 in a subtype relationship
+    //~^ ERROR mismatched types
+    x = Some(()); // set $2 = (), allowing impl selection
+                  // to proceed for <() as Foo<$0, $1>> = impl A.
+                  // kaboom, this *used* to trigge an ICE
+}
+
+fn main() {}
diff --git a/src/test/ui/type-inference/issue-30225.stderr b/src/test/ui/type-inference/issue-30225.stderr
new file mode 100644 (file)
index 0000000..ccd05fa
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-30225.rs:31:9
+   |
+LL |     u = v; // mark $0 and $1 in a subtype relationship
+   |         ^ expected struct `A`, found struct `B`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/typeck/auxiliary/xcrate-issue-43189-a.rs b/src/test/ui/typeck/auxiliary/xcrate-issue-43189-a.rs
new file mode 100644 (file)
index 0000000..9ab570f
--- /dev/null
@@ -0,0 +1,7 @@
+#![crate_type="lib"]
+
+
+pub trait A {
+    fn a(&self) {}
+}
+impl A for () {}
diff --git a/src/test/ui/typeck/auxiliary/xcrate-issue-43189-b.rs b/src/test/ui/typeck/auxiliary/xcrate-issue-43189-b.rs
new file mode 100644 (file)
index 0000000..31dfb05
--- /dev/null
@@ -0,0 +1,3 @@
+#![crate_type="lib"]
+
+pub extern crate xcrate_issue_43189_a;
diff --git a/src/test/ui/typeck/auxiliary/xcrate-issue-46112-rexport-core.rs b/src/test/ui/typeck/auxiliary/xcrate-issue-46112-rexport-core.rs
new file mode 100644 (file)
index 0000000..2b517b5
--- /dev/null
@@ -0,0 +1,3 @@
+#![crate_type="lib"]
+
+pub extern crate core;
diff --git a/src/test/ui/typeck/auxiliary/xcrate-issue-61711-b.rs b/src/test/ui/typeck/auxiliary/xcrate-issue-61711-b.rs
new file mode 100644 (file)
index 0000000..88a0405
--- /dev/null
@@ -0,0 +1,5 @@
+// edition:2018
+#![crate_type="lib"]
+#![crate_name="xcrate_issue_61711_b"]
+pub struct Struct;
+pub use crate as alias;
diff --git a/src/test/ui/typeck/issue-43189.rs b/src/test/ui/typeck/issue-43189.rs
new file mode 100644 (file)
index 0000000..ce667a5
--- /dev/null
@@ -0,0 +1,12 @@
+// Issue 46112: An extern crate pub re-exporting libcore was causing
+// paths rooted from `std` to be misrendered in the diagnostic output.
+
+// ignore-windows
+// aux-build:xcrate-issue-43189-a.rs
+// aux-build:xcrate-issue-43189-b.rs
+
+extern crate xcrate_issue_43189_b;
+fn main() {
+    ().a();
+    //~^ ERROR no method named `a` found
+}
diff --git a/src/test/ui/typeck/issue-43189.stderr b/src/test/ui/typeck/issue-43189.stderr
new file mode 100644 (file)
index 0000000..caf7530
--- /dev/null
@@ -0,0 +1,20 @@
+error[E0599]: no method named `a` found for unit type `()` in the current scope
+  --> $DIR/issue-43189.rs:10:8
+   |
+LL |     ().a();
+   |        ^ method not found in `()`
+   |
+  ::: $DIR/auxiliary/xcrate-issue-43189-a.rs:5:8
+   |
+LL |     fn a(&self) {}
+   |        - the method is available for `()` here
+   |
+   = help: items from traits can only be used if the trait is in scope
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+   |
+LL | use xcrate_issue_43189_b::xcrate_issue_43189_a::A;
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/typeck/issue-46112.rs b/src/test/ui/typeck/issue-46112.rs
new file mode 100644 (file)
index 0000000..0cdd2c2
--- /dev/null
@@ -0,0 +1,10 @@
+// Issue 46112: An extern crate pub re-exporting libcore was causing
+// paths rooted from `std` to be misrendered in the diagnostic output.
+
+// ignore-windows
+// aux-build:xcrate-issue-46112-rexport-core.rs
+
+extern crate xcrate_issue_46112_rexport_core;
+fn test(r: Result<Option<()>, &'static str>) { }
+fn main() { test(Ok(())); }
+//~^ mismatched types
diff --git a/src/test/ui/typeck/issue-46112.stderr b/src/test/ui/typeck/issue-46112.stderr
new file mode 100644 (file)
index 0000000..ec05fbe
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-46112.rs:9:21
+   |
+LL | fn main() { test(Ok(())); }
+   |                     ^^
+   |                     |
+   |                     expected enum `Option`, found `()`
+   |                     help: try using a variant of the expected enum: `Some(())`
+   |
+   = note:   expected enum `Option<()>`
+           found unit type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/typeck/issue-61711-once-caused-rustc-inf-loop.rs b/src/test/ui/typeck/issue-61711-once-caused-rustc-inf-loop.rs
new file mode 100644 (file)
index 0000000..de7d6a0
--- /dev/null
@@ -0,0 +1,11 @@
+// Issue 61711: A crate pub re-exporting `crate` was causing an
+// infinite loop.
+
+// edition:2018
+// aux-build:xcrate-issue-61711-b.rs
+// compile-flags:--extern xcrate_issue_61711_b
+
+// build-pass
+
+fn f<F: Fn(xcrate_issue_61711_b::Struct)>(_: F) { }
+fn main() { }
diff --git a/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.rs b/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.rs
new file mode 100644 (file)
index 0000000..74e50d4
--- /dev/null
@@ -0,0 +1,14 @@
+// edition:2021
+
+mod m {
+  pub struct S { foo: i32 }
+  impl S {
+    pub fn foo(&self) -> i32 { 42 }
+  }
+}
+
+fn bar(s: &m::S) {
+  || s.foo() + s.foo; //~ ERROR E0616
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.stderr b/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.stderr
new file mode 100644 (file)
index 0000000..02cdc10
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0616]: field `foo` of struct `S` is private
+  --> $DIR/issue-90483-inaccessible-field-adjustment.rs:11:18
+   |
+LL |   || s.foo() + s.foo;
+   |                  ^^^ private field
+   |
+help: a method `foo` also exists, call it with parentheses
+   |
+LL |   || s.foo() + s.foo();
+   |                     ++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0616`.
diff --git a/src/test/ui/unary-minus-suffix-inference.rs b/src/test/ui/unary-minus-suffix-inference.rs
deleted file mode 100644 (file)
index a4d0a84..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// run-pass
-
-pub fn main() {
-    let a = 1;
-    let a_neg: i8 = -a;
-    println!("{}", a_neg);
-
-    let b = 1;
-    let b_neg: i16 = -b;
-    println!("{}", b_neg);
-
-    let c = 1;
-    let c_neg: i32 = -c;
-    println!("{}", c_neg);
-
-    let d = 1;
-    let d_neg: i64 = -d;
-    println!("{}", d_neg);
-
-    let e = 1;
-    let e_neg: isize = -e;
-    println!("{}", e_neg);
-}
diff --git a/src/test/ui/unboxed-closures/issue-18652.rs b/src/test/ui/unboxed-closures/issue-18652.rs
new file mode 100644 (file)
index 0000000..59aa015
--- /dev/null
@@ -0,0 +1,10 @@
+// run-pass
+// Tests multiple free variables being passed by value into an unboxed
+// once closure as an optimization by codegen.  This used to hit an
+// incorrect assert.
+
+fn main() {
+    let x = 2u8;
+    let y = 3u8;
+    assert_eq!((move || x + y)(), 5);
+}
index 76c14ccc14b4522906c1821bb06a5ec6c26b9572..8976da01e739beba94204208bf2482f6543e3b42 100644 (file)
@@ -5,6 +5,12 @@ LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); }
    |                    ------      ------           ^ ...but data from `y` flows into `x` here
    |                                |
    |                                these two types are declared with different lifetimes...
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
+   |       ++++              ~~          ~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unnecessary-extern-crate.rs b/src/test/ui/unnecessary-extern-crate.rs
deleted file mode 100644 (file)
index 67eaaf4..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-// edition:2018
-
-#![deny(unused_extern_crates)]
-#![feature(test, rustc_private, crate_visibility_modifier)]
-
-extern crate libc;
-//~^ ERROR unused extern crate
-//~| HELP remove
-extern crate libc as x;
-//~^ ERROR unused extern crate
-//~| HELP remove
-
-extern crate proc_macro;
-
-#[macro_use]
-extern crate test;
-
-pub extern crate test as y;
-
-pub extern crate alloc;
-
-pub(crate) extern crate alloc as a;
-
-crate extern crate alloc as b;
-
-mod foo {
-    pub(in crate::foo) extern crate alloc as c;
-
-    pub(super) extern crate alloc as d;
-
-    extern crate libc;
-    //~^ ERROR unused extern crate
-    //~| HELP remove
-
-    extern crate libc as x;
-    //~^ ERROR unused extern crate
-    //~| HELP remove
-
-    pub extern crate test;
-
-    pub extern crate test as y;
-
-    mod bar {
-        extern crate libc;
-        //~^ ERROR unused extern crate
-        //~| HELP remove
-
-        extern crate libc as x;
-        //~^ ERROR unused extern crate
-        //~| HELP remove
-
-        pub(in crate::foo::bar) extern crate alloc as e;
-
-        fn dummy() {
-            e::string::String::new();
-        }
-    }
-
-    fn dummy() {
-        c::string::String::new();
-        d::string::String::new();
-    }
-}
-
-
-fn main() {
-    a::string::String::new();
-    b::string::String::new();
-
-    proc_macro::TokenStream::new();
-}
diff --git a/src/test/ui/unnecessary-extern-crate.stderr b/src/test/ui/unnecessary-extern-crate.stderr
deleted file mode 100644 (file)
index 14ba9d0..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:6:1
-   |
-LL | extern crate libc;
-   | ^^^^^^^^^^^^^^^^^^ help: remove it
-   |
-note: the lint level is defined here
-  --> $DIR/unnecessary-extern-crate.rs:3:9
-   |
-LL | #![deny(unused_extern_crates)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:9:1
-   |
-LL | extern crate libc as x;
-   | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:31:5
-   |
-LL |     extern crate libc;
-   |     ^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:35:5
-   |
-LL |     extern crate libc as x;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:44:9
-   |
-LL |         extern crate libc;
-   |         ^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:48:9
-   |
-LL |         extern crate libc as x;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: aborting due to 6 previous errors
-
diff --git a/src/test/ui/unrestricted-attribute-tokens.rs b/src/test/ui/unrestricted-attribute-tokens.rs
deleted file mode 100644 (file)
index e31bc91..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// build-pass (FIXME(62277): could be check-pass?)
-
-#![feature(rustc_attrs)]
-
-#[rustc_dummy(a b c d)]
-#[rustc_dummy[a b c d]]
-#[rustc_dummy{a b c d}]
-fn main() {}
diff --git a/src/test/ui/unsized/issue-30355.rs b/src/test/ui/unsized/issue-30355.rs
new file mode 100644 (file)
index 0000000..6ff5b37
--- /dev/null
@@ -0,0 +1,9 @@
+pub struct X([u8]);
+
+pub static Y: &'static X = {
+    const Y: &'static [u8] = b"";
+    &X(*Y)
+    //~^ ERROR E0277
+};
+
+fn main() {}
diff --git a/src/test/ui/unsized/issue-30355.stderr b/src/test/ui/unsized/issue-30355.stderr
new file mode 100644 (file)
index 0000000..71bbdf5
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/issue-30355.rs:5:8
+   |
+LL |     &X(*Y)
+   |        ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+   = note: all function arguments must have a statically known size
+   = help: unsized fn params are gated as an unstable feature
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
index 83199e8112e71d2ad12245d61793e49d91e142bc..93c7af68ac388e145714fe11c473d29eb0b5b16b 100644 (file)
@@ -1,4 +1,3 @@
-#![feature(relaxed_struct_unsize)]
 // run-pass
 // Test that we allow unsizing even if there is an unchanged param in the
 // field getting unsized.
index 9339a004d3b742bf138b79f0c3014e08737d72c5..6ac558974d0c5476e6a606ffe3006a0b050607ac 100644 (file)
@@ -1,7 +1,7 @@
 // --extern-location with a raw reference
 
 // aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar
+// compile-flags:--extern-location bar -Zunstable-options
 
 #![warn(unused_crate_dependencies)]
 
diff --git a/src/test/ui/warn-ctypes-inhibit.rs b/src/test/ui/warn-ctypes-inhibit.rs
deleted file mode 100644 (file)
index 15d8b09..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-
-#![allow(dead_code)]
-// compile-flags:-D improper-ctypes
-
-// pretty-expanded FIXME #23616
-#![allow(improper_ctypes)]
-
-mod libc {
-    extern "C" {
-        pub fn malloc(size: isize) -> *const u8;
-    }
-}
-
-pub fn main() {}
diff --git a/src/test/ui/yield2.rs b/src/test/ui/yield2.rs
deleted file mode 100644 (file)
index 376faab..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-pass
-
-use std::thread;
-
-pub fn main() {
-    let mut i: isize = 0;
-    while i < 100 { i = i + 1; println!("{}", i); thread::yield_now(); }
-}
index 6c1bc24b8b49d4bc965f67d7037906dc199c72b7..94ca096afbf25f670e76e07dca754fcfe27134be 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 6c1bc24b8b49d4bc965f67d7037906dc199c72b7
+Subproject commit 94ca096afbf25f670e76e07dca754fcfe27134be
diff --git a/src/tools/clippy/.cargo/config b/src/tools/clippy/.cargo/config
deleted file mode 100644 (file)
index 688473f..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-[alias]
-uitest = "test --test compile-test"
-dev = "run --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --"
-lintcheck = "run --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml  -- "
-collect-metadata = "test --test dogfood --features metadata-collector-lint -- run_metadata_collection_lint --ignored"
-
-[build]
-# -Zbinary-dep-depinfo allows us to track which rlib files to use for compiling UI tests
-rustflags = ["-Zunstable-options", "-Zbinary-dep-depinfo"]
-target-dir = "target"
diff --git a/src/tools/clippy/.cargo/config.toml b/src/tools/clippy/.cargo/config.toml
new file mode 100644 (file)
index 0000000..688473f
--- /dev/null
@@ -0,0 +1,10 @@
+[alias]
+uitest = "test --test compile-test"
+dev = "run --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --"
+lintcheck = "run --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml  -- "
+collect-metadata = "test --test dogfood --features metadata-collector-lint -- run_metadata_collection_lint --ignored"
+
+[build]
+# -Zbinary-dep-depinfo allows us to track which rlib files to use for compiling UI tests
+rustflags = ["-Zunstable-options", "-Zbinary-dep-depinfo"]
+target-dir = "target"
index a3c57232f557c4b774cb53ecc7e10299db1bd8e6..34225a5402904084617e9f19adaaa762d0aa5336 100644 (file)
@@ -13,7 +13,8 @@ cp util/gh-pages/lints.json out/master
 if [[ -n $TAG_NAME ]]; then
   echo "Save the doc for the current tag ($TAG_NAME) and point stable/ to it"
   cp -Tr out/master "out/$TAG_NAME"
-  ln -sf "$TAG_NAME" out/stable
+  rm -f out/stable
+  ln -s "$TAG_NAME" out/stable
 fi
 
 if [[ $BETA = "true" ]]; then
index 3b4c687209e11dfa8ebb9454ad8c4af571a9677f..85a6a6be8b7f2618d9b515afc201e54f27781e13 100644 (file)
@@ -6,11 +6,162 @@ document.
 
 ## Unreleased / In Rust Nightly
 
-[7bfc26e...master](https://github.com/rust-lang/rust-clippy/compare/7bfc26e...master)
+[b7f3f7f...master](https://github.com/rust-lang/rust-clippy/compare/b7f3f7f...master)
+
+## Rust 1.57
+
+Current beta, release 2021-12-02
+
+[7bfc26e...b7f3f7f](https://github.com/rust-lang/rust-clippy/compare/7bfc26e...b7f3f7f)
+
+### New Lints
+
+* [`negative_feature_names`]
+  [#7539](https://github.com/rust-lang/rust-clippy/pull/7539)
+* [`redundant_feature_names`]
+  [#7539](https://github.com/rust-lang/rust-clippy/pull/7539)
+* [`mod_module_files`]
+  [#7543](https://github.com/rust-lang/rust-clippy/pull/7543)
+* [`self_named_module_files`]
+  [#7543](https://github.com/rust-lang/rust-clippy/pull/7543)
+* [`manual_split_once`]
+  [#7565](https://github.com/rust-lang/rust-clippy/pull/7565)
+* [`derivable_impls`]
+  [#7570](https://github.com/rust-lang/rust-clippy/pull/7570)
+* [`needless_option_as_deref`]
+  [#7596](https://github.com/rust-lang/rust-clippy/pull/7596)
+* [`iter_not_returning_iterator`]
+  [#7610](https://github.com/rust-lang/rust-clippy/pull/7610)
+* [`same_name_method`]
+  [#7653](https://github.com/rust-lang/rust-clippy/pull/7653)
+* [`manual_assert`] [#7669](https://github.com/rust-lang/rust-clippy/pull/7669)
+* [`non_send_fields_in_send_ty`]
+  [#7709](https://github.com/rust-lang/rust-clippy/pull/7709)
+* [`equatable_if_let`]
+  [#7762](https://github.com/rust-lang/rust-clippy/pull/7762)
+
+### Moves and Deprecations
+
+* Move [`shadow_unrelated`] to `restriction`
+  [#7338](https://github.com/rust-lang/rust-clippy/pull/7338)
+* Move [`option_if_let_else`] to `nursery`
+  [#7568](https://github.com/rust-lang/rust-clippy/pull/7568)
+* Move [`branches_sharing_code`] to `nursery`
+  [#7595](https://github.com/rust-lang/rust-clippy/pull/7595)
+* Rename `if_let_some_result` to [`match_result_ok`] which now also handles
+  `while let` cases [#7608](https://github.com/rust-lang/rust-clippy/pull/7608)
+* Move [`many_single_char_names`] to `pedantic`
+  [#7671](https://github.com/rust-lang/rust-clippy/pull/7671)
+* Move [`float_cmp`] to `pedantic`
+  [#7692](https://github.com/rust-lang/rust-clippy/pull/7692)
+* Rename `box_vec` to [`box_collection`] and lint on more general cases
+  [#7693](https://github.com/rust-lang/rust-clippy/pull/7693)
+* Uplift `invalid_atomic_ordering` to rustc
+  [rust-lang/rust#84039](https://github.com/rust-lang/rust/pull/84039)
+
+### Enhancements
+
+* Rewrite the `shadow*` lints, so that they find a lot more shadows and are not
+  limited to certain patterns
+  [#7338](https://github.com/rust-lang/rust-clippy/pull/7338)
+* The `avoid-breaking-exported-api` configuration now also works for
+  [`box_collection`], [`redundant_allocation`], [`rc_buffer`], [`vec_box`],
+  [`option_option`], [`linkedlist`], [`rc_mutex`]
+  [#7560](https://github.com/rust-lang/rust-clippy/pull/7560)
+* [`unnecessary_unwrap`]: Now also checks for `expect`s
+  [#7584](https://github.com/rust-lang/rust-clippy/pull/7584)
+* [`disallowed_method`]: Allow adding a reason that will be displayed with the
+  lint message
+  [#7621](https://github.com/rust-lang/rust-clippy/pull/7621)
+* [`approx_constant`]: Now checks the MSRV for `LOG10_2` and `LOG2_10`
+  [#7629](https://github.com/rust-lang/rust-clippy/pull/7629)
+* [`approx_constant`]: Add `TAU`
+  [#7642](https://github.com/rust-lang/rust-clippy/pull/7642)
+* [`needless_borrow`]: Now also lints on needless mutable borrows
+  [#7657](https://github.com/rust-lang/rust-clippy/pull/7657)
+* [`missing_safety_doc`]: Now also lints on unsafe traits
+  [#7734](https://github.com/rust-lang/rust-clippy/pull/7734)
+
+### False Positive Fixes
+
+* [`manual_map`]: No longer lints when the option is borrowed in the match and
+  also consumed in the arm
+  [#7531](https://github.com/rust-lang/rust-clippy/pull/7531)
+* [`filter_next`]: No longer lints if `filter` method is not the
+  `Iterator::filter` method
+  [#7562](https://github.com/rust-lang/rust-clippy/pull/7562)
+* [`manual_flatten`]: No longer lints if expression is used after `if let`
+  [#7566](https://github.com/rust-lang/rust-clippy/pull/7566)
+* [`option_if_let_else`]: Multiple fixes
+  [#7573](https://github.com/rust-lang/rust-clippy/pull/7573)
+    * `break` and `continue` statements local to the would-be closure are
+      allowed
+    * Don't lint in const contexts
+    * Don't lint when yield expressions are used
+    * Don't lint when the captures made by the would-be closure conflict with
+      the other branch
+    * Don't lint when a field of a local is used when the type could be
+      potentially moved from
+    * In some cases, don't lint when scrutinee expression conflicts with the
+      captures of the would-be closure
+* [`redundant_allocation`]: No longer lints on `Box<Box<dyn T>>` which replaces
+  wide pointers with thin pointers
+  [#7592](https://github.com/rust-lang/rust-clippy/pull/7592)
+* [`bool_assert_comparison`]: No longer lints on types that do not implement the
+  `Not` trait with `Output = bool`
+  [#7605](https://github.com/rust-lang/rust-clippy/pull/7605)
+* [`mut_range_bound`]: No longer lints on range bound mutations, that are
+  immediately followed by a `break;`
+  [#7607](https://github.com/rust-lang/rust-clippy/pull/7607)
+* [`mutable_key_type`]: Improve accuracy and document remaining false positives
+  and false negatives
+  [#7640](https://github.com/rust-lang/rust-clippy/pull/7640)
+* [`redundant_closure`]: Rewrite the lint to fix various false positives and
+  false negatives [#7661](https://github.com/rust-lang/rust-clippy/pull/7661)
+* [`large_enum_variant`]: No longer wrongly identifies the second largest
+  variant [#7677](https://github.com/rust-lang/rust-clippy/pull/7677)
+* [`needless_return`]: No longer lints on let-else expressions
+  [#7685](https://github.com/rust-lang/rust-clippy/pull/7685)
+* [`suspicious_else_formatting`]: No longer lints in proc-macros
+  [#7707](https://github.com/rust-lang/rust-clippy/pull/7707)
+* [`excessive_precision`]: No longer lints when in some cases the float was
+  already written in the shortest form
+  [#7722](https://github.com/rust-lang/rust-clippy/pull/7722)
+* [`doc_markdown`]: No longer lints on intra-doc links
+  [#7772](https://github.com/rust-lang/rust-clippy/pull/7772)
+
+### Suggestion Fixes/Improvements
+
+* [`unnecessary_operation`]: Recommend using an `assert!` instead of using a
+  function call in an indexing operation
+  [#7453](https://github.com/rust-lang/rust-clippy/pull/7453)
+* [`manual_split_once`]: Produce semantically equivalent suggestion when
+  `rsplitn` is used [#7663](https://github.com/rust-lang/rust-clippy/pull/7663)
+* [`while_let_on_iterator`]: Produce correct suggestion when using `&mut`
+  [#7690](https://github.com/rust-lang/rust-clippy/pull/7690)
+* [`manual_assert`]: No better handles complex conditions
+  [#7741](https://github.com/rust-lang/rust-clippy/pull/7741)
+* Correctly handle signs in exponents in numeric literals lints
+  [#7747](https://github.com/rust-lang/rust-clippy/pull/7747)
+* [`suspicious_map`]: Now also suggests to use `inspect` as an alternative
+  [#7770](https://github.com/rust-lang/rust-clippy/pull/7770)
+* Drop exponent from suggestion if it is 0 in numeric literals lints
+  [#7774](https://github.com/rust-lang/rust-clippy/pull/7774)
+
+### ICE Fixes
+
+* [`implicit_hasher`]
+  [#7761](https://github.com/rust-lang/rust-clippy/pull/7761)
+
+### Others
+
+* Clippy now uses the 2021
+  [Edition!](https://www.youtube.com/watch?v=q0aNduqb2Ro)
+  [#7664](https://github.com/rust-lang/rust-clippy/pull/7664)
 
 ## Rust 1.56
 
-Current beta, release 2021-10-21
+Current stable, released 2021-10-21
 
 [74d1561...7bfc26e](https://github.com/rust-lang/rust-clippy/compare/74d1561...7bfc26e)
 
@@ -74,13 +225,9 @@ Current beta, release 2021-10-21
 * [`unnested_or_patterns`]: Removed `or_patterns` feature gate in the code
   example [#7507](https://github.com/rust-lang/rust-clippy/pull/7507)
 
-### New Lints
-
-* Renamed Lint: `if_let_some_result` is now called [`match_result_ok`]. Now also handles `while let` case.
-
 ## Rust 1.55
 
-Current stable, released 2021-09-09
+Released 2021-09-09
 
 [3ae8faf...74d1561](https://github.com/rust-lang/rust-clippy/compare/3ae8faf...74d1561)
 
@@ -2748,7 +2895,6 @@ Released 2018-09-13
 [`if_let_redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_redundant_pattern_matching
 [`if_not_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_not_else
 [`if_same_then_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_same_then_else
-[`if_then_panic`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic
 [`if_then_some_else_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none
 [`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond
 [`implicit_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_clone
@@ -2806,6 +2952,7 @@ Released 2018-09-13
 [`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal
 [`macro_use_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_use_imports
 [`main_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#main_recursion
+[`manual_assert`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert
 [`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn
 [`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter_map
 [`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map
@@ -2976,6 +3123,7 @@ Released 2018-09-13
 [`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
 [`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
+[`separated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/master/index.html#separated_literal_suffix
 [`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
 [`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse
 [`shadow_same`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_same
@@ -3000,6 +3148,7 @@ Released 2018-09-13
 [`string_extend_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_extend_chars
 [`string_from_utf8_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_from_utf8_as_bytes
 [`string_lit_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_as_bytes
+[`string_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_slice
 [`string_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_to_string
 [`strlen_on_c_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#strlen_on_c_strings
 [`struct_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools
@@ -3046,6 +3195,7 @@ Released 2018-09-13
 [`uninit_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_vec
 [`unit_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_arg
 [`unit_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_cmp
+[`unit_hash`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_hash
 [`unit_return_expecting_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_return_expecting_ord
 [`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast
 [`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map
index 4273fda4e640d5d9356a5d63f166db26224fc603..97ff31b4bc5a3181727c5d8230ea463a6c1c170a 100644 (file)
@@ -262,7 +262,9 @@ to be run inside the `rust` directory):
 2. Checkout the commit from the latest available nightly. You can get it using `rustup check`.
 3. Sync the changes to the rust-copy of Clippy to your Clippy fork:
     ```bash
-    # Make sure to change `your-github-name` to your github name in the following command
+    # Make sure to change `your-github-name` to your github name in the following command. Also be
+    # sure to either use a net-new branch, e.g. `sync-from-rust`, or delete the branch beforehand
+    # because changes cannot be fast forwarded
     git subtree push -P src/tools/clippy git@github.com:your-github-name/rust-clippy sync-from-rust
     ```
 
index ed7fb1440139f7d199f5632cb54525633c0d48a1..602877bb9d6831dfd824f6d0e8a4fdf143e96b59 100644 (file)
@@ -22,13 +22,13 @@ path = "src/driver.rs"
 
 [dependencies]
 clippy_lints = { version = "0.1", path = "clippy_lints" }
-semver = "0.11"
+semver = "1.0"
 rustc_tools_util = { version = "0.2", path = "rustc_tools_util" }
 tempfile = { version = "3.2", optional = true }
 
 [dev-dependencies]
-cargo_metadata = "0.12"
-compiletest_rs = { version = "0.7", features = ["tmp"] }
+cargo_metadata = "0.14"
+compiletest_rs = { version = "0.7.1", features = ["tmp"] }
 tester = "0.9"
 regex = "1.5"
 # This is used by the `collect-metadata` alias.
index 25320907bb492767f36da58f48e97d0b2d366477..43a478ee77db826975fcbda09202af1381a2981b 100644 (file)
@@ -42,7 +42,8 @@ pub fn create(pass: Option<&str>, lint_name: Option<&str>, category: Option<&str
     };
 
     create_lint(&lint, msrv).context("Unable to create lint implementation")?;
-    create_test(&lint).context("Unable to create a test for the new lint")
+    create_test(&lint).context("Unable to create a test for the new lint")?;
+    add_lint(&lint, msrv).context("Unable to add lint to clippy_lints/src/lib.rs")
 }
 
 fn create_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
@@ -80,6 +81,33 @@ fn create_project_layout<P: Into<PathBuf>>(lint_name: &str, location: P, case: &
     }
 }
 
+fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
+    let path = "clippy_lints/src/lib.rs";
+    let mut lib_rs = fs::read_to_string(path).context("reading")?;
+
+    let comment_start = lib_rs.find("// add lints here,").expect("Couldn't find comment");
+
+    let new_lint = if enable_msrv {
+        format!(
+            "store.register_{lint_pass}_pass(move || Box::new({module_name}::{camel_name}::new(msrv)));\n    ",
+            lint_pass = lint.pass,
+            module_name = lint.name,
+            camel_name = to_camel_case(lint.name),
+        )
+    } else {
+        format!(
+            "store.register_{lint_pass}_pass(|| Box::new({module_name}::{camel_name}));\n    ",
+            lint_pass = lint.pass,
+            module_name = lint.name,
+            camel_name = to_camel_case(lint.name),
+        )
+    };
+
+    lib_rs.insert_str(comment_start, &new_lint);
+
+    fs::write(path, lib_rs).context("writing")
+}
+
 fn write_file<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {
     fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {
         OpenOptions::new()
@@ -151,7 +179,6 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
     };
 
     let lint_name = lint.name;
-    let pass_name = lint.pass;
     let category = lint.category;
     let name_camel = to_camel_case(lint.name);
     let name_upper = lint_name.to_uppercase();
@@ -228,18 +255,14 @@ impl {pass_type}{pass_lifetimes} for {name_camel} {{
                     extract_msrv_attr!({context_import});
                 }}
 
-                // TODO: Register the lint pass in `clippy_lints/src/lib.rs`,
-                //       e.g. store.register_{pass_name}_pass(move || Box::new({module_name}::{name_camel}::new(msrv)));
                 // TODO: Add MSRV level to `clippy_utils/src/msrvs.rs` if needed.
                 // TODO: Add MSRV test to `tests/ui/min_rust_version_attr.rs`.
                 // TODO: Update msrv config comment in `clippy_lints/src/utils/conf.rs`
             "},
             pass_type = pass_type,
             pass_lifetimes = pass_lifetimes,
-            pass_name = pass_name,
             name_upper = name_upper,
             name_camel = name_camel,
-            module_name = lint_name,
             context_import = context_import,
         )
     } else {
@@ -248,16 +271,11 @@ impl {pass_type}{pass_lifetimes} for {name_camel} {{
                 declare_lint_pass!({name_camel} => [{name_upper}]);
 
                 impl {pass_type}{pass_lifetimes} for {name_camel} {{}}
-                //
-                // TODO: Register the lint pass in `clippy_lints/src/lib.rs`,
-                //       e.g. store.register_{pass_name}_pass(|| Box::new({module_name}::{name_camel}));
             "},
             pass_type = pass_type,
             pass_lifetimes = pass_lifetimes,
-            pass_name = pass_name,
             name_upper = name_upper,
             name_camel = name_camel,
-            module_name = lint_name,
         )
     });
 
index aaf9ac83d49005dad0df8a05de2dc7818dcedd06..281480b8d94914c2d1835a1fb7d2d1fb62620b18 100644 (file)
@@ -9,7 +9,7 @@ keywords = ["clippy", "lint", "plugin"]
 edition = "2021"
 
 [dependencies]
-cargo_metadata = "0.12"
+cargo_metadata = "0.14"
 clippy_utils = { path = "../clippy_utils" }
 if_chain = "1.0"
 itertools = "0.10"
@@ -21,7 +21,7 @@ serde_json = { version = "1.0", optional = true }
 toml = "0.5"
 unicode-normalization = "0.1"
 unicode-script = { version = "0.5", default-features = false }
-semver = "0.11"
+semver = "1.0"
 rustc-semver = "1.1"
 # NOTE: cargo requires serde feat in its url dep
 # see <https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864>
index 833ad122e0d4e20c46ae07f32c94157a4120f218..4af412ccaf35d7d0946429c5b997f9ae7081792e 100644 (file)
@@ -1,15 +1,88 @@
+use clippy_utils::consts::{constant, Constant};
 use clippy_utils::diagnostics::span_lint;
+use clippy_utils::expr_or_init;
 use clippy_utils::ty::is_isize_or_usize;
-use rustc_hir::Expr;
+use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, FloatTy, Ty};
 
 use super::{utils, CAST_POSSIBLE_TRUNCATION};
 
-pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
+fn constant_int(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<u128> {
+    if let Some((Constant::Int(c), _)) = constant(cx, cx.typeck_results(), expr) {
+        Some(c)
+    } else {
+        None
+    }
+}
+
+fn get_constant_bits(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<u64> {
+    constant_int(cx, expr).map(|c| u64::from(128 - c.leading_zeros()))
+}
+
+fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: bool) -> u64 {
+    match expr_or_init(cx, expr).kind {
+        ExprKind::Cast(inner, _) => apply_reductions(cx, nbits, inner, signed),
+        ExprKind::Block(block, _) => block.expr.map_or(nbits, |e| apply_reductions(cx, nbits, e, signed)),
+        ExprKind::Binary(op, left, right) => match op.node {
+            BinOpKind::Div => {
+                apply_reductions(cx, nbits, left, signed)
+                    - (if signed {
+                        0 // let's be conservative here
+                    } else {
+                        // by dividing by 1, we remove 0 bits, etc.
+                        get_constant_bits(cx, right).map_or(0, |b| b.saturating_sub(1))
+                    })
+            },
+            BinOpKind::Rem | BinOpKind::BitAnd => get_constant_bits(cx, right)
+                .unwrap_or(u64::max_value())
+                .min(apply_reductions(cx, nbits, left, signed)),
+            BinOpKind::Shr => {
+                apply_reductions(cx, nbits, left, signed)
+                    - constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))
+            },
+            _ => nbits,
+        },
+        ExprKind::MethodCall(method, _, [left, right], _) => {
+            if signed {
+                return nbits;
+            }
+            let max_bits = if method.ident.as_str() == "min" {
+                get_constant_bits(cx, right)
+            } else {
+                None
+            };
+            apply_reductions(cx, nbits, left, signed).min(max_bits.unwrap_or(u64::max_value()))
+        },
+        ExprKind::MethodCall(method, _, [_, lo, hi], _) => {
+            if method.ident.as_str() == "clamp" {
+                //FIXME: make this a diagnostic item
+                if let (Some(lo_bits), Some(hi_bits)) = (get_constant_bits(cx, lo), get_constant_bits(cx, hi)) {
+                    return lo_bits.max(hi_bits);
+                }
+            }
+            nbits
+        },
+        ExprKind::MethodCall(method, _, [_value], _) => {
+            if method.ident.name.as_str() == "signum" {
+                0 // do not lint if cast comes from a `signum` function
+            } else {
+                nbits
+            }
+        },
+        _ => nbits,
+    }
+}
+
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
     let msg = match (cast_from.is_integral(), cast_to.is_integral()) {
         (true, true) => {
-            let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx);
+            let from_nbits = apply_reductions(
+                cx,
+                utils::int_ty_to_nbits(cast_from, cx.tcx),
+                cast_expr,
+                cast_from.is_signed(),
+            );
             let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx);
 
             let (should_lint, suffix) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) {
index f0800c6a6f18f788bbb2804b20aaba1b8b362fc6..233abd178943e9bc20b2685c68fd55f03d46a9c3 100644 (file)
@@ -427,7 +427,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
             fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
             fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
             if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
-                cast_possible_truncation::check(cx, expr, cast_from, cast_to);
+                cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
                 cast_possible_wrap::check(cx, expr, cast_from, cast_to);
                 cast_precision_loss::check(cx, expr, cast_from, cast_to);
                 cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to);
index c604516742ce5a1a510862792bc48cb7fdb1b01e..9d8524ec91cc6e08f7c2ea056aabb58f3103e02e 100644 (file)
@@ -1,3 +1,6 @@
+// NOTE: if you add a deprecated lint in this file, please add a corresponding test in
+// tests/ui/deprecated.rs
+
 /// This struct fakes the `Lint` declaration that is usually created by `declare_lint!`. This
 /// enables the simple extraction of the metadata without changing the current deprecation
 /// declaration.
index 7825e5f6ed52e45f9f715c0cb2b93fd55a4fc9ca..ce59311c4aa96acac5154ce00f02e3d0a746fa99 100644 (file)
@@ -126,7 +126,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
                                 target_mut,
                             },
                         ));
-                    }
+                    },
                     _ => (),
                 }
             },
index 5511c3ea9b6889701a2dbdfaf015fdec0fa5b987..d4ba072807f8f891adb1de3f37b3327d5b9ea0eb 100644 (file)
@@ -1,16 +1,16 @@
 use clippy_utils::attrs::is_doc_hidden;
-use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_note};
-use clippy_utils::source::first_line_of_span;
+use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_sugg};
+use clippy_utils::source::{first_line_of_span, snippet_with_applicability};
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use clippy_utils::{is_entrypoint_fn, is_expn_of, match_panic_def_id, method_chain_args, return_ty};
 use if_chain::if_chain;
 use itertools::Itertools;
-use rustc_ast::ast::{Async, AttrKind, Attribute, FnKind, FnRetTy, ItemKind};
+use rustc_ast::ast::{Async, AttrKind, Attribute, Fn, FnRetTy, ItemKind};
 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::Handler;
+use rustc_errors::{Applicability, Handler};
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{AnonConst, Expr, ExprKind, QPath};
@@ -48,7 +48,7 @@
     /// content are not linted.
     ///
     /// In addition, when writing documentation comments, including `[]` brackets
-    /// inside a link text would trip the parser. Therfore, documenting link with
+    /// 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.
     ///
@@ -578,9 +578,12 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                     // text "http://example.com" by pulldown-cmark
                     continue;
                 }
-                headers.safety |= in_heading && text.trim() == "Safety";
-                headers.errors |= in_heading && text.trim() == "Errors";
-                headers.panics |= in_heading && text.trim() == "Panics";
+                let trimmed_text = text.trim();
+                headers.safety |= in_heading && trimmed_text == "Safety";
+                headers.safety |= in_heading && trimmed_text == "Implementation safety";
+                headers.safety |= in_heading && trimmed_text == "Implementation Safety";
+                headers.errors |= in_heading && trimmed_text == "Errors";
+                headers.panics |= in_heading && trimmed_text == "Panics";
                 if in_code {
                     if is_rust {
                         let edition = edition.unwrap_or_else(|| cx.tcx.sess.edition());
@@ -636,7 +639,7 @@ fn has_needless_main(code: String, edition: Edition) -> bool {
                             | ItemKind::ExternCrate(..)
                             | ItemKind::ForeignMod(..) => return false,
                             // We found a main function ...
-                            ItemKind::Fn(box FnKind(_, sig, _, Some(block))) if item.ident.name == sym::main => {
+                            ItemKind::Fn(box Fn { sig, body: Some(block), .. }) if item.ident.name == sym::main => {
                                 let is_async = matches!(sig.header.asyncness, Async::Yes { .. });
                                 let returns_nothing = match &sig.decl.output {
                                     FnRetTy::Default(..) => true,
@@ -686,10 +689,18 @@ fn check_text(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str
     for word in text.split(|c: char| c.is_whitespace() || c == '\'') {
         // Trim punctuation as in `some comment (see foo::bar).`
         //                                                   ^^
-        // Or even as in `_foo bar_` which is emphasized.
-        let word = word.trim_matches(|c: char| !c.is_alphanumeric());
+        // Or even as in `_foo bar_` which is emphasized. Also preserve `::` as a prefix/suffix.
+        let mut word = word.trim_matches(|c: char| !c.is_alphanumeric() && c != ':');
 
-        if valid_idents.contains(word) {
+        // Remove leading or trailing single `:` which may be part of a sentence.
+        if word.starts_with(':') && !word.starts_with("::") {
+            word = word.trim_start_matches(':');
+        }
+        if word.ends_with(':') && !word.ends_with("::") {
+            word = word.trim_end_matches(':');
+        }
+
+        if valid_idents.contains(word) || word.chars().all(|c| c == ':') {
             continue;
         }
 
@@ -744,17 +755,22 @@ fn has_hyphen(s: &str) -> bool {
         }
     }
 
-    // We assume that mixed-case words are not meant to be put inside bacticks. (Issue #2343)
+    // We assume that mixed-case words are not meant to be put inside backticks. (Issue #2343)
     if has_underscore(word) && has_hyphen(word) {
         return;
     }
 
     if has_underscore(word) || word.contains("::") || is_camel_case(word) {
-        span_lint(
+        let mut applicability = Applicability::MachineApplicable;
+
+        span_lint_and_sugg(
             cx,
             DOC_MARKDOWN,
             span,
-            &format!("you should put `{}` between ticks in the documentation", word),
+            "item in documentation is missing backticks",
+            "try",
+            format!("`{}`", snippet_with_applicability(cx, span, "..", &mut applicability)),
+            applicability,
         );
     }
 }
@@ -793,9 +809,9 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
 
         // check for `unwrap`
         if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
-            let reciever_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
-            if is_type_diagnostic_item(self.cx, reciever_ty, sym::Option)
-                || is_type_diagnostic_item(self.cx, reciever_ty, sym::Result)
+            let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
+            if is_type_diagnostic_item(self.cx, receiver_ty, sym::Option)
+                || is_type_diagnostic_item(self.cx, receiver_ty, sym::Result)
             {
                 self.panic_span = Some(expr.span);
             }
index ac6824672f66cbf90c13b7f7d9e6dfab2d009d4d..57fd24bd4f04d81ca9263a905b84b258a100ae59 100644 (file)
@@ -245,11 +245,14 @@ fn try_parse_contains(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Option<(Map
         ExprKind::MethodCall(
             _,
             _,
-            [map, Expr {
-                kind: ExprKind::AddrOf(_, _, key),
-                span: key_span,
-                ..
-            }],
+            [
+                map,
+                Expr {
+                    kind: ExprKind::AddrOf(_, _, key),
+                    span: key_span,
+                    ..
+                },
+            ],
             _,
         ) if key_span.ctxt() == expr.span.ctxt() => {
             let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
index 174260fabd228688c47943efa52d9cae07f84481..404b67c8f29f2817a9e6f58c3fc55d3b588075e4 100644 (file)
@@ -1,8 +1,8 @@
 //! lint on enum variants that are prefixed or suffixed by the same characters
 
-use clippy_utils::camel_case;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
 use clippy_utils::source::is_present_in_source;
+use clippy_utils::str_utils::{self, count_match_end, count_match_start};
 use rustc_hir::{EnumDef, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -117,26 +117,6 @@ pub fn new(threshold: u64, avoid_breaking_exported_api: bool) -> Self {
     MODULE_INCEPTION
 ]);
 
-/// Returns the number of chars that match from the start
-#[must_use]
-fn partial_match(pre: &str, name: &str) -> usize {
-    let mut name_iter = name.chars();
-    let _ = name_iter.next_back(); // make sure the name is never fully matched
-    pre.chars().zip(name_iter).take_while(|&(l, r)| l == r).count()
-}
-
-/// Returns the number of chars that match from the end
-#[must_use]
-fn partial_rmatch(post: &str, name: &str) -> usize {
-    let mut name_iter = name.chars();
-    let _ = name_iter.next(); // make sure the name is never fully matched
-    post.chars()
-        .rev()
-        .zip(name_iter.rev())
-        .take_while(|&(l, r)| l == r)
-        .count()
-}
-
 fn check_variant(
     cx: &LateContext<'_>,
     threshold: u64,
@@ -150,7 +130,7 @@ fn check_variant(
     }
     for var in def.variants {
         let name = var.ident.name.as_str();
-        if partial_match(item_name, &name) == item_name_chars
+        if count_match_start(item_name, &name).char_count == item_name_chars
             && name.chars().nth(item_name_chars).map_or(false, |c| !c.is_lowercase())
             && name.chars().nth(item_name_chars + 1).map_or(false, |c| !c.is_numeric())
         {
@@ -161,7 +141,7 @@ fn check_variant(
                 "variant name starts with the enum's name",
             );
         }
-        if partial_rmatch(item_name, &name) == item_name_chars {
+        if count_match_end(item_name, &name).char_count == item_name_chars {
             span_lint(
                 cx,
                 ENUM_VARIANT_NAMES,
@@ -171,14 +151,14 @@ fn check_variant(
         }
     }
     let first = &def.variants[0].ident.name.as_str();
-    let mut pre = &first[..camel_case::until(&*first)];
-    let mut post = &first[camel_case::from(&*first)..];
+    let mut pre = &first[..str_utils::camel_case_until(&*first).byte_index];
+    let mut post = &first[str_utils::camel_case_start(&*first).byte_index..];
     for var in def.variants {
         let name = var.ident.name.as_str();
 
-        let pre_match = partial_match(pre, &name);
+        let pre_match = count_match_start(pre, &name).byte_count;
         pre = &pre[..pre_match];
-        let pre_camel = camel_case::until(pre);
+        let pre_camel = str_utils::camel_case_until(pre).byte_index;
         pre = &pre[..pre_camel];
         while let Some((next, last)) = name[pre.len()..].chars().zip(pre.chars().rev()).next() {
             if next.is_numeric() {
@@ -186,18 +166,18 @@ fn check_variant(
             }
             if next.is_lowercase() {
                 let last = pre.len() - last.len_utf8();
-                let last_camel = camel_case::until(&pre[..last]);
-                pre = &pre[..last_camel];
+                let last_camel = str_utils::camel_case_until(&pre[..last]);
+                pre = &pre[..last_camel.byte_index];
             } else {
                 break;
             }
         }
 
-        let post_match = partial_rmatch(post, &name);
-        let post_end = post.len() - post_match;
+        let post_match = count_match_end(post, &name);
+        let post_end = post.len() - post_match.byte_count;
         post = &post[post_end..];
-        let post_camel = camel_case::from(post);
-        post = &post[post_camel..];
+        let post_camel = str_utils::camel_case_start(post);
+        post = &post[post_camel.byte_index..];
     }
     let (what, value) = match (pre.is_empty(), post.is_empty()) {
         (true, true) => return,
@@ -266,14 +246,16 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
                             );
                         }
                     }
-                    if item.vis.node.is_pub() {
-                        let matching = partial_match(mod_camel, &item_camel);
-                        let rmatching = partial_rmatch(mod_camel, &item_camel);
+                    // The `module_name_repetitions` lint should only trigger if the item has the module in its
+                    // name. Having the same name is accepted.
+                    if item.vis.node.is_pub() && item_camel.len() > mod_camel.len() {
+                        let matching = count_match_start(mod_camel, &item_camel);
+                        let rmatching = count_match_end(mod_camel, &item_camel);
                         let nchars = mod_camel.chars().count();
 
                         let is_word_beginning = |c: char| c == '_' || c.is_uppercase() || c.is_numeric();
 
-                        if matching == nchars {
+                        if matching.char_count == nchars {
                             match item_camel.chars().nth(nchars) {
                                 Some(c) if is_word_beginning(c) => span_lint(
                                     cx,
@@ -284,7 +266,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
                                 _ => (),
                             }
                         }
-                        if rmatching == nchars {
+                        if rmatching.char_count == nchars {
                             span_lint(
                                 cx,
                                 MODULE_NAME_REPETITIONS,
index 765a6c7585a20a6ee3b5f4d09bd6f5b0319396ab..9247343b52a5322f8c7ee09eec77de8b655ffcff 100644 (file)
@@ -169,13 +169,16 @@ fn check_inputs(cx: &LateContext<'_>, params: &[Param<'_>], call_args: &[Expr<'_
         }
         match *cx.typeck_results().expr_adjustments(arg) {
             [] => true,
-            [Adjustment {
-                kind: Adjust::Deref(None),
-                ..
-            }, Adjustment {
-                kind: Adjust::Borrow(AutoBorrow::Ref(_, mu2)),
-                ..
-            }] => {
+            [
+                Adjustment {
+                    kind: Adjust::Deref(None),
+                    ..
+                },
+                Adjustment {
+                    kind: Adjust::Borrow(AutoBorrow::Ref(_, mu2)),
+                    ..
+                },
+            ] => {
                 // re-borrow with the same mutability is allowed
                 let ty = cx.typeck_results().expr_ty(arg);
                 matches!(*ty.kind(), ty::Ref(.., mu1) if mu1 == mu2.into())
index 476e6d23f12151e869270de3c8265bc647993d25..09b6e20083889e863ac884636ad2c3b20f08db50 100644 (file)
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::in_macro;
-use rustc_ast::ast::{AssocItemKind, Extern, FnKind, FnSig, ImplKind, Item, ItemKind, TraitKind, Ty, TyKind};
+use rustc_ast::ast::{AssocItemKind, Extern, Fn, FnSig, Impl, Item, ItemKind, Trait, Ty, TyKind};
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{sym, Span};
@@ -162,17 +162,17 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
                     );
                 }
             },
-            ItemKind::Impl(box ImplKind {
+            ItemKind::Impl(box Impl {
                 of_trait: None, items, ..
             })
-            | ItemKind::Trait(box TraitKind(.., items)) => {
+            | ItemKind::Trait(box Trait { items, .. }) => {
                 for item in items {
-                    if let AssocItemKind::Fn(box FnKind(_, fn_sig, _, _)) = &item.kind {
-                        self.check_fn_sig(cx, fn_sig, item.span);
+                    if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
+                        self.check_fn_sig(cx, sig, item.span);
                     }
                 }
             },
-            ItemKind::Fn(box FnKind(_, fn_sig, _, _)) => self.check_fn_sig(cx, fn_sig, item.span),
+            ItemKind::Fn(box Fn { sig, .. }) => self.check_fn_sig(cx, sig, item.span),
             _ => (),
         }
     }
index c22f9d0e170326c79fbdd0df8cc2228b27822aaf..7169ac9ad6c5a50ce98062c8d1dcdaa465adea46 100644 (file)
@@ -49,15 +49,19 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 
         let mut applicability = Applicability::MachineApplicable;
         if format_args.value_args.is_empty() {
-            if_chain! {
-                if let [e] = &*format_args.format_string_parts;
-                if let ExprKind::Lit(lit) = &e.kind;
-                if let Some(s_src) = snippet_opt(cx, lit.span);
-                then {
-                    // Simulate macro expansion, converting {{ and }} to { and }.
-                    let s_expand = s_src.replace("{{", "{").replace("}}", "}");
-                    let sugg = format!("{}.to_string()", s_expand);
-                    span_useless_format(cx, call_site, sugg, applicability);
+            if format_args.format_string_parts.is_empty() {
+                span_useless_format_empty(cx, call_site, "String::new()".to_owned(), applicability);
+            } else {
+                if_chain! {
+                    if let [e] = &*format_args.format_string_parts;
+                    if let ExprKind::Lit(lit) = &e.kind;
+                    if let Some(s_src) = snippet_opt(cx, lit.span);
+                    then {
+                        // Simulate macro expansion, converting {{ and }} to { and }.
+                        let s_expand = s_src.replace("{{", "{").replace("}}", "}");
+                        let sugg = format!("{}.to_string()", s_expand);
+                        span_useless_format(cx, call_site, sugg, applicability);
+                    }
                 }
             }
         } else if let [value] = *format_args.value_args {
@@ -89,6 +93,18 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
     }
 }
 
+fn span_useless_format_empty(cx: &LateContext<'_>, span: Span, sugg: String, applicability: Applicability) {
+    span_lint_and_sugg(
+        cx,
+        USELESS_FORMAT,
+        span,
+        "useless use of `format!`",
+        "consider using `String::new()`",
+        sugg,
+        applicability,
+    );
+}
+
 fn span_useless_format(cx: &LateContext<'_>, span: Span, sugg: String, applicability: Applicability) {
     span_lint_and_sugg(
         cx,
index 3ce91d421baca8bc9efe4b9ae760c522c7f288ca..ac938156237bf8f090feb281558f6301b685e6b0 100644 (file)
@@ -2,9 +2,9 @@
 //! on the condition
 
 use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_ast::ast::{BinOpKind, Expr, ExprKind, UnOp};
-use rustc_lint::{EarlyContext, EarlyLintPass};
-use rustc_middle::lint::in_external_macro;
+use clippy_utils::is_else_clause;
+use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
 declare_clippy_lint! {
 
 declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]);
 
-impl EarlyLintPass for IfNotElse {
-    fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) {
-        if in_external_macro(cx.sess, item.span) {
+impl LateLintPass<'_> for IfNotElse {
+    fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
+        // While loops will be desugared to ExprKind::If. This will cause the lint to fire.
+        // To fix this, return early if this span comes from a macro or desugaring.
+        if item.span.from_expansion() {
             return;
         }
-        if let ExprKind::If(ref cond, _, Some(ref els)) = item.kind {
+        if let ExprKind::If(cond, _, Some(els)) = item.kind {
             if let ExprKind::Block(..) = els.kind {
-                match cond.kind {
+                // Disable firing the lint in "else if" expressions.
+                if is_else_clause(cx.tcx, item) {
+                    return;
+                }
+
+                match cond.peel_drop_temps().kind {
                     ExprKind::Unary(UnOp::Not, _) => {
                         span_lint_and_help(
                             cx,
diff --git a/src/tools/clippy/clippy_lints/src/if_then_panic.rs b/src/tools/clippy/clippy_lints/src/if_then_panic.rs
deleted file mode 100644 (file)
index e8cea55..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::higher::PanicExpn;
-use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{is_expn_of, sugg};
-use rustc_errors::Applicability;
-use rustc_hir::{Block, Expr, ExprKind, StmtKind, UnOp};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-
-declare_clippy_lint! {
-    /// ### 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
-    /// ```rust
-    /// let sad_people: Vec<&str> = vec![];
-    /// if !sad_people.is_empty() {
-    ///     panic!("there are sad people: {:?}", sad_people);
-    /// }
-    /// ```
-    /// Use instead:
-    /// ```rust
-    /// let sad_people: Vec<&str> = vec![];
-    /// assert!(sad_people.is_empty(), "there are sad people: {:?}", sad_people);
-    /// ```
-    pub IF_THEN_PANIC,
-    style,
-    "`panic!` and only a `panic!` in `if`-then statement"
-}
-
-declare_lint_pass!(IfThenPanic => [IF_THEN_PANIC]);
-
-impl LateLintPass<'_> for IfThenPanic {
-    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
-        if_chain! {
-            if let Expr {
-                kind: ExprKind:: If(cond, Expr {
-                    kind: ExprKind::Block(
-                        Block {
-                            stmts: [stmt],
-                            ..
-                        },
-                        _),
-                    ..
-                }, None),
-                ..
-            } = &expr;
-            if is_expn_of(stmt.span, "panic").is_some();
-            if !matches!(cond.kind, ExprKind::Let(_, _, _));
-            if let StmtKind::Semi(semi) = stmt.kind;
-            if !cx.tcx.sess.source_map().is_multiline(cond.span);
-
-            then {
-                let span = if let Some(panic_expn) = PanicExpn::parse(semi) {
-                    match *panic_expn.format_args.value_args {
-                        [] => panic_expn.format_args.format_string_span,
-                        [.., last] => panic_expn.format_args.format_string_span.to(last.span),
-                    }
-                } else {
-                    if_chain! {
-                        if let ExprKind::Block(block, _) = semi.kind;
-                        if let Some(init) = block.expr;
-                        if let ExprKind::Call(_, [format_args]) = init.kind;
-
-                        then {
-                            format_args.span
-                        } else {
-                            return
-                        }
-                    }
-                };
-                let mut applicability = Applicability::MachineApplicable;
-                let sugg = snippet_with_applicability(cx, span, "..", &mut applicability);
-                let cond_sugg = if let ExprKind::DropTemps(e, ..) = cond.kind {
-                    if let Expr{kind: ExprKind::Unary(UnOp::Not, not_expr), ..} = e {
-                         sugg::Sugg::hir_with_applicability(cx, not_expr, "..", &mut applicability).maybe_par().to_string()
-                    } else {
-                       format!("!{}", sugg::Sugg::hir_with_applicability(cx, e, "..", &mut applicability).maybe_par())
-                    }
-                } else {
-                   format!("!{}", sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par())
-                };
-
-                span_lint_and_sugg(
-                    cx,
-                    IF_THEN_PANIC,
-                    expr.span,
-                    "only a `panic!` in `if`-then statement",
-                    "try",
-                    format!("assert!({}, {});", cond_sugg, sugg),
-                    Applicability::MachineApplicable,
-                );
-            }
-        }
-    }
-}
index 49b69dd072a21352da51d21d4eb1a4c0bee2778f..6850e0c34767cb0864a002b5ce498c3cc157c5a8 100644 (file)
@@ -89,7 +89,7 @@ fn check_binop(cx: &EarlyContext<'_>, binop: BinOpKind, lhs: &Expr, rhs: &Expr)
                     },
                     _ => None,
                 }
-            }
+            },
             // case where `x + 1 <= ...` or `1 + x <= ...`
             (BinOpKind::Le, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _)
                 if lhskind.node == BinOpKind::Add =>
@@ -104,7 +104,7 @@ fn check_binop(cx: &EarlyContext<'_>, binop: BinOpKind, lhs: &Expr, rhs: &Expr)
                     },
                     _ => None,
                 }
-            }
+            },
             // case where `... >= y - 1` or `... >= -1 + y`
             (BinOpKind::Le, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs)) => {
                 match (rhskind.node, &rhslhs.kind, &rhsrhs.kind) {
index b1f70b30c12cf1c1605b09ac48cf9fc9891fad3e..82438d85c7a3a353128134b0736e587c4dc9d5f1 100644 (file)
@@ -1,5 +1,3 @@
-use std::cmp::Ordering;
-
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
@@ -7,11 +5,11 @@
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::Span;
 
+use clippy_utils::comparisons;
 use clippy_utils::comparisons::Rel;
-use clippy_utils::consts::{constant, Constant};
+use clippy_utils::consts::{constant_full_int, FullInt};
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::source::snippet;
-use clippy_utils::{comparisons, sext};
 
 declare_clippy_lint! {
     /// ### What it does
 
 declare_lint_pass!(InvalidUpcastComparisons => [INVALID_UPCAST_COMPARISONS]);
 
-#[derive(Copy, Clone, Debug, Eq)]
-enum FullInt {
-    S(i128),
-    U(u128),
-}
-
-impl FullInt {
-    #[allow(clippy::cast_sign_loss)]
-    #[must_use]
-    fn cmp_s_u(s: i128, u: u128) -> Ordering {
-        if s < 0 {
-            Ordering::Less
-        } else if u > (i128::MAX as u128) {
-            Ordering::Greater
-        } else {
-            (s as u128).cmp(&u)
-        }
-    }
-}
-
-impl PartialEq for FullInt {
-    #[must_use]
-    fn eq(&self, other: &Self) -> bool {
-        self.partial_cmp(other).expect("`partial_cmp` only returns `Some(_)`") == Ordering::Equal
-    }
-}
-
-impl PartialOrd for FullInt {
-    #[must_use]
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        Some(match (self, other) {
-            (&Self::S(s), &Self::S(o)) => s.cmp(&o),
-            (&Self::U(s), &Self::U(o)) => s.cmp(&o),
-            (&Self::S(s), &Self::U(o)) => Self::cmp_s_u(s, o),
-            (&Self::U(s), &Self::S(o)) => Self::cmp_s_u(o, s).reverse(),
-        })
-    }
-}
-
-impl Ord for FullInt {
-    #[must_use]
-    fn cmp(&self, other: &Self) -> Ordering {
-        self.partial_cmp(other)
-            .expect("`partial_cmp` for FullInt can never return `None`")
-    }
-}
-
 fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<(FullInt, FullInt)> {
     if let ExprKind::Cast(cast_exp, _) = expr.kind {
         let pre_cast_ty = cx.typeck_results().expr_ty(cast_exp);
@@ -118,19 +69,6 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_>, expr: &'a Expr<'_>) ->
     }
 }
 
-fn node_as_const_fullint<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<FullInt> {
-    let val = constant(cx, cx.typeck_results(), expr)?.0;
-    if let Constant::Int(const_int) = val {
-        match *cx.typeck_results().expr_ty(expr).kind() {
-            ty::Int(ity) => Some(FullInt::S(sext(cx.tcx, const_int, ity))),
-            ty::Uint(_) => Some(FullInt::U(const_int)),
-            _ => None,
-        }
-    } else {
-        None
-    }
-}
-
 fn err_upcast_comparison(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, always: bool) {
     if let ExprKind::Cast(cast_val, _) = expr.kind {
         span_lint(
@@ -156,7 +94,7 @@ fn upcast_comparison_bounds_err<'tcx>(
     invert: bool,
 ) {
     if let Some((lb, ub)) = lhs_bounds {
-        if let Some(norm_rhs_val) = node_as_const_fullint(cx, rhs) {
+        if let Some(norm_rhs_val) = constant_full_int(cx, cx.typeck_results(), rhs) {
             if rel == Rel::Eq || rel == Rel::Ne {
                 if norm_rhs_val < lb || norm_rhs_val > ub {
                     err_upcast_comparison(cx, span, lhs, rel == Rel::Ne);
index c949ee23ecc7a94858ce40214e496a881c8a08fd..15edb79d36c24d613653e870f38dc66ff94ca3e3 100644 (file)
@@ -76,7 +76,6 @@
     LintId::of(get_last_with_len::GET_LAST_WITH_LEN),
     LintId::of(identity_op::IDENTITY_OP),
     LintId::of(if_let_mutex::IF_LET_MUTEX),
-    LintId::of(if_then_panic::IF_THEN_PANIC),
     LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
     LintId::of(infinite_iter::INFINITE_ITER),
     LintId::of(inherent_to_string::INHERENT_TO_STRING),
     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(non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY),
     LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
     LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
     LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
     LintId::of(undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
     LintId::of(unicode::INVISIBLE_CHARACTERS),
     LintId::of(uninit_vec::UNINIT_VEC),
+    LintId::of(unit_hash::UNIT_HASH),
     LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
     LintId::of(unit_types::UNIT_ARG),
     LintId::of(unit_types::UNIT_CMP),
index ff56a6081fb57f8cbc44c08f785b2981900147f4..4217fd3a3ea72c04af802f688f39d34f1f501c7a 100644 (file)
@@ -64,6 +64,7 @@
     LintId::of(undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
     LintId::of(unicode::INVISIBLE_CHARACTERS),
     LintId::of(uninit_vec::UNINIT_VEC),
+    LintId::of(unit_hash::UNIT_HASH),
     LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
     LintId::of(unit_types::UNIT_CMP),
     LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
index e8dd3708c8ed406dc3f92b6bff81332d49d9757e..2cb86418e3cb5df2cc946ba79a8095fe48de7be0 100644 (file)
     identity_op::IDENTITY_OP,
     if_let_mutex::IF_LET_MUTEX,
     if_not_else::IF_NOT_ELSE,
-    if_then_panic::IF_THEN_PANIC,
     if_then_some_else_none::IF_THEN_SOME_ELSE_NONE,
     implicit_hasher::IMPLICIT_HASHER,
     implicit_return::IMPLICIT_RETURN,
     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_map::MANUAL_MAP,
     manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE,
     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,
     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,
     strlen_on_c_strings::STRLEN_ON_C_STRINGS,
     unicode::NON_ASCII_LITERAL,
     unicode::UNICODE_NOT_NFC,
     uninit_vec::UNINIT_VEC,
+    unit_hash::UNIT_HASH,
     unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
     unit_types::LET_UNIT_VALUE,
     unit_types::UNIT_ARG,
index 1e54482a8dafdc7b5f73d3798f5fd5a04864cc2b..44c75a11eec08111c17db1d2ca03862a17e3a6a3 100644 (file)
@@ -17,7 +17,6 @@
     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_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(path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE),
index 268349d28481182fdbac33fe20ba0d0312430fbf..404ca20b5abc62bf05adf9b474a19c0990048e00 100644 (file)
@@ -48,6 +48,7 @@
     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_ok_or::MANUAL_OK_OR),
     LintId::of(match_on_vec_items::MATCH_ON_VEC_ITEMS),
     LintId::of(matches::MATCH_BOOL),
@@ -65,7 +66,6 @@
     LintId::of(methods::MAP_UNWRAP_OR),
     LintId::of(misc::FLOAT_CMP),
     LintId::of(misc::USED_UNDERSCORE_BINDING),
-    LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
     LintId::of(mut_mut::MUT_MUT),
     LintId::of(needless_bitwise_bool::NEEDLESS_BITWISE_BOOL),
     LintId::of(needless_borrow::REF_BINDING_TO_REFERENCE),
@@ -88,7 +88,6 @@
     LintId::of(transmute::TRANSMUTE_PTR_TO_PTR),
     LintId::of(types::LINKEDLIST),
     LintId::of(types::OPTION_OPTION),
-    LintId::of(unicode::NON_ASCII_LITERAL),
     LintId::of(unicode::UNICODE_NOT_NFC),
     LintId::of(unit_types::LET_UNIT_VALUE),
     LintId::of(unnecessary_wraps::UNNECESSARY_WRAPS),
index 3d68a6e900958fbcfcd886007abc15c468b5ceef..eab389a9bd892089b94a10c749b2837d3916b25c 100644 (file)
@@ -35,7 +35,9 @@
     LintId::of(methods::GET_UNWRAP),
     LintId::of(methods::UNWRAP_USED),
     LintId::of(misc::FLOAT_CMP_CONST),
+    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(shadow::SHADOW_SAME),
     LintId::of(shadow::SHADOW_UNRELATED),
     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(verbose_file_reads::VERBOSE_FILE_READS),
index a39c111c5742340d1a0d59723da29d722c8271c6..744880bda3e69c2a83763dc5d9b1a38ade7b6ec5 100644 (file)
@@ -27,7 +27,6 @@
     LintId::of(functions::DOUBLE_MUST_USE),
     LintId::of(functions::MUST_USE_UNIT),
     LintId::of(functions::RESULT_UNIT_ERR),
-    LintId::of(if_then_panic::IF_THEN_PANIC),
     LintId::of(inherent_to_string::INHERENT_TO_STRING),
     LintId::of(len_zero::COMPARISON_TO_EMPTY),
     LintId::of(len_zero::LEN_WITHOUT_IS_EMPTY),
index 8859787fbc830c97e7b34a0ee21e053d586bcdcf..a3f964d1580428f92230f26f169586fd86e25504 100644 (file)
@@ -15,6 +15,7 @@
     LintId::of(loops::MUT_RANGE_BOUND),
     LintId::of(methods::SUSPICIOUS_MAP),
     LintId::of(mut_key::MUTABLE_KEY_TYPE),
+    LintId::of(non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY),
     LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
     LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
 ])
index ed7e827702395dc72336e5f2adaf24709324e6ac..7174d0a082e0f7627f062180d10f5ef47c170a4b 100644 (file)
@@ -228,7 +228,6 @@ macro_rules! declare_clippy_lint {
 mod identity_op;
 mod if_let_mutex;
 mod if_not_else;
-mod if_then_panic;
 mod if_then_some_else_none;
 mod implicit_hasher;
 mod implicit_return;
@@ -255,6 +254,7 @@ macro_rules! declare_clippy_lint {
 mod loops;
 mod macro_use;
 mod main_recursion;
+mod manual_assert;
 mod manual_async_fn;
 mod manual_map;
 mod manual_non_exhaustive;
@@ -364,6 +364,7 @@ macro_rules! declare_clippy_lint {
 mod undropped_manually_drops;
 mod unicode;
 mod uninit_vec;
+mod unit_hash;
 mod unit_return_expecting_ord;
 mod unit_types;
 mod unnamed_address;
@@ -522,6 +523,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| Box::new(collapsible_match::CollapsibleMatch));
     store.register_late_pass(|| Box::new(unicode::Unicode));
     store.register_late_pass(|| Box::new(uninit_vec::UninitVec));
+    store.register_late_pass(|| Box::new(unit_hash::UnitHash));
     store.register_late_pass(|| Box::new(unit_return_expecting_ord::UnitReturnExpectingOrd));
     store.register_late_pass(|| Box::new(strings::StringAdd));
     store.register_late_pass(|| Box::new(implicit_return::ImplicitReturn));
@@ -666,7 +668,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_early_pass(|| Box::new(double_parens::DoubleParens));
     store.register_late_pass(|| Box::new(to_string_in_display::ToStringInDisplay::new()));
     store.register_early_pass(|| Box::new(unsafe_removed_from_name::UnsafeNameRemoval));
-    store.register_early_pass(|| Box::new(if_not_else::IfNotElse));
     store.register_early_pass(|| Box::new(else_if_without_else::ElseIfWithoutElse));
     store.register_early_pass(|| Box::new(int_plus_one::IntPlusOne));
     store.register_early_pass(|| Box::new(formatting::Formatting));
@@ -720,6 +721,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     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));
+    store.register_late_pass(|| Box::new(if_not_else::IfNotElse));
     store.register_late_pass(|| Box::new(equatable_if_let::PatternEquality));
     store.register_late_pass(|| Box::new(mut_mutex_lock::MutMutexLock));
     store.register_late_pass(|| Box::new(match_on_vec_items::MatchOnVecItems));
@@ -770,14 +772,14 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move || Box::new(self_named_constructors::SelfNamedConstructors));
     store.register_late_pass(move || Box::new(feature_name::FeatureName));
     store.register_late_pass(move || Box::new(iter_not_returning_iterator::IterNotReturningIterator));
-    store.register_late_pass(move || Box::new(if_then_panic::IfThenPanic));
+    store.register_late_pass(move || Box::new(manual_assert::ManualAssert));
     let enable_raw_pointer_heuristic_for_send = conf.enable_raw_pointer_heuristic_for_send;
     store.register_late_pass(move || Box::new(non_send_fields_in_send_ty::NonSendFieldInSendTy::new(enable_raw_pointer_heuristic_for_send)));
     store.register_late_pass(move || Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks::default()));
     store.register_late_pass(|| Box::new(match_str_case_mismatch::MatchStrCaseMismatch));
     store.register_late_pass(move || Box::new(format_args::FormatArgs));
     store.register_late_pass(|| Box::new(trailing_empty_array::TrailingEmptyArray));
-
+    // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
 #[rustfmt::skip]
@@ -828,6 +830,7 @@ fn register_removed_non_tool_lints(store: &mut rustc_lint::LintStore) {
 ///
 /// Used in `./src/driver.rs`.
 pub fn register_renamed(ls: &mut rustc_lint::LintStore) {
+    // NOTE: when renaming a lint, add a corresponding test to tests/ui/rename.rs
     ls.register_renamed("clippy::stutter", "clippy::module_name_repetitions");
     ls.register_renamed("clippy::new_without_default_derive", "clippy::new_without_default");
     ls.register_renamed("clippy::cyclomatic_complexity", "clippy::cognitive_complexity");
index e5e6f8d25cc11143878512361a1a9d9f5672cb99..cb0b96e0652e53b1115b238a63713907c8a7fa04 100644 (file)
@@ -378,11 +378,15 @@ fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>, tbm: Tra
 
     fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
         match ty.kind {
-            TyKind::OpaqueDef(item, _) => {
+            TyKind::OpaqueDef(item, bounds) => {
                 let map = self.cx.tcx.hir();
                 let item = map.item(item);
                 walk_item(self, item);
                 walk_ty(self, ty);
+                self.lts.extend(bounds.iter().filter_map(|bound| match bound {
+                    GenericArg::Lifetime(l) => Some(RefLt::Named(l.name.ident().name)),
+                    _ => None,
+                }));
             },
             TyKind::BareFn(&BareFnTy { decl, .. }) => {
                 let mut sub_visitor = RefVisitor::new(self.cx);
index 2f7360210ba4de7918204c49434a6cf0a5ecd8f3..f9f515cc40a0fbdd120af9de1358d4e92ba66ce7 100644 (file)
@@ -338,7 +338,7 @@ pub(super) fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applic
                     sugg::Sugg::hir_with_applicability(cx, arg_inner, "_", applic_ref).maybe_par(),
                     meth_name,
                 )
-            }
+            },
             _ => format!(
                 "{}.into_iter()",
                 sugg::Sugg::hir_with_applicability(cx, arg, "_", applic_ref).maybe_par()
diff --git a/src/tools/clippy/clippy_lints/src/manual_assert.rs b/src/tools/clippy/clippy_lints/src/manual_assert.rs
new file mode 100644 (file)
index 0000000..e55aa3f
--- /dev/null
@@ -0,0 +1,100 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::higher::PanicExpn;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::{is_expn_of, sugg};
+use rustc_errors::Applicability;
+use rustc_hir::{Block, Expr, ExprKind, StmtKind, UnOp};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+    /// ### 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
+    /// ```rust
+    /// let sad_people: Vec<&str> = vec![];
+    /// if !sad_people.is_empty() {
+    ///     panic!("there are sad people: {:?}", sad_people);
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// let sad_people: Vec<&str> = vec![];
+    /// assert!(sad_people.is_empty(), "there are sad people: {:?}", sad_people);
+    /// ```
+    pub MANUAL_ASSERT,
+    pedantic,
+    "`panic!` and only a `panic!` in `if`-then statement"
+}
+
+declare_lint_pass!(ManualAssert => [MANUAL_ASSERT]);
+
+impl LateLintPass<'_> for ManualAssert {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        if_chain! {
+            if let Expr {
+                kind: ExprKind:: If(cond, Expr {
+                    kind: ExprKind::Block(
+                        Block {
+                            stmts: [stmt],
+                            ..
+                        },
+                        _),
+                    ..
+                }, None),
+                ..
+            } = &expr;
+            if is_expn_of(stmt.span, "panic").is_some();
+            if !matches!(cond.kind, ExprKind::Let(_, _, _));
+            if let StmtKind::Semi(semi) = stmt.kind;
+            if !cx.tcx.sess.source_map().is_multiline(cond.span);
+
+            then {
+                let call = if_chain! {
+                    if let ExprKind::Block(block, _) = semi.kind;
+                    if let Some(init) = block.expr;
+                    then {
+                        init
+                    } else {
+                        semi
+                    }
+                };
+                let span = if let Some(panic_expn) = PanicExpn::parse(call) {
+                    match *panic_expn.format_args.value_args {
+                        [] => panic_expn.format_args.format_string_span,
+                        [.., last] => panic_expn.format_args.format_string_span.to(last.span),
+                    }
+                } else if let ExprKind::Call(_, [format_args]) = call.kind {
+                    format_args.span
+                } else {
+                    return
+                };
+                let mut applicability = Applicability::MachineApplicable;
+                let sugg = snippet_with_applicability(cx, span, "..", &mut applicability);
+                let cond_sugg = if let ExprKind::DropTemps(e, ..) = cond.kind {
+                    if let Expr{kind: ExprKind::Unary(UnOp::Not, not_expr), ..} = e {
+                         sugg::Sugg::hir_with_applicability(cx, not_expr, "..", &mut applicability).maybe_par().to_string()
+                    } else {
+                       format!("!{}", sugg::Sugg::hir_with_applicability(cx, e, "..", &mut applicability).maybe_par())
+                    }
+                } else {
+                   format!("!{}", sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par())
+                };
+
+                span_lint_and_sugg(
+                    cx,
+                    MANUAL_ASSERT,
+                    expr.span,
+                    "only a `panic!` in `if`-then statement",
+                    "try",
+                    format!("assert!({}, {});", cond_sugg, sugg),
+                    Applicability::MachineApplicable,
+                );
+            }
+        }
+    }
+}
index a83f38e3d516e5c74c345cc2de119f57468710e2..f501593c5187e36e99b823f0a1a6919df425bc86 100644 (file)
@@ -127,10 +127,10 @@ fn get_case_method(segment_ident_str: &str) -> Option<CaseMethod> {
 
 fn verify_case<'a>(case_method: &'a CaseMethod, arms: &'a [Arm<'_>]) -> Option<(Span, SymbolStr)> {
     let case_check = match case_method {
-        CaseMethod::LowerCase => |input: &str| -> bool { input.chars().all(char::is_lowercase) },
-        CaseMethod::AsciiLowerCase => |input: &str| -> bool { input.chars().all(|c| matches!(c, 'a'..='z')) },
-        CaseMethod::UpperCase => |input: &str| -> bool { input.chars().all(char::is_uppercase) },
-        CaseMethod::AsciiUppercase => |input: &str| -> bool { input.chars().all(|c| matches!(c, 'A'..='Z')) },
+        CaseMethod::LowerCase => |input: &str| -> bool { input.chars().all(|c| c.to_lowercase().next() == Some(c)) },
+        CaseMethod::AsciiLowerCase => |input: &str| -> bool { !input.chars().any(|c| c.is_ascii_uppercase()) },
+        CaseMethod::UpperCase => |input: &str| -> bool { input.chars().all(|c| c.to_uppercase().next() == Some(c)) },
+        CaseMethod::AsciiUppercase => |input: &str| -> bool { !input.chars().any(|c| c.is_ascii_lowercase()) },
     };
 
     for arm in arms {
@@ -153,7 +153,7 @@ fn verify_case<'a>(case_method: &'a CaseMethod, arms: &'a [Arm<'_>]) -> Option<(
 
 fn lint(cx: &LateContext<'_>, case_method: &CaseMethod, bad_case_span: Span, bad_case_str: &str) {
     let (method_str, suggestion) = match case_method {
-        CaseMethod::LowerCase => ("to_lower_case", bad_case_str.to_lowercase()),
+        CaseMethod::LowerCase => ("to_lowercase", bad_case_str.to_lowercase()),
         CaseMethod::AsciiLowerCase => ("to_ascii_lowercase", bad_case_str.to_ascii_lowercase()),
         CaseMethod::UpperCase => ("to_uppercase", bad_case_str.to_uppercase()),
         CaseMethod::AsciiUppercase => ("to_ascii_uppercase", bad_case_str.to_ascii_uppercase()),
index b643fba5d328865baded5f1192cca02fa6ae979a..eb311983b29276ebf0b21b35ed9e0dcc46750af3 100644 (file)
@@ -1,4 +1,4 @@
-use clippy_utils::consts::{constant, miri_to_const, Constant};
+use clippy_utils::consts::{constant, constant_full_int, miri_to_const, FullInt};
 use clippy_utils::diagnostics::{
     multispan_sugg, span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then,
 };
@@ -930,9 +930,8 @@ fn check_match_bool(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr:
 fn check_overlapping_arms<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) {
     if arms.len() >= 2 && cx.typeck_results().expr_ty(ex).is_integral() {
         let ranges = all_ranges(cx, arms, cx.typeck_results().expr_ty(ex));
-        let type_ranges = type_ranges(&ranges);
-        if !type_ranges.is_empty() {
-            if let Some((start, end)) = overlapping(&type_ranges) {
+        if !ranges.is_empty() {
+            if let Some((start, end)) = overlapping(&ranges) {
                 span_lint_and_note(
                     cx,
                     MATCH_OVERLAPPING_ARM,
@@ -968,8 +967,7 @@ fn check_wild_err_arm<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm
                     }
                     if_chain! {
                         if matching_wild;
-                        if let ExprKind::Block(block, _) = arm.body.kind;
-                        if is_panic_block(block);
+                        if is_panic_call(arm.body);
                         then {
                             // `Err(_)` or `Err(_e)` arm with `panic!` found
                             span_lint_and_note(cx,
@@ -1172,14 +1170,19 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
 }
 
 // If the block contains only a `panic!` macro (as expression or statement)
-fn is_panic_block(block: &Block<'_>) -> bool {
-    match (&block.expr, block.stmts.len(), block.stmts.first()) {
-        (&Some(exp), 0, _) => is_expn_of(exp.span, "panic").is_some() && is_expn_of(exp.span, "unreachable").is_none(),
-        (&None, 1, Some(stmt)) => {
-            is_expn_of(stmt.span, "panic").is_some() && is_expn_of(stmt.span, "unreachable").is_none()
-        },
-        _ => false,
-    }
+fn is_panic_call(expr: &Expr<'_>) -> bool {
+    // Unwrap any wrapping blocks
+    let span = if let ExprKind::Block(block, _) = expr.kind {
+        match (&block.expr, block.stmts.len(), block.stmts.first()) {
+            (&Some(exp), 0, _) => exp.span,
+            (&None, 1, Some(stmt)) => stmt.span,
+            _ => return false,
+        }
+    } else {
+        expr.span
+    };
+
+    is_expn_of(span, "panic").is_some() && is_expn_of(span, "unreachable").is_none()
 }
 
 fn check_match_ref_pats<'a, 'b, I>(cx: &LateContext<'_>, ex: &Expr<'_>, pats: I, expr: &Expr<'_>)
@@ -1601,7 +1604,7 @@ fn opt_parent_let<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<&'a Local<'
 }
 
 /// Gets all arms that are unbounded `PatRange`s.
-fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>) -> Vec<SpannedRange<Constant>> {
+fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>) -> Vec<SpannedRange<FullInt>> {
     arms.iter()
         .filter_map(|arm| {
             if let Arm { pat, guard: None, .. } = *arm {
@@ -1614,21 +1617,25 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
                         Some(rhs) => constant(cx, cx.typeck_results(), rhs)?.0,
                         None => miri_to_const(ty.numeric_max_val(cx.tcx)?)?,
                     };
-                    let rhs = match range_end {
-                        RangeEnd::Included => Bound::Included(rhs),
-                        RangeEnd::Excluded => Bound::Excluded(rhs),
+
+                    let lhs_val = lhs.int_value(cx, ty)?;
+                    let rhs_val = rhs.int_value(cx, ty)?;
+
+                    let rhs_bound = match range_end {
+                        RangeEnd::Included => Bound::Included(rhs_val),
+                        RangeEnd::Excluded => Bound::Excluded(rhs_val),
                     };
                     return Some(SpannedRange {
                         span: pat.span,
-                        node: (lhs, rhs),
+                        node: (lhs_val, rhs_bound),
                     });
                 }
 
                 if let PatKind::Lit(value) = pat.kind {
-                    let value = constant(cx, cx.typeck_results(), value)?.0;
+                    let value = constant_full_int(cx, cx.typeck_results(), value)?;
                     return Some(SpannedRange {
                         span: pat.span,
-                        node: (value.clone(), Bound::Included(value)),
+                        node: (value, Bound::Included(value)),
                     });
                 }
             }
@@ -1643,32 +1650,6 @@ pub struct SpannedRange<T> {
     pub node: (T, Bound<T>),
 }
 
-type TypedRanges = Vec<SpannedRange<u128>>;
-
-/// Gets all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway
-/// and other types than
-/// `Uint` and `Int` probably don't make sense.
-fn type_ranges(ranges: &[SpannedRange<Constant>]) -> TypedRanges {
-    ranges
-        .iter()
-        .filter_map(|range| match range.node {
-            (Constant::Int(start), Bound::Included(Constant::Int(end))) => Some(SpannedRange {
-                span: range.span,
-                node: (start, Bound::Included(end)),
-            }),
-            (Constant::Int(start), Bound::Excluded(Constant::Int(end))) => Some(SpannedRange {
-                span: range.span,
-                node: (start, Bound::Excluded(end)),
-            }),
-            (Constant::Int(start), Bound::Unbounded) => Some(SpannedRange {
-                span: range.span,
-                node: (start, Bound::Unbounded),
-            }),
-            _ => None,
-        })
-        .collect()
-}
-
 // Checks if arm has the form `None => None`
 fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
     matches!(arm.pat.kind, PatKind::Path(ref qpath) if is_lang_ctor(cx, qpath, OptionNone))
index 1a32af5dc7a386fdd5e03c3832e8c105d6fc47f8..b4dacb2580c313fbc366aae7b251facfbdda215e 100644 (file)
@@ -85,7 +85,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol,
                     if expr.hir_id == self_arg.hir_id && ty != cx.typeck_results().expr_ty_adjusted(expr) =>
                 {
                     return;
-                }
+                },
                 ExprKind::MethodCall(_, _, [self_arg, ..], _) if expr.hir_id == self_arg.hir_id => true,
                 ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar)
                 | ExprKind::Field(..)
@@ -100,7 +100,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol,
                 ) =>
             {
                 return;
-            }
+            },
             _ => false,
         };
 
index b5bbbb09092af4f12d27c6fc60cc363444796019..fe9ffde0d337c1f15506e73bdca1e0f373c88da5 100644 (file)
@@ -186,7 +186,7 @@ fn check_general_case<'tcx>(
                         check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None);
                     }
                 }
-            }
+            },
             _ => (),
         }
     }
index 6f65778e1193cfc08d011e0eec606f08e683bf6a..06ba968fa4ed31da1700c3df599ff67badc51359 100644 (file)
@@ -1,4 +1,3 @@
-use super::MiscEarlyLints;
 use clippy_utils::diagnostics::span_lint;
 use rustc_ast::ast::{Expr, ExprKind, UnOp};
 use rustc_lint::EarlyContext;
@@ -6,18 +5,14 @@
 use super::DOUBLE_NEG;
 
 pub(super) fn check(cx: &EarlyContext<'_>, expr: &Expr) {
-    match expr.kind {
-        ExprKind::Unary(UnOp::Neg, ref inner) => {
-            if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
-                span_lint(
-                    cx,
-                    DOUBLE_NEG,
-                    expr.span,
-                    "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
-                );
-            }
-        },
-        ExprKind::Lit(ref lit) => MiscEarlyLints::check_lit(cx, lit),
-        _ => (),
+    if let ExprKind::Unary(UnOp::Neg, ref inner) = expr.kind {
+        if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
+            span_lint(
+                cx,
+                DOUBLE_NEG,
+                expr.span,
+                "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
+            );
+        }
     }
 }
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
new file mode 100644 (file)
index 0000000..1165c19
--- /dev/null
@@ -0,0 +1,38 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::ast::Lit;
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+
+use super::{SEPARATED_LITERAL_SUFFIX, UNSEPARATED_LITERAL_SUFFIX};
+
+pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) {
+    let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) {
+        val
+    } else {
+        return; // It's useless so shouldn't lint.
+    };
+    // Do not lint when literal is unsuffixed.
+    if !suffix.is_empty() {
+        if lit_snip.as_bytes()[maybe_last_sep_idx] == b'_' {
+            span_lint_and_sugg(
+                cx,
+                SEPARATED_LITERAL_SUFFIX,
+                lit.span,
+                &format!("{} type suffix should not be separated by an underscore", sugg_type),
+                "remove the underscore",
+                format!("{}{}", &lit_snip[..maybe_last_sep_idx], suffix),
+                Applicability::MachineApplicable,
+            );
+        } else {
+            span_lint_and_sugg(
+                cx,
+                UNSEPARATED_LITERAL_SUFFIX,
+                lit.span,
+                &format!("{} type suffix should be separated by an underscore", sugg_type),
+                "add an underscore",
+                format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+}
index b32feab4ee3e7e5506b23875170ca01d6d4920b6..7c3f5f22ade0f9ba447d1dc583791b092f1abf80 100644 (file)
@@ -1,15 +1,15 @@
 mod builtin_type_shadow;
 mod double_neg;
+mod literal_suffix;
 mod mixed_case_hex_literals;
 mod redundant_pattern;
 mod unneeded_field_pattern;
 mod unneeded_wildcard_pattern;
-mod unseparated_literal_suffix;
 mod zero_prefixed_literal;
 
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::source::snippet_opt;
-use rustc_ast::ast::{Expr, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
+use rustc_ast::ast::{Expr, ExprKind, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
 use rustc_ast::visit::FnKind;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_lint::{EarlyContext, EarlyLintPass};
     /// ### 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?
-    /// It is much less readable.
+    /// Suffix style should be consistent.
     ///
     /// ### Example
     /// ```rust
     /// let y = 123832_i32;
     /// ```
     pub UNSEPARATED_LITERAL_SUFFIX,
-    pedantic,
+    restriction,
     "literals whose suffix is not separated by an underscore"
 }
 
+declare_clippy_lint! {
+    /// ### 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
+    /// ```rust
+    /// // Bad
+    /// let y = 123832_i32;
+    ///
+    /// // Good
+    /// let y = 123832i32;
+    /// ```
+    pub SEPARATED_LITERAL_SUFFIX,
+    restriction,
+    "literals whose suffix is separated by an underscore"
+}
+
 declare_clippy_lint! {
     /// ### What it does
     /// Warns if an integral constant literal starts with `0`.
     DOUBLE_NEG,
     MIXED_CASE_HEX_LITERALS,
     UNSEPARATED_LITERAL_SUFFIX,
+    SEPARATED_LITERAL_SUFFIX,
     ZERO_PREFIXED_LITERAL,
     BUILTIN_TYPE_SHADOW,
     REDUNDANT_PATTERN,
@@ -310,6 +335,10 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
         if in_external_macro(cx.sess, expr.span) {
             return;
         }
+
+        if let ExprKind::Lit(ref lit) = expr.kind {
+            MiscEarlyLints::check_lit(cx, lit);
+        }
         double_neg::check(cx, expr);
     }
 }
@@ -332,7 +361,7 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit) {
                 LitIntType::Unsigned(ty) => ty.name_str(),
                 LitIntType::Unsuffixed => "",
             };
-            unseparated_literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
+            literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
             if lit_snip.starts_with("0x") {
                 mixed_case_hex_literals::check(cx, lit, suffix, &lit_snip);
             } else if lit_snip.starts_with("0b") || lit_snip.starts_with("0o") {
@@ -342,7 +371,7 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit) {
             }
         } else if let LitKind::Float(_, LitFloatType::Suffixed(float_ty)) = lit.kind {
             let suffix = float_ty.name_str();
-            unseparated_literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
+            literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/unseparated_literal_suffix.rs b/src/tools/clippy/clippy_lints/src/misc_early/unseparated_literal_suffix.rs
deleted file mode 100644 (file)
index 2018aa6..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use rustc_ast::ast::Lit;
-use rustc_errors::Applicability;
-use rustc_lint::EarlyContext;
-
-use super::UNSEPARATED_LITERAL_SUFFIX;
-
-pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) {
-    let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) {
-        val
-    } else {
-        return; // It's useless so shouldn't lint.
-    };
-    // Do not lint when literal is unsuffixed.
-    if !suffix.is_empty() && lit_snip.as_bytes()[maybe_last_sep_idx] != b'_' {
-        span_lint_and_sugg(
-            cx,
-            UNSEPARATED_LITERAL_SUFFIX,
-            lit.span,
-            &format!("{} type suffix should be separated by an underscore", sugg_type),
-            "add an underscore",
-            format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
-            Applicability::MachineApplicable,
-        );
-    }
-}
index f351d0098b7509cf6abdddfef53c21a29cc7a663..d41b54745649958de717e61f6d395bfbce0e62e5 100644 (file)
@@ -106,7 +106,7 @@ fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
                     }
                     process_paths_for_mod_files(path, &mut folder_segments, &mut mod_folders);
                     check_self_named_mod_exists(cx, path, file);
-                }
+                },
                 _ => {},
             }
         }
index 1b2495d764d2a0c650f9f866a153252fa5288b5a..f1be90c44f98b998901e0f4b2462722466c99d69 100644 (file)
@@ -107,14 +107,18 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         if let ExprKind::AddrOf(BorrowKind::Ref, mutability, inner) = e.kind {
             if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty(inner).kind() {
                 for adj3 in cx.typeck_results().expr_adjustments(e).windows(3) {
-                    if let [Adjustment {
-                        kind: Adjust::Deref(_), ..
-                    }, Adjustment {
-                        kind: Adjust::Deref(_), ..
-                    }, Adjustment {
-                        kind: Adjust::Borrow(_),
-                        ..
-                    }] = *adj3
+                    if let [
+                        Adjustment {
+                            kind: Adjust::Deref(_), ..
+                        },
+                        Adjustment {
+                            kind: Adjust::Deref(_), ..
+                        },
+                        Adjustment {
+                            kind: Adjust::Borrow(_),
+                            ..
+                        },
+                    ] = *adj3
                     {
                         let help_msg_ty = if matches!(mutability, Mutability::Not) {
                             format!("&{}", ty)
index 5b254bc8133d2fecce4c6227b90d7c91e2206b6c..e28cc49bf2a1a0f955ac3686c132d4c201b2b6ef 100644 (file)
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use rustc_ast::ast::{
-    Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, FnKind, Item, ItemKind, Local, Pat, PatKind,
+    self, Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Item, ItemKind, Local, Pat, PatKind,
 };
 use rustc_ast::visit::{walk_block, walk_expr, walk_pat, Visitor};
 use rustc_lint::{EarlyContext, EarlyLintPass};
@@ -357,7 +357,7 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
             return;
         }
 
-        if let ItemKind::Fn(box FnKind(_, ref sig, _, Some(ref blk))) = item.kind {
+        if let ItemKind::Fn(box ast::Fn { ref sig, body: Some(ref blk), .. }) = item.kind {
             do_check(self, cx, &item.attrs, &sig.decl, blk);
         }
     }
@@ -367,7 +367,7 @@ fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &AssocItem) {
             return;
         }
 
-        if let AssocItemKind::Fn(box FnKind(_, ref sig, _, Some(ref blk))) = item.kind {
+        if let AssocItemKind::Fn(box ast::Fn { ref sig, body: Some(ref blk), .. }) = item.kind {
             do_check(self, cx, &item.attrs, &sig.decl, blk);
         }
     }
index 374b7bd59649e87db0f8ffbbdb22f1ae0b015309..7ebf84d400f569c3f891bc7d417afeeb2d741167 100644 (file)
@@ -44,7 +44,7 @@
     /// 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`).
     pub NON_SEND_FIELDS_IN_SEND_TY,
-    nursery,
+    suspicious,
     "there is field that does not implement `Send` in a `Send` struct"
 }
 
index a62eb0699891bf583fc94e13a6e38629b533f877..cbe1c5d44d513044d745718518c69876f69a10f3 100644 (file)
@@ -22,7 +22,7 @@
     /// expression).
     ///
     /// ### Why is this bad?
-    /// Using the dedicated functions of the Option type is clearer and
+    /// Using the dedicated functions of the `Option` type is clearer and
     /// more concise than an `if let` expression.
     ///
     /// ### Known problems
index 92a4801a8468ae3d3e592212280e8dd7959c9bc5..8a36e20fc973d678297d14718039e8913af8acc7 100644 (file)
@@ -3,16 +3,16 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::ptr::get_spans;
 use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{is_type_diagnostic_item, match_type, walk_ptrs_hir_ty};
+use clippy_utils::ty::walk_ptrs_hir_ty;
 use clippy_utils::{expr_path_res, is_lint_allowed, match_any_diagnostic_items, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
+use rustc_hir::def::Res;
 use rustc_hir::{
-    BinOpKind, BodyId, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, HirId, Impl, ImplItem, ImplItemKind, Item,
-    ItemKind, Lifetime, MutTy, Mutability, Node, PathSegment, QPath, TraitFn, TraitItem, TraitItemKind, Ty, TyKind,
+    BinOpKind, BodyId, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, Impl, ImplItem, ImplItemKind, Item, ItemKind,
+    Lifetime, MutTy, Mutability, Node, PathSegment, QPath, TraitFn, TraitItem, TraitItemKind, Ty, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::Span;
 use rustc_span::symbol::Symbol;
 impl<'tcx> LateLintPass<'tcx> for Ptr {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if let ItemKind::Fn(ref sig, _, body_id) = item.kind {
-            check_fn(cx, sig.decl, item.hir_id(), Some(body_id));
+            check_fn(cx, sig.decl, Some(body_id));
         }
     }
 
@@ -165,7 +165,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>)
                     return; // ignore trait impls
                 }
             }
-            check_fn(cx, sig.decl, item.hir_id(), Some(body_id));
+            check_fn(cx, sig.decl, Some(body_id));
         }
     }
 
@@ -176,7 +176,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>
             } else {
                 None
             };
-            check_fn(cx, sig.decl, item.hir_id(), body_id);
+            check_fn(cx, sig.decl, body_id);
         }
     }
 
@@ -244,13 +244,10 @@ fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 }
 
 #[allow(clippy::too_many_lines)]
-fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: Option<BodyId>) {
-    let fn_def_id = cx.tcx.hir().local_def_id(fn_id);
-    let sig = cx.tcx.fn_sig(fn_def_id);
-    let fn_ty = sig.skip_binder();
+fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, opt_body_id: Option<BodyId>) {
     let body = opt_body_id.map(|id| cx.tcx.hir().body(id));
 
-    for (idx, (arg, ty)) in decl.inputs.iter().zip(fn_ty.inputs()).enumerate() {
+    for (idx, arg) in decl.inputs.iter().enumerate() {
         // Honor the allow attribute on parameters. See issue 5644.
         if let Some(body) = &body {
             if is_lint_allowed(cx, PTR_ARG, body.params[idx].hir_id) {
@@ -258,8 +255,20 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
             }
         }
 
-        if let ty::Ref(_, ty, Mutability::Not) = ty.kind() {
-            if is_type_diagnostic_item(cx, ty, sym::Vec) {
+        let (item_name, path) = if_chain! {
+            if let TyKind::Rptr(_, MutTy { ty, mutbl: Mutability::Not }) = arg.kind;
+            if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind;
+            if let Res::Def(_, did) = path.res;
+            if let Some(item_name) = cx.tcx.get_diagnostic_name(did);
+            then {
+                (item_name, path)
+            } else {
+                continue
+            }
+        };
+
+        match item_name {
+            sym::Vec => {
                 if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_owned()")]) {
                     span_lint_and_then(
                         cx,
@@ -289,7 +298,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
                         },
                     );
                 }
-            } else if is_type_diagnostic_item(cx, ty, sym::String) {
+            },
+            sym::String => {
                 if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_string()"), ("as_str", "")]) {
                     span_lint_and_then(
                         cx,
@@ -311,7 +321,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
                         },
                     );
                 }
-            } else if is_type_diagnostic_item(cx, ty, sym::PathBuf) {
+            },
+            sym::PathBuf => {
                 if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_path_buf()"), ("as_path", "")]) {
                     span_lint_and_then(
                         cx,
@@ -338,11 +349,10 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
                         },
                     );
                 }
-            } else if match_type(cx, ty, &paths::COW) {
+            },
+            sym::Cow => {
                 if_chain! {
-                    if let TyKind::Rptr(_, MutTy { ty, ..} ) = arg.kind;
-                    if let TyKind::Path(QPath::Resolved(None, pp)) = ty.kind;
-                    if let [ref bx] = *pp.segments;
+                    if let [ref bx] = *path.segments;
                     if let Some(params) = bx.args;
                     if !params.parenthesized;
                     if let Some(inner) = params.args.iter().find_map(|arg| match arg {
@@ -363,7 +373,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
                         );
                     }
                 }
-            }
+            },
+            _ => {},
         }
     }
 
index 4d616e26bfc1da1dab23a26aaaf0dcbc3b009cf5..f63ef163bcbd0f1b76ddfd92fcac4d38b50a48bc 100644 (file)
@@ -172,23 +172,17 @@ fn expression_returns_none(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool
         }
     }
 
-    fn expression_returns_unmodified_err(
-        cx: &LateContext<'_>,
-        expression: &Expr<'_>,
-        origin_hir_id: &Expr<'_>,
-    ) -> bool {
-        match expression.kind {
+    fn expression_returns_unmodified_err(cx: &LateContext<'_>, expr: &Expr<'_>, cond_expr: &Expr<'_>) -> bool {
+        match expr.kind {
             ExprKind::Block(block, _) => {
                 if let Some(return_expression) = Self::return_expression(block) {
-                    return Self::expression_returns_unmodified_err(cx, return_expression, origin_hir_id);
+                    return Self::expression_returns_unmodified_err(cx, return_expression, cond_expr);
                 }
 
                 false
             },
-            ExprKind::Ret(Some(expr)) | ExprKind::Call(expr, _) => {
-                Self::expression_returns_unmodified_err(cx, expr, origin_hir_id)
-            },
-            ExprKind::Path(_) => path_to_local(expression) == path_to_local(origin_hir_id),
+            ExprKind::Ret(Some(ret_expr)) => Self::expression_returns_unmodified_err(cx, ret_expr, cond_expr),
+            ExprKind::Path(_) => path_to_local(expr) == path_to_local(cond_expr),
             _ => false,
         }
     }
index 35b6bde56964c17f64c1f711dae4ed77fe9839d0..6435107b8b4643f02f94078b7fe0c70802458d56 100644 (file)
     "calling `as_bytes` on a string literal instead of using a byte string literal"
 }
 
-declare_lint_pass!(StringAdd => [STRING_ADD, STRING_ADD_ASSIGN]);
+declare_clippy_lint! {
+    /// ### 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
+    /// ```rust,should_panic
+    /// &"Ölkanne"[1..];
+    /// ```
+    pub STRING_SLICE,
+    restriction,
+    "slicing a string"
+}
+
+declare_lint_pass!(StringAdd => [STRING_ADD, STRING_ADD_ASSIGN, STRING_SLICE]);
 
 impl<'tcx> LateLintPass<'tcx> for StringAdd {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         if in_external_macro(cx.sess(), e.span) {
             return;
         }
-
-        if let ExprKind::Binary(
-            Spanned {
-                node: BinOpKind::Add, ..
-            },
-            left,
-            _,
-        ) = e.kind
-        {
-            if is_string(cx, left) {
-                if !is_lint_allowed(cx, STRING_ADD_ASSIGN, e.hir_id) {
-                    let parent = get_parent_expr(cx, e);
-                    if let Some(p) = parent {
-                        if let ExprKind::Assign(target, _, _) = p.kind {
-                            // avoid duplicate matches
-                            if SpanlessEq::new(cx).eq_expr(target, left) {
-                                return;
+        match e.kind {
+            ExprKind::Binary(
+                Spanned {
+                    node: BinOpKind::Add, ..
+                },
+                left,
+                _,
+            ) => {
+                if is_string(cx, left) {
+                    if !is_lint_allowed(cx, STRING_ADD_ASSIGN, e.hir_id) {
+                        let parent = get_parent_expr(cx, e);
+                        if let Some(p) = parent {
+                            if let ExprKind::Assign(target, _, _) = p.kind {
+                                // avoid duplicate matches
+                                if SpanlessEq::new(cx).eq_expr(target, left) {
+                                    return;
+                                }
                             }
                         }
                     }
+                    span_lint(
+                        cx,
+                        STRING_ADD,
+                        e.span,
+                        "you added something to a string. Consider using `String::push_str()` instead",
+                    );
                 }
-                span_lint(
-                    cx,
-                    STRING_ADD,
-                    e.span,
-                    "you added something to a string. Consider using `String::push_str()` instead",
-                );
-            }
-        } else if let ExprKind::Assign(target, src, _) = e.kind {
-            if is_string(cx, target) && is_add(cx, src, target) {
-                span_lint(
-                    cx,
-                    STRING_ADD_ASSIGN,
-                    e.span,
-                    "you assigned the result of adding something to this string. Consider using \
-                     `String::push_str()` instead",
-                );
-            }
+            },
+            ExprKind::Assign(target, src, _) => {
+                if is_string(cx, target) && is_add(cx, src, target) {
+                    span_lint(
+                        cx,
+                        STRING_ADD_ASSIGN,
+                        e.span,
+                        "you assigned the result of adding something to this string. Consider using \
+                         `String::push_str()` instead",
+                    );
+                }
+            },
+            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) {
+                    span_lint(
+                        cx,
+                        STRING_SLICE,
+                        e.span,
+                        "indexing into a string may panic if the index is within a UTF-8 character",
+                    );
+                }
+            },
+            _ => {},
         }
     }
 }
index e08e4d03c7efef5c651cdd46fcfb4ada153400d3..11aef50991b0a1415a12dc83077de7246fe53d03 100644 (file)
@@ -145,8 +145,9 @@ fn block_has_safety_comment(&mut self, tcx: TyCtxt<'_>, enclosing_hir_id: HirId,
         let file_name = source_map.span_to_filename(between_span);
         let source_file = source_map.get_source_file(&file_name)?;
 
-        let lex_start = (between_span.lo().0 + 1) as usize;
-        let src_str = source_file.src.as_ref()?[lex_start..between_span.hi().0 as usize].to_string();
+        let lex_start = (between_span.lo().0 - source_file.start_pos.0 + 1) as usize;
+        let lex_end = (between_span.hi().0 - source_file.start_pos.0) as usize;
+        let src_str = source_file.src.as_ref()?[lex_start..lex_end].to_string();
 
         let mut pos = 0;
         let mut comment = false;
index f337dec8f2b9663faf88299154394ba35e8c49ba..f49ce696a04b77d4832cca91d62f78b12964f72d 100644 (file)
@@ -45,7 +45,7 @@
     /// let x = String::from("\u{20ac}");
     /// ```
     pub NON_ASCII_LITERAL,
-    pedantic,
+    restriction,
     "using any literal non-ASCII chars in a string literal instead of using the `\\u` escape"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/unit_hash.rs b/src/tools/clippy/clippy_lints/src/unit_hash.rs
new file mode 100644 (file)
index 0000000..a3a3f2d
--- /dev/null
@@ -0,0 +1,77 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::snippet;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+    /// ### 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
+    /// ```rust
+    /// # use std::hash::Hash;
+    /// # use std::collections::hash_map::DefaultHasher;
+    /// # enum Foo { Empty, WithValue(u8) }
+    /// # use Foo::*;
+    /// # let mut state = DefaultHasher::new();
+    /// # let my_enum = Foo::Empty;
+    /// match my_enum {
+    ///        Empty => ().hash(&mut state),
+    ///        WithValue(x) => x.hash(&mut state),
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// # use std::hash::Hash;
+    /// # use std::collections::hash_map::DefaultHasher;
+    /// # enum Foo { Empty, WithValue(u8) }
+    /// # use Foo::*;
+    /// # let mut state = DefaultHasher::new();
+    /// # let my_enum = Foo::Empty;
+    /// match my_enum {
+    ///        Empty => 0_u8.hash(&mut state),
+    ///        WithValue(x) => x.hash(&mut state),
+    /// }
+    /// ```
+    pub UNIT_HASH,
+    correctness,
+    "hashing a unit value, which does nothing"
+}
+declare_lint_pass!(UnitHash => [UNIT_HASH]);
+
+impl LateLintPass<'tcx> for UnitHash {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if_chain! {
+            if let ExprKind::MethodCall(name_ident, _, args, _) = &expr.kind;
+            if name_ident.ident.name == sym::hash;
+            if let [recv, state_param] = args;
+            if cx.typeck_results().expr_ty(recv).is_unit();
+            then {
+                span_lint_and_then(
+                    cx,
+                    UNIT_HASH,
+                    expr.span,
+                    "this call to `hash` on the unit type will do nothing",
+                    |diag| {
+                        diag.span_suggestion(
+                            expr.span,
+                            "remove the call to `hash` or consider using",
+                            format!(
+                                "0_u8.hash({})",
+                                snippet(cx, state_param.span, ".."),
+                            ),
+                            Applicability::MaybeIncorrect,
+                        );
+                        diag.note("the implementation of `Hash` for `()` is a no-op");
+                    }
+                );
+            }
+        }
+    }
+}
index a4680ae137b3254e13f3c318448194a10211c8f9..6447e3fa2ca08a85d04716b6bd1f955ba8f5b931 100644 (file)
@@ -13,7 +13,7 @@
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for functions of type Result that contain `expect()` or `unwrap()`
+    /// 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.
index d05c52122d5ee518ab1d00f0349851909026151b..122a5ce3fc8f12d19fd8d0ce877ff2a672c01537 100644 (file)
@@ -288,10 +288,10 @@ pub(crate) fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
     ///
     /// The list of imports to always rename, a fully qualified path followed by the rename.
     (enforced_import_renames: Vec<crate::utils::conf::Rename> = Vec::new()),
-    /// Lint: RESTRICTED_SCRIPTS.
+    /// Lint: DISALLOWED_SCRIPT_IDENTS.
     ///
     /// The list of unicode scripts allowed to be used in the scope.
-    (allowed_scripts: Vec<String> = vec!["Latin".to_string()]),
+    (allowed_scripts: Vec<String> = ["Latin"].iter().map(ToString::to_string).collect()),
     /// Lint: NON_SEND_FIELDS_IN_SEND_TY.
     ///
     /// Whether to apply the raw pointer heuristic to determine if a type is `Send`.
index 0d27874b7affb88d7a4dc16f119469919cbf23ef..99cf4c1ed40fbcbd0a52105176f455b05f230995 100644 (file)
@@ -512,12 +512,21 @@ fn extract_attr_docs(cx: &LateContext<'_>, item: &Item<'_>) -> Option<String> {
     let mut lines = attrs.iter().filter_map(ast::Attribute::doc_str);
     let mut docs = String::from(&*lines.next()?.as_str());
     let mut in_code_block = false;
+    let mut is_code_block_rust = false;
     for line in lines {
-        docs.push('\n');
         let line = line.as_str();
         let line = &*line;
+
+        // Rustdoc hides code lines starting with `# ` and this removes them from Clippy's lint list :)
+        if is_code_block_rust && line.trim_start().starts_with("# ") {
+            continue;
+        }
+
+        // The line should be represented in the lint list, even if it's just an empty line
+        docs.push('\n');
         if let Some(info) = line.trim_start().strip_prefix("```") {
             in_code_block = !in_code_block;
+            is_code_block_rust = false;
             if in_code_block {
                 let lang = info
                     .trim()
@@ -528,6 +537,8 @@ fn extract_attr_docs(cx: &LateContext<'_>, item: &Item<'_>) -> Option<String> {
                     .unwrap_or("rust");
                 docs.push_str("```");
                 docs.push_str(lang);
+
+                is_code_block_rust = lang == "rust";
                 continue;
             }
         }
index 85d1f65c51f0911aaf1ab76ffb36ce496a759536..b412e15ae4f82c9b474f71837b84cb944ebbd23e 100644 (file)
@@ -4,7 +4,7 @@
 
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::{snippet_opt, snippet_with_applicability};
-use rustc_ast::ast::{Expr, ExprKind, ImplKind, Item, ItemKind, MacCall, Path, StrLit, StrStyle};
+use rustc_ast::ast::{Expr, ExprKind, Impl, Item, ItemKind, MacCall, Path, StrLit, StrStyle};
 use rustc_ast::token::{self, LitKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_errors::Applicability;
@@ -243,7 +243,7 @@ pub struct Write {
 
 impl EarlyLintPass for Write {
     fn check_item(&mut self, _: &EarlyContext<'_>, item: &Item) {
-        if let ItemKind::Impl(box ImplKind {
+        if let ItemKind::Impl(box Impl {
             of_trait: Some(trait_ref),
             ..
         }) = &item.kind
index 2fa98831c7740aa31e7765ddf463cb36eba3d658..1b05a8a35046ede0d99e4a5b439f52659ab2a075 100644 (file)
@@ -250,7 +250,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         (Use(l), Use(r)) => eq_use_tree(l, r),
         (Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
         (Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
-        (Fn(box FnKind(ld, lf, lg, lb)), Fn(box FnKind(rd, rf, rg, rb))) => {
+        (Fn(box ast::Fn { defaultness: ld, sig: lf, generics: lg, body: lb }),
+         Fn(box ast::Fn { defaultness: rd, sig: rf, generics: rg, body: rb })) => {
             eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
         },
         (Mod(lu, lmk), Mod(ru, rmk)) => {
@@ -266,7 +267,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         (ForeignMod(l), ForeignMod(r)) => {
             both(&l.abi, &r.abi, eq_str_lit) && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
         },
-        (TyAlias(box TyAliasKind(ld, lg, lb, lt)), TyAlias(box TyAliasKind(rd, rg, rb, rt))) => {
+        (TyAlias(box ast::TyAlias { defaultness: ld, generics: lg, bounds: lb, ty: lt }),
+         TyAlias(box ast::TyAlias { defaultness: rd, generics: rg, bounds: rb, ty: rt })) => {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
@@ -276,7 +278,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         (Struct(lv, lg), Struct(rv, rg)) | (Union(lv, lg), Union(rv, rg)) => {
             eq_variant_data(lv, rv) && eq_generics(lg, rg)
         },
-        (Trait(box TraitKind(la, lu, lg, lb, li)), Trait(box TraitKind(ra, ru, rg, rb, ri))) => {
+        (Trait(box ast::Trait { is_auto: la, unsafety: lu, generics: lg, bounds: lb, items: li }),
+         Trait(box ast::Trait { is_auto: ra, unsafety: ru, generics: rg, bounds: rb, items: ri })) => {
             la == ra
                 && matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
                 && eq_generics(lg, rg)
@@ -285,7 +288,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         },
         (TraitAlias(lg, lb), TraitAlias(rg, rb)) => eq_generics(lg, rg) && over(lb, rb, eq_generic_bound),
         (
-            Impl(box ImplKind {
+            Impl(box ast::Impl {
                 unsafety: lu,
                 polarity: lp,
                 defaultness: ld,
@@ -295,7 +298,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 self_ty: lst,
                 items: li,
             }),
-            Impl(box ImplKind {
+            Impl(box ast::Impl {
                 unsafety: ru,
                 polarity: rp,
                 defaultness: rd,
@@ -325,10 +328,12 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
     use ForeignItemKind::*;
     match (l, r) {
         (Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
-        (Fn(box FnKind(ld, lf, lg, lb)), Fn(box FnKind(rd, rf, rg, rb))) => {
+        (Fn(box ast::Fn { defaultness: ld, sig: lf, generics: lg, body: lb }),
+         Fn(box ast::Fn { defaultness: rd, sig: rf, generics: rg, body: rb })) => {
             eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
         },
-        (TyAlias(box TyAliasKind(ld, lg, lb, lt)), TyAlias(box TyAliasKind(rd, rg, rb, rt))) => {
+        (TyAlias(box ast::TyAlias { defaultness: ld, generics: lg, bounds: lb, ty: lt }),
+         TyAlias(box ast::TyAlias { defaultness: rd, generics: rg, bounds: rb, ty: rt })) => {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
@@ -343,10 +348,12 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
     use AssocItemKind::*;
     match (l, r) {
         (Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
-        (Fn(box FnKind(ld, lf, lg, lb)), Fn(box FnKind(rd, rf, rg, rb))) => {
+        (Fn(box ast::Fn { defaultness: ld, sig: lf, generics: lg, body: lb }),
+         Fn(box ast::Fn { defaultness: rd, sig: rf, generics: rg, body: rb })) => {
             eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
         },
-        (TyAlias(box TyAliasKind(ld, lg, lb, lt)), TyAlias(box TyAliasKind(rd, rg, rb, rt))) => {
+        (TyAlias(box ast::TyAlias { defaultness: ld, generics: lg, bounds: lb, ty: lt }),
+         TyAlias(box ast::TyAlias { defaultness: rd, generics: rg, bounds: rb, ty: rt })) => {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
diff --git a/src/tools/clippy/clippy_utils/src/camel_case.rs b/src/tools/clippy/clippy_utils/src/camel_case.rs
deleted file mode 100644 (file)
index a6636e3..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/// Returns the index of the character after the first camel-case component of `s`.
-#[must_use]
-pub fn until(s: &str) -> usize {
-    let mut iter = s.char_indices();
-    if let Some((_, first)) = iter.next() {
-        if !first.is_uppercase() {
-            return 0;
-        }
-    } else {
-        return 0;
-    }
-    let mut up = true;
-    let mut last_i = 0;
-    for (i, c) in iter {
-        if up {
-            if c.is_lowercase() {
-                up = false;
-            } else {
-                return last_i;
-            }
-        } else if c.is_uppercase() {
-            up = true;
-            last_i = i;
-        } else if !c.is_lowercase() {
-            return i;
-        }
-    }
-    if up { last_i } else { s.len() }
-}
-
-/// Returns index of the last camel-case component of `s`.
-#[must_use]
-pub fn from(s: &str) -> usize {
-    let mut iter = s.char_indices().rev();
-    if let Some((_, first)) = iter.next() {
-        if !first.is_lowercase() {
-            return s.len();
-        }
-    } else {
-        return s.len();
-    }
-    let mut down = true;
-    let mut last_i = s.len();
-    for (i, c) in iter {
-        if down {
-            if c.is_uppercase() {
-                down = false;
-                last_i = i;
-            } else if !c.is_lowercase() {
-                return last_i;
-            }
-        } else if c.is_lowercase() {
-            down = true;
-        } else if c.is_uppercase() {
-            last_i = i;
-        } else {
-            return last_i;
-        }
-    }
-    last_i
-}
-
-#[cfg(test)]
-mod test {
-    use super::{from, until};
-
-    #[test]
-    fn from_full() {
-        assert_eq!(from("AbcDef"), 0);
-        assert_eq!(from("Abc"), 0);
-        assert_eq!(from("ABcd"), 0);
-        assert_eq!(from("ABcdEf"), 0);
-        assert_eq!(from("AabABcd"), 0);
-    }
-
-    #[test]
-    fn from_partial() {
-        assert_eq!(from("abcDef"), 3);
-        assert_eq!(from("aDbc"), 1);
-        assert_eq!(from("aabABcd"), 3);
-    }
-
-    #[test]
-    fn from_not() {
-        assert_eq!(from("AbcDef_"), 7);
-        assert_eq!(from("AbcDD"), 5);
-    }
-
-    #[test]
-    fn from_caps() {
-        assert_eq!(from("ABCD"), 4);
-    }
-
-    #[test]
-    fn until_full() {
-        assert_eq!(until("AbcDef"), 6);
-        assert_eq!(until("Abc"), 3);
-    }
-
-    #[test]
-    fn until_not() {
-        assert_eq!(until("abcDef"), 0);
-        assert_eq!(until("aDbc"), 0);
-    }
-
-    #[test]
-    fn until_partial() {
-        assert_eq!(until("AbcDef_"), 6);
-        assert_eq!(until("CallTypeC"), 8);
-        assert_eq!(until("AbcDD"), 3);
-    }
-
-    #[test]
-    fn until_caps() {
-        assert_eq!(until("ABCD"), 0);
-    }
-}
index 8bf31807d55d1441d74e503a42e29334aee365f0..04347672e0fbb35e12241580aacfeac22de28fbc 100644 (file)
@@ -155,6 +155,19 @@ pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self)
             _ => None,
         }
     }
+
+    /// Returns the integer value or `None` if `self` or `val_type` is not integer type.
+    pub fn int_value(&self, cx: &LateContext<'_>, val_type: Ty<'_>) -> Option<FullInt> {
+        if let Constant::Int(const_int) = *self {
+            match *val_type.kind() {
+                ty::Int(ity) => Some(FullInt::S(sext(cx.tcx, const_int, ity))),
+                ty::Uint(_) => Some(FullInt::U(const_int)),
+                _ => None,
+            }
+        } else {
+            None
+        }
+    }
 }
 
 /// Parses a `LitKind` to a `Constant`.
@@ -202,6 +215,52 @@ pub fn constant_simple<'tcx>(
     constant(lcx, typeck_results, e).and_then(|(cst, res)| if res { None } else { Some(cst) })
 }
 
+pub fn constant_full_int(
+    lcx: &LateContext<'tcx>,
+    typeck_results: &ty::TypeckResults<'tcx>,
+    e: &Expr<'_>,
+) -> Option<FullInt> {
+    constant_simple(lcx, typeck_results, e)?.int_value(lcx, typeck_results.expr_ty(e))
+}
+
+#[derive(Copy, Clone, Debug, Eq)]
+pub enum FullInt {
+    S(i128),
+    U(u128),
+}
+
+impl PartialEq for FullInt {
+    #[must_use]
+    fn eq(&self, other: &Self) -> bool {
+        self.cmp(other) == Ordering::Equal
+    }
+}
+
+impl PartialOrd for FullInt {
+    #[must_use]
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for FullInt {
+    #[must_use]
+    fn cmp(&self, other: &Self) -> Ordering {
+        use FullInt::{S, U};
+
+        fn cmp_s_u(s: i128, u: u128) -> Ordering {
+            u128::try_from(s).map_or(Ordering::Less, |x| x.cmp(&u))
+        }
+
+        match (*self, *other) {
+            (S(s), S(o)) => s.cmp(&o),
+            (U(s), U(o)) => s.cmp(&o),
+            (S(s), U(o)) => cmp_s_u(s, o),
+            (U(s), S(o)) => cmp_s_u(o, s).reverse(),
+        }
+    }
+}
+
 /// Creates a `ConstEvalLateContext` from the given `LateContext` and `TypeckResults`.
 pub fn constant_context<'a, 'tcx>(
     lcx: &'a LateContext<'tcx>,
index 9302e5c21faa4f7606d485726bcbf256aba1cfb8..d47b002ad7aca95a94336ac60e6b6f511913d3b4 100644 (file)
@@ -72,7 +72,7 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
 /// 6  |     let other_f64_nan = 0.0f64 / 0.0;
 ///    |                         ^^^^^^^^^^^^
 ///    |
-///    = help: Consider using `f64::NAN` if you would like a constant representing NaN
+///    = 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,
index 60c4cb361aa6c0dfbc2d9ff534ca2569d9e7db18..b3a9a1de2ec93daa57b44eace9a0d66d1781f6d3 100644 (file)
@@ -1,14 +1,14 @@
-//! This module contains functions that retrieves specifiec elements.
+//! This module contains functions that retrieve specific elements.
 
 #![deny(clippy::missing_docs_in_private_items)]
 
 use crate::ty::is_type_diagnostic_item;
-use crate::{is_expn_of, last_path_segment, match_def_path, paths};
+use crate::{is_expn_of, last_path_segment, match_def_path, path_to_local_id, paths};
 use if_chain::if_chain;
 use rustc_ast::ast::{self, LitKind};
 use rustc_hir as hir;
 use rustc_hir::{
-    Arm, Block, BorrowKind, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath, StmtKind, UnOp,
+    Arm, Block, BorrowKind, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, PatKind, QPath, StmtKind, UnOp,
 };
 use rustc_lint::LateContext;
 use rustc_span::{sym, symbol, ExpnKind, Span, Symbol};
@@ -513,6 +513,8 @@ pub struct FormatArgsExpn<'tcx> {
     pub format_string_parts: &'tcx [Expr<'tcx>],
     /// Symbols corresponding to [`Self::format_string_parts`]
     pub format_string_symbols: Vec<Symbol>,
+    /// Match arm patterns, the `arg0`, etc. from the next field `args`
+    pub arg_names: &'tcx [Pat<'tcx>],
     /// Expressions like `ArgumentV1::new(arg0, Debug::fmt)`
     pub args: &'tcx [Expr<'tcx>],
     /// The final argument passed to `Arguments::new_v1_formatted`, if applicable
@@ -557,6 +559,7 @@ pub fn parse(expr: &'tcx Expr<'tcx>) -> Option<Self> {
                     _ => None,
                 })
                 .collect();
+            if let PatKind::Tuple(arg_names, None) = arm.pat.kind;
             if let ExprKind::Array(args) = arm.body.kind;
             then {
                 Some(FormatArgsExpn {
@@ -564,6 +567,7 @@ pub fn parse(expr: &'tcx Expr<'tcx>) -> Option<Self> {
                     value_args,
                     format_string_parts,
                     format_string_symbols,
+                    arg_names,
                     args,
                     fmt_expr,
                 })
@@ -587,9 +591,15 @@ pub fn args(&self) -> Option<Vec<FormatArgsArg<'tcx>>> {
                             if let Some(position_field) = fields.iter().find(|f| f.ident.name == sym::position);
                             if let ExprKind::Lit(lit) = &position_field.expr.kind;
                             if let LitKind::Int(position, _) = lit.node;
+                            if let Ok(i) = usize::try_from(position);
+                            let arg = &self.args[i];
+                            if let ExprKind::Call(_, [arg_name, _]) = arg.kind;
+                            if let Some(j) = self
+                                .arg_names
+                                .iter()
+                                .position(|pat| path_to_local_id(arg_name, pat.hir_id));
                             then {
-                                let i = usize::try_from(position).unwrap();
-                                Some(FormatArgsArg { value: self.value_args[i], arg: &self.args[i], fmt: Some(fmt) })
+                                Some(FormatArgsArg { value: self.value_args[j], arg, fmt: Some(fmt) })
                             } else {
                                 None
                             }
@@ -718,9 +728,7 @@ impl PanicExpn<'tcx> {
     /// Parses an expanded `panic!` invocation
     pub fn parse(expr: &'tcx Expr<'tcx>) -> Option<Self> {
         if_chain! {
-            if let ExprKind::Block(block, _) = expr.kind;
-            if let Some(init) = block.expr;
-            if let ExprKind::Call(_, [format_args]) = init.kind;
+            if let ExprKind::Call(_, [format_args]) = expr.kind;
             let expn_data = expr.span.ctxt().outer_expn_data();
             if let Some(format_args) = FormatArgsExpn::parse(format_args);
             then {
@@ -770,13 +778,13 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -
                     }
                     return Some(VecInitKind::WithExprCapacity(arg.hir_id));
                 }
-            }
+            },
             ExprKind::Path(QPath::Resolved(_, path))
                 if match_def_path(cx, path.res.opt_def_id()?, &paths::DEFAULT_TRAIT_METHOD)
                     && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::Vec) =>
             {
                 return Some(VecInitKind::Default);
-            }
+            },
             _ => (),
         }
     }
index 9bc380ca6caa6501c526c4edd18b2faa11df4a5c..086fbc9d3ddddcfba357846e45e897f806118814 100644 (file)
@@ -37,7 +37,6 @@
 #[allow(clippy::module_name_repetitions)]
 pub mod ast_utils;
 pub mod attrs;
-pub mod camel_case;
 pub mod comparisons;
 pub mod consts;
 pub mod diagnostics;
@@ -50,6 +49,7 @@
 pub mod ptr;
 pub mod qualify_min_const_fn;
 pub mod source;
+pub mod str_utils;
 pub mod sugg;
 pub mod ty;
 pub mod usage;
@@ -712,7 +712,7 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
 /// Checks if the top level expression can be moved into a closure as is.
 /// Currently checks for:
 /// * Break/Continue outside the given loop HIR ids.
-/// * Yield/Return statments.
+/// * Yield/Return statements.
 /// * Inline assembly.
 /// * Usages of a field of a local where the type of the local can be partially moved.
 ///
@@ -844,10 +844,13 @@ fn pat_capture_kind(cx: &LateContext<'_>, pat: &Pat<'_>) -> CaptureKind {
     let mut capture_expr_ty = e;
 
     for (parent_id, parent) in cx.tcx.hir().parent_iter(e.hir_id) {
-        if let [Adjustment {
-            kind: Adjust::Deref(_) | Adjust::Borrow(AutoBorrow::Ref(..)),
-            target,
-        }, ref adjust @ ..] = *cx
+        if let [
+            Adjustment {
+                kind: Adjust::Deref(_) | Adjust::Borrow(AutoBorrow::Ref(..)),
+                target,
+            },
+            ref adjust @ ..,
+        ] = *cx
             .typeck_results()
             .adjustments()
             .get(child_id)
@@ -1232,9 +1235,7 @@ pub fn get_enclosing_loop_or_closure(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Opti
     for (_, node) in tcx.hir().parent_iter(expr.hir_id) {
         match node {
             Node::Expr(
-                e
-                @
-                Expr {
+                e @ Expr {
                     kind: ExprKind::Loop(..) | ExprKind::Closure(..),
                     ..
                 },
@@ -1692,10 +1693,12 @@ pub fn is_async_fn(kind: FnKind<'_>) -> bool {
 pub fn get_async_fn_body(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'tcx Expr<'tcx>> {
     if let ExprKind::Call(
         _,
-        &[Expr {
-            kind: ExprKind::Closure(_, _, body, _, _),
-            ..
-        }],
+        &[
+            Expr {
+                kind: ExprKind::Closure(_, _, body, _, _),
+                ..
+            },
+        ],
     ) = body.value.kind
     {
         if let ExprKind::Block(
@@ -2123,7 +2126,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
     vis.found
 }
 
-/// Checks whether item either has `test` attribute appelied, or
+/// Checks whether item either has `test` attribute applied, or
 /// is a module with `test` in its name.
 ///
 /// Note: If you use this function, please add a `#[test]` case in `tests/ui_test`.
diff --git a/src/tools/clippy/clippy_utils/src/str_utils.rs b/src/tools/clippy/clippy_utils/src/str_utils.rs
new file mode 100644 (file)
index 0000000..cba96e0
--- /dev/null
@@ -0,0 +1,230 @@
+/// Dealing with sting indices can be hard, this struct ensures that both the
+/// character and byte index are provided for correct indexing.
+#[derive(Debug, Default, PartialEq, Eq)]
+pub struct StrIndex {
+    pub char_index: usize,
+    pub byte_index: usize,
+}
+
+impl StrIndex {
+    pub fn new(char_index: usize, byte_index: usize) -> Self {
+        Self { char_index, byte_index }
+    }
+}
+
+/// Returns the index of the character after the first camel-case component of `s`.
+///
+/// ```
+/// assert_eq!(camel_case_until("AbcDef"), StrIndex::new(6, 6));
+/// assert_eq!(camel_case_until("ABCD"), StrIndex::new(0, 0));
+/// assert_eq!(camel_case_until("AbcDD"), StrIndex::new(3, 3));
+/// assert_eq!(camel_case_until("Abc\u{f6}\u{f6}DD"), StrIndex::new(5, 7));
+/// ```
+#[must_use]
+pub fn camel_case_until(s: &str) -> StrIndex {
+    let mut iter = s.char_indices().enumerate();
+    if let Some((_char_index, (_, first))) = iter.next() {
+        if !first.is_uppercase() {
+            return StrIndex::new(0, 0);
+        }
+    } else {
+        return StrIndex::new(0, 0);
+    }
+    let mut up = true;
+    let mut last_index = StrIndex::new(0, 0);
+    for (char_index, (byte_index, c)) in iter {
+        if up {
+            if c.is_lowercase() {
+                up = false;
+            } else {
+                return last_index;
+            }
+        } else if c.is_uppercase() {
+            up = true;
+            last_index.byte_index = byte_index;
+            last_index.char_index = char_index;
+        } else if !c.is_lowercase() {
+            return StrIndex::new(char_index, byte_index);
+        }
+    }
+
+    if up {
+        last_index
+    } else {
+        StrIndex::new(s.chars().count(), s.len())
+    }
+}
+
+/// Returns index of the last camel-case component of `s`.
+///
+/// ```
+/// assert_eq!(camel_case_start("AbcDef"), StrIndex::new(0, 0));
+/// assert_eq!(camel_case_start("abcDef"), StrIndex::new(3, 3));
+/// assert_eq!(camel_case_start("ABCD"), StrIndex::new(4, 4));
+/// assert_eq!(camel_case_start("abcd"), StrIndex::new(4, 4));
+/// assert_eq!(camel_case_start("\u{f6}\u{f6}cd"), StrIndex::new(4, 6));
+/// ```
+#[must_use]
+pub fn camel_case_start(s: &str) -> StrIndex {
+    let char_count = s.chars().count();
+    let range = 0..char_count;
+    let mut iter = range.rev().zip(s.char_indices().rev());
+    if let Some((char_index, (_, first))) = iter.next() {
+        if !first.is_lowercase() {
+            return StrIndex::new(char_index, s.len());
+        }
+    } else {
+        return StrIndex::new(char_count, s.len());
+    }
+    let mut down = true;
+    let mut last_index = StrIndex::new(char_count, s.len());
+    for (char_index, (byte_index, c)) in iter {
+        if down {
+            if c.is_uppercase() {
+                down = false;
+                last_index.byte_index = byte_index;
+                last_index.char_index = char_index;
+            } else if !c.is_lowercase() {
+                return last_index;
+            }
+        } else if c.is_lowercase() {
+            down = true;
+        } else if c.is_uppercase() {
+            last_index.byte_index = byte_index;
+            last_index.char_index = char_index;
+        } else {
+            return last_index;
+        }
+    }
+    last_index
+}
+
+/// Dealing with sting comparison can be complicated, this struct ensures that both the
+/// character and byte count are provided for correct indexing.
+#[derive(Debug, Default, PartialEq, Eq)]
+pub struct StrCount {
+    pub char_count: usize,
+    pub byte_count: usize,
+}
+
+impl StrCount {
+    pub fn new(char_count: usize, byte_count: usize) -> Self {
+        Self { char_count, byte_count }
+    }
+}
+
+/// Returns the number of chars that match from the start
+///
+/// ```
+/// assert_eq!(count_match_start("hello_mouse", "hello_penguin"), StrCount::new(6, 6));
+/// assert_eq!(count_match_start("hello_clippy", "bye_bugs"), StrCount::new(0, 0));
+/// assert_eq!(count_match_start("hello_world", "hello_world"), StrCount::new(11, 11));
+/// assert_eq!(count_match_start("T\u{f6}ffT\u{f6}ff", "T\u{f6}ff"), StrCount::new(4, 5));
+/// ```
+#[must_use]
+pub fn count_match_start(str1: &str, str2: &str) -> StrCount {
+    // (char_index, char1)
+    let char_count = str1.chars().count();
+    let iter1 = (0..=char_count).zip(str1.chars());
+    // (byte_index, char2)
+    let iter2 = str2.char_indices();
+
+    iter1
+        .zip(iter2)
+        .take_while(|((_, c1), (_, c2))| c1 == c2)
+        .last()
+        .map_or_else(StrCount::default, |((char_index, _), (byte_index, character))| {
+            StrCount::new(char_index + 1, byte_index + character.len_utf8())
+        })
+}
+
+/// Returns the number of chars and bytes that match from the end
+///
+/// ```
+/// assert_eq!(count_match_end("hello_cat", "bye_cat"), StrCount::new(4, 4));
+/// assert_eq!(count_match_end("if_item_thing", "enum_value"), StrCount::new(0, 0));
+/// assert_eq!(count_match_end("Clippy", "Clippy"), StrCount::new(6, 6));
+/// assert_eq!(count_match_end("MyT\u{f6}ff", "YourT\u{f6}ff"), StrCount::new(4, 5));
+/// ```
+#[must_use]
+pub fn count_match_end(str1: &str, str2: &str) -> StrCount {
+    let char_count = str1.chars().count();
+    if char_count == 0 {
+        return StrCount::default();
+    }
+
+    // (char_index, char1)
+    let iter1 = (0..char_count).rev().zip(str1.chars().rev());
+    // (byte_index, char2)
+    let byte_count = str2.len();
+    let iter2 = str2.char_indices().rev();
+
+    iter1
+        .zip(iter2)
+        .take_while(|((_, c1), (_, c2))| c1 == c2)
+        .last()
+        .map_or_else(StrCount::default, |((char_index, _), (byte_index, _))| {
+            StrCount::new(char_count - char_index, byte_count - byte_index)
+        })
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn camel_case_start_full() {
+        assert_eq!(camel_case_start("AbcDef"), StrIndex::new(0, 0));
+        assert_eq!(camel_case_start("Abc"), StrIndex::new(0, 0));
+        assert_eq!(camel_case_start("ABcd"), StrIndex::new(0, 0));
+        assert_eq!(camel_case_start("ABcdEf"), StrIndex::new(0, 0));
+        assert_eq!(camel_case_start("AabABcd"), StrIndex::new(0, 0));
+    }
+
+    #[test]
+    fn camel_case_start_partial() {
+        assert_eq!(camel_case_start("abcDef"), StrIndex::new(3, 3));
+        assert_eq!(camel_case_start("aDbc"), StrIndex::new(1, 1));
+        assert_eq!(camel_case_start("aabABcd"), StrIndex::new(3, 3));
+        assert_eq!(camel_case_start("\u{f6}\u{f6}AabABcd"), StrIndex::new(2, 4));
+    }
+
+    #[test]
+    fn camel_case_start_not() {
+        assert_eq!(camel_case_start("AbcDef_"), StrIndex::new(7, 7));
+        assert_eq!(camel_case_start("AbcDD"), StrIndex::new(5, 5));
+        assert_eq!(camel_case_start("all_small"), StrIndex::new(9, 9));
+        assert_eq!(camel_case_start("\u{f6}_all_small"), StrIndex::new(11, 12));
+    }
+
+    #[test]
+    fn camel_case_start_caps() {
+        assert_eq!(camel_case_start("ABCD"), StrIndex::new(4, 4));
+    }
+
+    #[test]
+    fn camel_case_until_full() {
+        assert_eq!(camel_case_until("AbcDef"), StrIndex::new(6, 6));
+        assert_eq!(camel_case_until("Abc"), StrIndex::new(3, 3));
+        assert_eq!(camel_case_until("Abc\u{f6}\u{f6}\u{f6}"), StrIndex::new(6, 9));
+    }
+
+    #[test]
+    fn camel_case_until_not() {
+        assert_eq!(camel_case_until("abcDef"), StrIndex::new(0, 0));
+        assert_eq!(camel_case_until("aDbc"), StrIndex::new(0, 0));
+    }
+
+    #[test]
+    fn camel_case_until_partial() {
+        assert_eq!(camel_case_until("AbcDef_"), StrIndex::new(6, 6));
+        assert_eq!(camel_case_until("CallTypeC"), StrIndex::new(8, 8));
+        assert_eq!(camel_case_until("AbcDD"), StrIndex::new(3, 3));
+        assert_eq!(camel_case_until("Abc\u{f6}\u{f6}DD"), StrIndex::new(5, 7));
+    }
+
+    #[test]
+    fn until_caps() {
+        assert_eq!(camel_case_until("ABCD"), StrIndex::new(0, 0));
+    }
+}
index 004eb28b44640fb59ab3d43c31203ab97c622870..bd32696d6dbda7d15b4b6975a6195f673d2f76c7 100644 (file)
@@ -16,6 +16,7 @@ because that's clearly a non-descriptive name.
   - [Edition 2018 tests](#edition-2018-tests)
   - [Testing manually](#testing-manually)
   - [Lint declaration](#lint-declaration)
+  - [Lint registration](#lint-registration)
   - [Lint passes](#lint-passes)
   - [Emitting a lint](#emitting-a-lint)
   - [Adding the lint logic](#adding-the-lint-logic)
@@ -43,9 +44,9 @@ take a look at our [lint naming guidelines][lint_naming]. To get started on this
 lint you can run `cargo dev new_lint --name=foo_functions --pass=early
 --category=pedantic` (category will default to nursery if not provided). This
 command will create two files: `tests/ui/foo_functions.rs` and
-`clippy_lints/src/foo_functions.rs`, as well as run `cargo dev update_lints` to
-register the new lint. For cargo lints, two project hierarchies (fail/pass) will
-be created by default under `tests/ui-cargo`.
+`clippy_lints/src/foo_functions.rs`, as well as
+[registering the lint](#lint-registration). For cargo lints, two project
+hierarchies (fail/pass) will be created by default under `tests/ui-cargo`.
 
 Next, we'll open up these files and add our lint!
 
@@ -220,32 +221,34 @@ declare_lint_pass!(FooFunctions => [FOO_FUNCTIONS]);
 impl EarlyLintPass for FooFunctions {}
 ```
 
-Normally after declaring the lint, we have to run `cargo dev update_lints`,
-which updates some files, so Clippy knows about the new lint. Since we used
-`cargo dev new_lint ...` to generate the lint declaration, this was done
-automatically. While `update_lints` automates most of the things, it doesn't
-automate everything. We will have to register our lint pass manually in the
-`register_plugins` function in `clippy_lints/src/lib.rs`:
+[declare_clippy_lint]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L60
+[example_lint_page]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
+[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
+[category_level_mapping]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L110
+
+## Lint registration
+
+When using `cargo dev new_lint`, the lint is automatically registered and
+nothing more has to be done.
+
+When declaring a new lint by hand and `cargo dev update_lints` is used, the lint
+pass may have to be registered manually in the `register_plugins` function in
+`clippy_lints/src/lib.rs`:
 
 ```rust
-store.register_early_pass(|| box foo_functions::FooFunctions);
+store.register_early_pass(|| Box::new(foo_functions::FooFunctions));
 ```
 
 As one may expect, there is a corresponding `register_late_pass` method
 available as well. Without a call to one of `register_early_pass` or
 `register_late_pass`, the lint pass in question will not be run.
 
-One reason that `cargo dev` does not automate this step is that multiple lints
-can use the same lint pass, so registering the lint pass may already be done
-when adding a new lint. Another reason that this step is not automated is that
-the order that the passes are registered determines the order the passes
-actually run, which in turn affects the order that any emitted lints are output
-in.
-
-[declare_clippy_lint]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L60
-[example_lint_page]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
-[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
-[category_level_mapping]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L110
+One reason that `cargo dev update_lints` does not automate this step is that
+multiple lints can use the same lint pass, so registering the lint pass may
+already be done when adding a new lint. Another reason that this step is not
+automated is that the order that the passes are registered determines the order
+the passes actually run, which in turn affects the order that any emitted lints
+are output in.
 
 ## Lint passes
 
@@ -564,7 +567,8 @@ in the following steps:
     /// <The configuration field doc comment>
     (configuration_ident: Type = DefaultValue),
     ```
-    The doc comment will be automatically added to the lint documentation.
+    The doc comment is automatically added to the documentation of the listed lints. The default
+    value will be formatted using the `Debug` implementation of the type.
 2. Adding the configuration value to the lint impl struct:
     1. This first requires the definition of a lint impl struct. Lint impl structs are usually
         generated with the `declare_lint_pass!` macro. This struct needs to be defined manually
index 67eaf286004f9515cabbfefe3d889ec4b9c74b3f..09554c08987b1ae66902243826bcfec6b063c91f 100644 (file)
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-10-21"
+channel = "nightly-2021-11-04"
 components = ["llvm-tools-preview", "rustc-dev", "rust-src"]
index c15835ef2995687327d9227c861b1decd8b3f85d..f25cf1d3ef56185243762a4f3296f4f7ca2eca98 100644 (file)
@@ -104,7 +104,10 @@ fn extern_flags() -> String {
 }
 
 fn default_config() -> compiletest::Config {
-    let mut config = compiletest::Config::default();
+    let mut config = compiletest::Config {
+        edition: Some("2021".into()),
+        ..compiletest::Config::default()
+    };
 
     if let Ok(filters) = env::var("TESTNAME") {
         config.filters = filters.split(',').map(std::string::ToString::to_string).collect();
index bd342e390f52f3d065bdef329f2c082ed3f322c7..7d6edc2b1e095fb1cb59e81cca7b28bba7f44497 100644 (file)
@@ -1,7 +1,10 @@
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
 #![warn(rust_2018_idioms, unused_lifetimes)]
 #![allow(clippy::assertions_on_constants)]
+#![feature(path_file_prefix)]
 
+use std::cmp::Ordering;
+use std::ffi::OsStr;
 use std::fs::{self, DirEntry};
 use std::path::Path;
 
@@ -21,29 +24,39 @@ fn test_missing_tests() {
     }
 }
 
-/*
-Test for missing files.
-
-Since rs files are alphabetically before stderr/stdout, we can sort by the full name
-and iter in that order. If we've seen the file stem for the first time and it's not
-a rust file, it means the rust file has to be missing.
-*/
+// Test for missing files.
 fn explore_directory(dir: &Path) -> Vec<String> {
     let mut missing_files: Vec<String> = Vec::new();
     let mut current_file = String::new();
     let mut files: Vec<DirEntry> = fs::read_dir(dir).unwrap().filter_map(Result::ok).collect();
-    files.sort_by_key(std::fs::DirEntry::path);
+    files.sort_by(|x, y| {
+        match x.path().file_prefix().cmp(&y.path().file_prefix()) {
+            Ordering::Equal => (),
+            ord => return ord,
+        }
+        // Sort rs files before the others if they share the same prefix. So when we see
+        // the file prefix for the first time and it's not a rust file, it means the rust
+        // file has to be missing.
+        match (
+            x.path().extension().and_then(OsStr::to_str),
+            y.path().extension().and_then(OsStr::to_str),
+        ) {
+            (Some("rs"), _) => Ordering::Less,
+            (_, Some("rs")) => Ordering::Greater,
+            _ => Ordering::Equal,
+        }
+    });
     for entry in &files {
         let path = entry.path();
         if path.is_dir() {
             missing_files.extend(explore_directory(&path));
         } else {
-            let file_stem = path.file_stem().unwrap().to_str().unwrap().to_string();
+            let file_prefix = path.file_prefix().unwrap().to_str().unwrap().to_string();
             if let Some(ext) = path.extension() {
                 match ext.to_str().unwrap() {
-                    "rs" => current_file = file_stem.clone(),
+                    "rs" => current_file = file_prefix.clone(),
                     "stderr" | "stdout" => {
-                        if file_stem != current_file {
+                        if file_prefix != current_file {
                             missing_files.push(path.to_str().unwrap().to_string());
                         }
                     },
index 33a3ef7513631aab7d1fb367d49c9993ab1c44ad..e678c896fd3e3b3dc8e7bcba92fb5b641a6f8797 100644 (file)
@@ -1,5 +1,3 @@
-// edition:2018
-
 #![warn(clippy::too_many_lines)]
 
 // This function should be considered one line.
index 7551cac9f504b968918e65f3d82ae0ee1b800cf0..d736bf899735a5cfb5ed02eef151b4c20cbd635f 100644 (file)
@@ -1,5 +1,5 @@
 error: this function has too many lines (2/1)
-  --> $DIR/test.rs:20:1
+  --> $DIR/test.rs:18:1
    |
 LL | / fn too_many_lines() {
 LL | |     println!("This is bad.");
@@ -10,7 +10,7 @@ LL | | }
    = note: `-D clippy::too-many-lines` implied by `-D warnings`
 
 error: this function has too many lines (4/1)
-  --> $DIR/test.rs:26:1
+  --> $DIR/test.rs:24:1
    |
 LL | / async fn async_too_many_lines() {
 LL | |     println!("This is bad.");
@@ -19,7 +19,7 @@ LL | | }
    | |_^
 
 error: this function has too many lines (4/1)
-  --> $DIR/test.rs:32:1
+  --> $DIR/test.rs:30:1
    |
 LL | / fn closure_too_many_lines() {
 LL | |     let _ = {
@@ -30,7 +30,7 @@ LL | | }
    | |_^
 
 error: this function has too many lines (2/1)
-  --> $DIR/test.rs:54:1
+  --> $DIR/test.rs:52:1
    |
 LL | / fn comment_before_code() {
 LL | |     let _ = "test";
index 2180f848d62cd256f7538d100d6cf5c634398ec2..cb516d0f97783fee0b7b4a71c3cc9336a5072c64 100644 (file)
@@ -1,3 +1,4 @@
+//FIXME: suggestions are wrongly expanded, this should be fixed along with #7843
 #![allow(non_fmt_panics)]
 
 macro_rules! assert_const {
@@ -6,7 +7,6 @@ macro_rules! assert_const {
         debug_assert!($len < 0);
     };
 }
-
 fn main() {
     assert!(true);
     assert!(false);
@@ -14,7 +14,7 @@ fn main() {
     assert!(false, "false message");
 
     let msg = "panic message";
-    assert!(false, msg.to_uppercase());
+    assert!(false, "{}", msg.to_uppercase());
 
     const B: bool = true;
     assert!(B);
index 4ca1e6f6e88cc783cf0b2ecd25d9b0c44ddfea5e..ec80ec702fb574ad4cf6380b9e7b2179230a8c84 100644 (file)
@@ -26,22 +26,13 @@ LL |     assert!(true, "true message");
    = help: remove it
    = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: `assert!(false, "false message")` should probably be replaced
+error: `assert!(false, $crate::const_format_args!($($t)+))` should probably be replaced
   --> $DIR/assertions_on_constants.rs:14:5
    |
 LL |     assert!(false, "false message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: use `panic!("false message")` or `unreachable!("false message")`
-   = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: `assert!(false, msg.to_uppercase())` should probably be replaced
-  --> $DIR/assertions_on_constants.rs:17:5
-   |
-LL |     assert!(false, msg.to_uppercase());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: use `panic!(msg.to_uppercase())` or `unreachable!(msg.to_uppercase())`
+   = help: use `panic!($crate::const_format_args!($($t)+))` or `unreachable!($crate::const_format_args!($($t)+))`
    = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `assert!(true)` will be optimized out by the compiler
@@ -62,13 +53,13 @@ LL |     assert!(C);
    = help: use `panic!()` or `unreachable!()`
    = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: `assert!(false, "C message")` should probably be replaced
+error: `assert!(false, $crate::const_format_args!($($t)+))` should probably be replaced
   --> $DIR/assertions_on_constants.rs:24:5
    |
 LL |     assert!(C, "C message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: use `panic!("C message")` or `unreachable!("C message")`
+   = help: use `panic!($crate::const_format_args!($($t)+))` or `unreachable!($crate::const_format_args!($($t)+))`
    = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `debug_assert!(true)` will be optimized out by the compiler
@@ -80,5 +71,5 @@ LL |     debug_assert!(true);
    = help: remove it
    = note: this error originates in the macro `$crate::assert` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 9 previous errors
+error: aborting due to 8 previous errors
 
index 9b1a7ac3ba9de85493244232abca89ce4d5d5452..e20b58269b93e60485b68b74618b3bc4a6fe77d3 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 
 #![feature(async_closure)]
 #![warn(clippy::async_yields_async)]
index 731c094edb42b16b7a8488293fb09affc43d92db..c1dfa398450250f6d67a6d1290e34c139865d8e1 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 
 #![feature(async_closure)]
 #![warn(clippy::async_yields_async)]
index 3f2051458f677c219930503943f5ef00ae44224a..b0c4215e7ddf1be1c4bbcaeb031e3896096f9386 100644 (file)
@@ -1,5 +1,5 @@
 error: an async construct yields a type which is itself awaitable
-  --> $DIR/async_yields_async.rs:40:9
+  --> $DIR/async_yields_async.rs:39:9
    |
 LL |        let _h = async {
    |   ____________________-
@@ -20,7 +20,7 @@ LL +         }.await
    |
 
 error: an async construct yields a type which is itself awaitable
-  --> $DIR/async_yields_async.rs:45:9
+  --> $DIR/async_yields_async.rs:44:9
    |
 LL |       let _i = async {
    |  ____________________-
@@ -33,7 +33,7 @@ LL | |     };
    | |_____- outer async construct
 
 error: an async construct yields a type which is itself awaitable
-  --> $DIR/async_yields_async.rs:51:9
+  --> $DIR/async_yields_async.rs:50:9
    |
 LL |        let _j = async || {
    |   _______________________-
@@ -53,7 +53,7 @@ LL +         }.await
    |
 
 error: an async construct yields a type which is itself awaitable
-  --> $DIR/async_yields_async.rs:56:9
+  --> $DIR/async_yields_async.rs:55:9
    |
 LL |       let _k = async || {
    |  _______________________-
@@ -66,7 +66,7 @@ LL | |     };
    | |_____- outer async construct
 
 error: an async construct yields a type which is itself awaitable
-  --> $DIR/async_yields_async.rs:58:23
+  --> $DIR/async_yields_async.rs:57:23
    |
 LL |     let _l = async || CustomFutureType;
    |                       ^^^^^^^^^^^^^^^^
@@ -76,7 +76,7 @@ LL |     let _l = async || CustomFutureType;
    |                       help: consider awaiting this value: `CustomFutureType.await`
 
 error: an async construct yields a type which is itself awaitable
-  --> $DIR/async_yields_async.rs:64:9
+  --> $DIR/async_yields_async.rs:63:9
    |
 LL |       let _m = async || {
    |  _______________________-
index 0458950edee1c9660d41a4e15a974038f3949eac..dd6640a387a23877548f96c8b6a40185b27c7cfd 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::await_holding_lock)]
 
 use std::sync::Mutex;
index a5fcff7e0e44363f02087f6c87fdfacc46638734..ddfb104cdfbd07ab1207f133e075182b3d409d0e 100644 (file)
@@ -1,12 +1,12 @@
 error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await
-  --> $DIR/await_holding_lock.rs:7:9
+  --> $DIR/await_holding_lock.rs:6:9
    |
 LL |     let guard = x.lock().unwrap();
    |         ^^^^^
    |
    = note: `-D clippy::await-holding-lock` implied by `-D warnings`
 note: these are all the await points this lock is held through
-  --> $DIR/await_holding_lock.rs:7:5
+  --> $DIR/await_holding_lock.rs:6:5
    |
 LL | /     let guard = x.lock().unwrap();
 LL | |     baz().await
@@ -14,13 +14,13 @@ LL | | }
    | |_^
 
 error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await
-  --> $DIR/await_holding_lock.rs:28:9
+  --> $DIR/await_holding_lock.rs:27:9
    |
 LL |     let guard = x.lock().unwrap();
    |         ^^^^^
    |
 note: these are all the await points this lock is held through
-  --> $DIR/await_holding_lock.rs:28:5
+  --> $DIR/await_holding_lock.rs:27:5
    |
 LL | /     let guard = x.lock().unwrap();
 LL | |
@@ -32,13 +32,13 @@ LL | | }
    | |_^
 
 error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await
-  --> $DIR/await_holding_lock.rs:41:13
+  --> $DIR/await_holding_lock.rs:40:13
    |
 LL |         let guard = x.lock().unwrap();
    |             ^^^^^
    |
 note: these are all the await points this lock is held through
-  --> $DIR/await_holding_lock.rs:41:9
+  --> $DIR/await_holding_lock.rs:40:9
    |
 LL | /         let guard = x.lock().unwrap();
 LL | |         baz().await
@@ -46,13 +46,13 @@ LL | |     };
    | |_____^
 
 error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await
-  --> $DIR/await_holding_lock.rs:53:13
+  --> $DIR/await_holding_lock.rs:52:13
    |
 LL |         let guard = x.lock().unwrap();
    |             ^^^^^
    |
 note: these are all the await points this lock is held through
-  --> $DIR/await_holding_lock.rs:53:9
+  --> $DIR/await_holding_lock.rs:52:9
    |
 LL | /         let guard = x.lock().unwrap();
 LL | |         baz().await
index 88841597bb60bf5bc8a8bff346fdfc9391a40cfe..23b7095de3a39ae31a36bbc37a7b625c38bec5b3 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::await_holding_refcell_ref)]
 
 use std::cell::RefCell;
index 55e41dbca96f834046b43c624e377ddcb6bbb6d3..67cc0032be2f46742725351dd9beca969d458b4e 100644 (file)
@@ -1,12 +1,12 @@
 error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
-  --> $DIR/await_holding_refcell_ref.rs:7:9
+  --> $DIR/await_holding_refcell_ref.rs:6:9
    |
 LL |     let b = x.borrow();
    |         ^
    |
    = note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings`
 note: these are all the await points this ref is held through
-  --> $DIR/await_holding_refcell_ref.rs:7:5
+  --> $DIR/await_holding_refcell_ref.rs:6:5
    |
 LL | /     let b = x.borrow();
 LL | |     baz().await
@@ -14,13 +14,13 @@ LL | | }
    | |_^
 
 error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
-  --> $DIR/await_holding_refcell_ref.rs:12:9
+  --> $DIR/await_holding_refcell_ref.rs:11:9
    |
 LL |     let b = x.borrow_mut();
    |         ^
    |
 note: these are all the await points this ref is held through
-  --> $DIR/await_holding_refcell_ref.rs:12:5
+  --> $DIR/await_holding_refcell_ref.rs:11:5
    |
 LL | /     let b = x.borrow_mut();
 LL | |     baz().await
@@ -28,13 +28,13 @@ LL | | }
    | |_^
 
 error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
-  --> $DIR/await_holding_refcell_ref.rs:33:9
+  --> $DIR/await_holding_refcell_ref.rs:32:9
    |
 LL |     let b = x.borrow_mut();
    |         ^
    |
 note: these are all the await points this ref is held through
-  --> $DIR/await_holding_refcell_ref.rs:33:5
+  --> $DIR/await_holding_refcell_ref.rs:32:5
    |
 LL | /     let b = x.borrow_mut();
 LL | |
@@ -46,13 +46,13 @@ LL | | }
    | |_^
 
 error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
-  --> $DIR/await_holding_refcell_ref.rs:45:9
+  --> $DIR/await_holding_refcell_ref.rs:44:9
    |
 LL |     let b = x.borrow_mut();
    |         ^
    |
 note: these are all the await points this ref is held through
-  --> $DIR/await_holding_refcell_ref.rs:45:5
+  --> $DIR/await_holding_refcell_ref.rs:44:5
    |
 LL | /     let b = x.borrow_mut();
 LL | |
@@ -64,13 +64,13 @@ LL | | }
    | |_^
 
 error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
-  --> $DIR/await_holding_refcell_ref.rs:60:13
+  --> $DIR/await_holding_refcell_ref.rs:59:13
    |
 LL |         let b = x.borrow_mut();
    |             ^
    |
 note: these are all the await points this ref is held through
-  --> $DIR/await_holding_refcell_ref.rs:60:9
+  --> $DIR/await_holding_refcell_ref.rs:59:9
    |
 LL | /         let b = x.borrow_mut();
 LL | |         baz().await
@@ -78,13 +78,13 @@ LL | |     };
    | |_____^
 
 error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
-  --> $DIR/await_holding_refcell_ref.rs:72:13
+  --> $DIR/await_holding_refcell_ref.rs:71:13
    |
 LL |         let b = x.borrow_mut();
    |             ^
    |
 note: these are all the await points this ref is held through
-  --> $DIR/await_holding_refcell_ref.rs:72:9
+  --> $DIR/await_holding_refcell_ref.rs:71:9
    |
 LL | /         let b = x.borrow_mut();
 LL | |         baz().await
index 8ee0969b0f0761b16371eb485570ac83ad3abe5d..ebc1ed5587fe30a9b8f6675e6ac51b79f1a9725f 100644 (file)
@@ -92,4 +92,27 @@ fn main() {
     (1i64).checked_rem_euclid(-1i64).unwrap() as u64;
     (1i64).checked_rem_euclid(-1i64).unwrap() as u128;
     (1isize).checked_rem_euclid(-1isize).unwrap() as usize;
+
+    // no lint for `cast_possible_truncation`
+    // with `signum` method call (see issue #5395)
+    let x: i64 = 5;
+    let _ = x.signum() as i32;
+
+    let s = x.signum();
+    let _ = s as i32;
+
+    // Test for signed min
+    (-99999999999i64).min(1) as i8; // should be linted because signed
+
+    // Test for various operations that remove enough bits for the result to fit
+    (999999u64 & 1) as u8;
+    (999999u64 % 15) as u8;
+    (999999u64 / 0x1_0000_0000_0000) as u16;
+    ({ 999999u64 >> 56 }) as u8;
+    ({
+        let x = 999999u64;
+        x.min(1)
+    }) as u8;
+    999999u64.clamp(0, 255) as u8;
+    999999u64.clamp(0, 256) as u8; // should still be linted
 }
index 4c66d736494843955903b39f917ac5ee187f61d5..edf8790cf33d861c3978669145d5e500f2232314 100644 (file)
@@ -138,5 +138,17 @@ error: casting `isize` to `usize` may lose the sign of the value
 LL |     -1isize as usize;
    |     ^^^^^^^^^^^^^^^^
 
-error: aborting due to 22 previous errors
+error: casting `i64` to `i8` may truncate the value
+  --> $DIR/cast.rs:105:5
+   |
+LL |     (-99999999999i64).min(1) as i8; // should be linted because signed
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `u64` to `u8` may truncate the value
+  --> $DIR/cast.rs:117:5
+   |
+LL |     999999u64.clamp(0, 256) as u8; // should still be linted
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 24 previous errors
 
diff --git a/src/tools/clippy/tests/ui/crashes/auxiliary/ice-7868-aux.rs b/src/tools/clippy/tests/ui/crashes/auxiliary/ice-7868-aux.rs
new file mode 100644 (file)
index 0000000..bee2989
--- /dev/null
@@ -0,0 +1,3 @@
+fn zero() {
+    unsafe { 0 };
+}
index 4feab7910b7445da53bf0c73ac25bea9ce160a66..9b68cac7ff4854abc60352d7c8cbff472604cf44 100644 (file)
@@ -7,7 +7,6 @@
 // in type inference.
 #![feature(trivial_bounds)]
 #![allow(unused)]
-
 trait A {}
 
 impl A for i32 {}
@@ -22,9 +21,9 @@ struct TwoStrs(str, str)
 
 fn unsized_local()
 where
-    for<'a> Dst<A + 'a>: Sized,
+    for<'a> Dst<dyn A + 'a>: Sized,
 {
-    let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
+    let x: Dst<dyn A> = *(Box::new(Dst { x: 1 }) as Box<Dst<dyn A>>);
 }
 
 fn return_str() -> str
index 9a89047f072777cd7f6bf3f5588083be74b7f6b0..79018080886c0561d33fc88fe31890911f4ccd9f 100644 (file)
@@ -1,30 +1,34 @@
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-3969.rs:25:17
+error: trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
+  --> $DIR/ice-3969.rs:20:10
    |
-LL |     for<'a> Dst<A + 'a>: Sized,
-   |                 ^^^^^^ help: use `dyn`: `dyn A + 'a`
+LL |     str: Sized;
+   |          ^^^^^
    |
-   = note: `-D bare-trait-objects` implied by `-D warnings`
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `-D trivial-bounds` implied by `-D warnings`
 
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-3969.rs:27:16
+error: trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
+  --> $DIR/ice-3969.rs:24:30
    |
-LL |     let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
-   |                ^ help: use `dyn`: `dyn A`
+LL |     for<'a> Dst<dyn A + 'a>: Sized,
+   |                              ^^^^^
+
+error: trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
+  --> $DIR/ice-3969.rs:31:10
    |
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+LL |     str: Sized,
+   |          ^^^^^
 
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-3969.rs:27:57
+error: trait bound std::string::String: std::ops::Neg does not depend on any type or lifetime parameters
+  --> $DIR/ice-3969.rs:38:13
    |
-LL |     let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
-   |                                                         ^ help: use `dyn`: `dyn A`
+LL |     String: ::std::ops::Neg<Output = String>,
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: trait bound i32: std::iter::Iterator does not depend on any type or lifetime parameters
+  --> $DIR/ice-3969.rs:45:10
    |
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+LL |     i32: Iterator,
+   |          ^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 5 previous errors
 
index 1b20c9defac823185ec31b6a3229167d0abb5e58..f463f78a99ab738bc0117ad3391817145323c146 100644 (file)
@@ -1,5 +1,3 @@
-// edition:2018
-
 // Regression test for https://github.com/rust-lang/rust-clippy/issues/5207
 
 pub async fn bar<'a, T: 'a>(_: T) {}
index 2e3d9fd1e9240ed097512ca6216325968fa4c078..0ccf0aae9d74298099fd483995d2d73ce76763b3 100644 (file)
@@ -1,6 +1,5 @@
 // originally from glacier fixed/77919.rs
 // encountered errors resolving bounds after type-checking
-
 trait TypeVal<T> {
     const VAL: T;
 }
index eaa5e6f51cb4abd51ed518386e1fb9a867061237..c8239897f3abb5b7032d8f574aeae103599b1e71 100644 (file)
@@ -1,16 +1,20 @@
 error[E0412]: cannot find type `PhantomData` in this scope
-  --> $DIR/ice-6252.rs:9:9
+  --> $DIR/ice-6252.rs:8:9
    |
 LL |     _n: PhantomData,
    |         ^^^^^^^^^^^ not found in this scope
    |
-help: consider importing this struct
+help: consider importing one of these items
+   |
+LL | use core::marker::PhantomData;
+   |
+LL | use serde::__private::PhantomData;
    |
 LL | use std::marker::PhantomData;
    |
 
 error[E0412]: cannot find type `VAL` in this scope
-  --> $DIR/ice-6252.rs:11:63
+  --> $DIR/ice-6252.rs:10:63
    |
 LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
    |          -                                                    ^^^ not found in this scope
@@ -18,7 +22,7 @@ LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
    |          help: you might be missing a type parameter: `, VAL`
 
 error[E0046]: not all trait items implemented, missing: `VAL`
-  --> $DIR/ice-6252.rs:11:1
+  --> $DIR/ice-6252.rs:10:1
    |
 LL |     const VAL: T;
    |     ------------- `VAL` from trait
index 5595d8d1d626978d136f7c61e26daa74a07010dd..4ad0d351372f7559de26a2a84d6974f0cdf3643a 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![allow(clippy::never_loop)]
 
 async fn f() {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7868.rs b/src/tools/clippy/tests/ui/crashes/ice-7868.rs
new file mode 100644 (file)
index 0000000..c693216
--- /dev/null
@@ -0,0 +1,7 @@
+#![warn(clippy::undocumented_unsafe_blocks)]
+#![allow(clippy::no_effect)]
+
+#[path = "auxiliary/ice-7868-aux.rs"]
+mod zero;
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
new file mode 100644 (file)
index 0000000..d7b49eb
--- /dev/null
@@ -0,0 +1,15 @@
+error: unsafe block missing a safety comment
+  --> $DIR/auxiliary/ice-7868-aux.rs:2:5
+   |
+LL |     unsafe { 0 };
+   |     ^^^^^^^^^^^^
+   |
+   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
+help: consider adding a safety comment
+   |
+LL ~     // Safety: ...
+LL ~     unsafe { 0 };
+   |
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7869.rs b/src/tools/clippy/tests/ui/crashes/ice-7869.rs
new file mode 100644 (file)
index 0000000..8f97a06
--- /dev/null
@@ -0,0 +1,7 @@
+enum Tila {
+    TyöAlkoi,
+    TyöKeskeytyi,
+    TyöValmis,
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7869.stderr b/src/tools/clippy/tests/ui/crashes/ice-7869.stderr
new file mode 100644 (file)
index 0000000..4fa9fb2
--- /dev/null
@@ -0,0 +1,15 @@
+error: all variants have the same prefix: `Työ`
+  --> $DIR/ice-7869.rs:1:1
+   |
+LL | / enum Tila {
+LL | |     TyöAlkoi,
+LL | |     TyöKeskeytyi,
+LL | |     TyöValmis,
+LL | | }
+   | |_^
+   |
+   = note: `-D clippy::enum-variant-names` implied by `-D warnings`
+   = help: remove the prefixes and use full paths to the variants instead of glob imports
+
+error: aborting due to previous error
+
index c57a45dc7aab9b1c1f3e48dfc7e41558b6002fc9..901eb4e50398888f50747c1ba2a496703474d82e 100644 (file)
@@ -1,5 +1,3 @@
-// edition:2018
-
 use serde::Deserialize;
 
 /// Tests that we do not lint for unused underscores in a `MacroAttribute`
index 477a47118d4116587fc6526ca01f3f72edf639e2..c5de412556567ffe6718fc9ada4471dcb5e4cc8b 100644 (file)
@@ -1,9 +1,9 @@
-// compile-flags: --edition=2018
 #![feature(custom_inner_attributes)]
 #![rustfmt::skip]
 #![warn(clippy::debug_assert_with_mut_call)]
 #![allow(clippy::redundant_closure_call)]
 
+
 struct S;
 
 impl S {
index 1943d0092e6244851b9c5480a879116b788e56b9..39a2601fee9aca39e6d3882f27c8d1008ffce339 100644 (file)
@@ -1,19 +1,18 @@
-#[warn(clippy::unstable_as_slice)]
-#[warn(clippy::unstable_as_mut_slice)]
-#[warn(clippy::misaligned_transmute)]
-#[warn(clippy::unused_collect)]
-#[warn(clippy::invalid_ref)]
-#[warn(clippy::into_iter_on_array)]
-#[warn(clippy::unused_label)]
-#[warn(clippy::regex_macro)]
-#[warn(clippy::drop_bounds)]
-#[warn(clippy::temporary_cstring_as_ptr)]
-#[warn(clippy::panic_params)]
-#[warn(clippy::unknown_clippy_lints)]
-#[warn(clippy::find_map)]
-#[warn(clippy::filter_map)]
-#[warn(clippy::pub_enum_variant_names)]
-#[warn(clippy::wrong_pub_self_convention)]
-#[warn(clippy::invalid_atomic_ordering)]
+#![warn(clippy::should_assert_eq)]
+#![warn(clippy::extend_from_slice)]
+#![warn(clippy::range_step_by_zero)]
+#![warn(clippy::unstable_as_slice)]
+#![warn(clippy::unstable_as_mut_slice)]
+#![warn(clippy::misaligned_transmute)]
+#![warn(clippy::assign_ops)]
+#![warn(clippy::if_let_redundant_pattern_matching)]
+#![warn(clippy::unsafe_vector_initialization)]
+#![warn(clippy::unused_collect)]
+#![warn(clippy::replace_consts)]
+#![warn(clippy::regex_macro)]
+#![warn(clippy::find_map)]
+#![warn(clippy::filter_map)]
+#![warn(clippy::pub_enum_variant_names)]
+#![warn(clippy::wrong_pub_self_convention)]
 
 fn main() {}
index 51048e45c0677c208bb8e050edc7fa0169eb8a82..6095f134d55e0d2ea7452696adfb9a047521f077 100644 (file)
-error: lint `clippy::unstable_as_slice` has been removed: `Vec::as_slice` has been stabilized in 1.7
-  --> $DIR/deprecated.rs:1:8
+error: lint `clippy::should_assert_eq` has been removed: `assert!()` will be more flexible with RFC 2011
+  --> $DIR/deprecated.rs:1:9
    |
-LL | #[warn(clippy::unstable_as_slice)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(clippy::should_assert_eq)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D renamed-and-removed-lints` implied by `-D warnings`
 
-error: lint `clippy::unstable_as_mut_slice` has been removed: `Vec::as_mut_slice` has been stabilized in 1.7
-  --> $DIR/deprecated.rs:2:8
+error: lint `clippy::extend_from_slice` has been removed: `.extend_from_slice(_)` is a faster way to extend a Vec by a slice
+  --> $DIR/deprecated.rs:2:9
    |
-LL | #[warn(clippy::unstable_as_mut_slice)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(clippy::extend_from_slice)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::misaligned_transmute` has been removed: this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr
-  --> $DIR/deprecated.rs:3:8
+error: lint `clippy::range_step_by_zero` has been removed: `iterator.step_by(0)` panics nowadays
+  --> $DIR/deprecated.rs:3:9
    |
-LL | #[warn(clippy::misaligned_transmute)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(clippy::range_step_by_zero)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::unused_collect` has been removed: `collect` has been marked as #[must_use] in rustc and that covers all cases of this lint
-  --> $DIR/deprecated.rs:4:8
+error: lint `clippy::unstable_as_slice` has been removed: `Vec::as_slice` has been stabilized in 1.7
+  --> $DIR/deprecated.rs:4:9
    |
-LL | #[warn(clippy::unused_collect)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(clippy::unstable_as_slice)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
-  --> $DIR/deprecated.rs:5:8
+error: lint `clippy::unstable_as_mut_slice` has been removed: `Vec::as_mut_slice` has been stabilized in 1.7
+  --> $DIR/deprecated.rs:5:9
    |
-LL | #[warn(clippy::invalid_ref)]
-   |        ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
+LL | #![warn(clippy::unstable_as_mut_slice)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
-  --> $DIR/deprecated.rs:6:8
+error: lint `clippy::misaligned_transmute` has been removed: this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr
+  --> $DIR/deprecated.rs:6:9
    |
-LL | #[warn(clippy::into_iter_on_array)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
+LL | #![warn(clippy::misaligned_transmute)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::unused_label` has been renamed to `unused_labels`
-  --> $DIR/deprecated.rs:7:8
+error: lint `clippy::assign_ops` has been removed: using compound assignment operators (e.g., `+=`) is harmless
+  --> $DIR/deprecated.rs:7:9
    |
-LL | #[warn(clippy::unused_label)]
-   |        ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
+LL | #![warn(clippy::assign_ops)]
+   |         ^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::regex_macro` has been removed: the regex! macro has been removed from the regex crate in 2018
-  --> $DIR/deprecated.rs:8:8
+error: lint `clippy::if_let_redundant_pattern_matching` has been removed: this lint has been changed to redundant_pattern_matching
+  --> $DIR/deprecated.rs:8:9
    |
-LL | #[warn(clippy::regex_macro)]
-   |        ^^^^^^^^^^^^^^^^^^^
+LL | #![warn(clippy::if_let_redundant_pattern_matching)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
-  --> $DIR/deprecated.rs:9:8
+error: lint `clippy::unsafe_vector_initialization` has been removed: the replacement suggested by this lint had substantially different behavior
+  --> $DIR/deprecated.rs:9:9
    |
-LL | #[warn(clippy::drop_bounds)]
-   |        ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
+LL | #![warn(clippy::unsafe_vector_initialization)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
-  --> $DIR/deprecated.rs:10:8
+error: lint `clippy::unused_collect` has been removed: `collect` has been marked as #[must_use] in rustc and that covers all cases of this lint
+  --> $DIR/deprecated.rs:10:9
    |
-LL | #[warn(clippy::temporary_cstring_as_ptr)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
+LL | #![warn(clippy::unused_collect)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
-  --> $DIR/deprecated.rs:11:8
+error: lint `clippy::replace_consts` has been removed: associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants
+  --> $DIR/deprecated.rs:11:9
    |
-LL | #[warn(clippy::panic_params)]
-   |        ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
+LL | #![warn(clippy::replace_consts)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
-  --> $DIR/deprecated.rs:12:8
+error: lint `clippy::regex_macro` has been removed: the regex! macro has been removed from the regex crate in 2018
+  --> $DIR/deprecated.rs:12:9
    |
-LL | #[warn(clippy::unknown_clippy_lints)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
+LL | #![warn(clippy::regex_macro)]
+   |         ^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::find_map` has been removed: this lint has been replaced by `manual_find_map`, a more specific lint
-  --> $DIR/deprecated.rs:13:8
+  --> $DIR/deprecated.rs:13:9
    |
-LL | #[warn(clippy::find_map)]
-   |        ^^^^^^^^^^^^^^^^
+LL | #![warn(clippy::find_map)]
+   |         ^^^^^^^^^^^^^^^^
 
 error: lint `clippy::filter_map` has been removed: this lint has been replaced by `manual_filter_map`, a more specific lint
-  --> $DIR/deprecated.rs:14:8
+  --> $DIR/deprecated.rs:14:9
    |
-LL | #[warn(clippy::filter_map)]
-   |        ^^^^^^^^^^^^^^^^^^
+LL | #![warn(clippy::filter_map)]
+   |         ^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::pub_enum_variant_names` has been removed: set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items
-  --> $DIR/deprecated.rs:15:8
+  --> $DIR/deprecated.rs:15:9
    |
-LL | #[warn(clippy::pub_enum_variant_names)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(clippy::pub_enum_variant_names)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::wrong_pub_self_convention` has been removed: set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items
-  --> $DIR/deprecated.rs:16:8
-   |
-LL | #[warn(clippy::wrong_pub_self_convention)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
-  --> $DIR/deprecated.rs:17:8
+  --> $DIR/deprecated.rs:16:9
    |
-LL | #[warn(clippy::invalid_atomic_ordering)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
+LL | #![warn(clippy::wrong_pub_self_convention)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 17 previous errors
+error: aborting due to 16 previous errors
 
index 4df241c9fc39be35b1fe3a00ac017e637ad69e82..e27f9fea708ee16c0bcfd889cf27ad6ed7b39b8d 100644 (file)
@@ -1,6 +1,5 @@
 #![warn(clippy::diverging_sub_expression)]
 #![allow(clippy::match_same_arms, clippy::logic_bug)]
-
 #[allow(clippy::empty_loop)]
 fn diverge() -> ! {
     loop {}
index 170e7d92de4acff6b643a1ead8d762e2d61e2d8b..c712a6a7e38eaf1433c0aee8f46e4897612370a7 100644 (file)
@@ -1,5 +1,5 @@
 error: sub-expression diverges
-  --> $DIR/diverging_sub_expression.rs:20:10
+  --> $DIR/diverging_sub_expression.rs:19:10
    |
 LL |     b || diverge();
    |          ^^^^^^^^^
@@ -7,34 +7,42 @@ LL |     b || diverge();
    = note: `-D clippy::diverging-sub-expression` implied by `-D warnings`
 
 error: sub-expression diverges
-  --> $DIR/diverging_sub_expression.rs:21:10
+  --> $DIR/diverging_sub_expression.rs:20:10
    |
 LL |     b || A.foo();
    |          ^^^^^^^
 
 error: sub-expression diverges
-  --> $DIR/diverging_sub_expression.rs:30:26
+  --> $DIR/diverging_sub_expression.rs:29:26
    |
 LL |             6 => true || return,
    |                          ^^^^^^
 
 error: sub-expression diverges
-  --> $DIR/diverging_sub_expression.rs:31:26
+  --> $DIR/diverging_sub_expression.rs:30:26
    |
 LL |             7 => true || continue,
    |                          ^^^^^^^^
 
 error: sub-expression diverges
-  --> $DIR/diverging_sub_expression.rs:34:26
+  --> $DIR/diverging_sub_expression.rs:33:26
    |
 LL |             3 => true || diverge(),
    |                          ^^^^^^^^^
 
 error: sub-expression diverges
-  --> $DIR/diverging_sub_expression.rs:39:26
+  --> $DIR/diverging_sub_expression.rs:36:30
+   |
+LL |                 _ => true || panic!("boo"),
+   |                              ^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: sub-expression diverges
+  --> $DIR/diverging_sub_expression.rs:38:26
    |
 LL |             _ => true || break,
    |                          ^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
new file mode 100644 (file)
index 0000000..747801b
--- /dev/null
@@ -0,0 +1,215 @@
+// run-rustfix
+//! This file tests for the `DOC_MARKDOWN` lint.
+
+#![allow(dead_code, incomplete_features)]
+#![warn(clippy::doc_markdown)]
+#![feature(custom_inner_attributes, generic_const_exprs, const_option)]
+#![rustfmt::skip]
+
+/// The `foo_bar` function does _nothing_. See also `foo::bar`. (note the dot there)
+/// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun`
+/// which should be reported only once despite being __doubly bad__.
+/// Here be `::a::global:path`, and _`::another::global::path`_.  :: is not a path though.
+/// Import an item from `::awesome::global::blob::` (Intended postfix)
+/// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted)
+/// That's not code ~`NotInCodeBlock`~.
+/// `be_sure_we_got_to_the_end_of_it`
+fn foo_bar() {
+}
+
+/// That one tests multiline ticks.
+/// ```rust
+/// foo_bar FOO_BAR
+/// _foo bar_
+/// ```
+///
+/// ~~~rust
+/// foo_bar FOO_BAR
+/// _foo bar_
+/// ~~~
+/// `be_sure_we_got_to_the_end_of_it`
+fn multiline_codeblock() {
+}
+
+/// This _is a test for
+/// multiline
+/// emphasis_.
+/// `be_sure_we_got_to_the_end_of_it`
+fn test_emphasis() {
+}
+
+/// This tests units. See also #835.
+/// kiB MiB GiB TiB PiB EiB
+/// kib Mib Gib Tib Pib Eib
+/// kB MB GB TB PB EB
+/// kb Mb Gb Tb Pb Eb
+/// 32kiB 32MiB 32GiB 32TiB 32PiB 32EiB
+/// 32kib 32Mib 32Gib 32Tib 32Pib 32Eib
+/// 32kB 32MB 32GB 32TB 32PB 32EB
+/// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb
+/// NaN
+/// `be_sure_we_got_to_the_end_of_it`
+fn test_units() {
+}
+
+/// This tests allowed identifiers.
+/// KiB MiB GiB TiB PiB EiB
+/// DirectX
+/// ECMAScript
+/// GPLv2 GPLv3
+/// GitHub GitLab
+/// IPv4 IPv6
+/// ClojureScript CoffeeScript JavaScript PureScript TypeScript
+/// NaN NaNs
+/// OAuth GraphQL
+/// OCaml
+/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS
+/// WebGL
+/// TensorFlow
+/// TrueType
+/// iOS macOS FreeBSD
+/// TeX LaTeX BibTeX BibLaTeX
+/// MinGW
+/// CamelCase (see also #2395)
+/// `be_sure_we_got_to_the_end_of_it`
+fn test_allowed() {
+}
+
+/// This test has [a `link_with_underscores`][chunked-example] inside it. See #823.
+/// See also [the issue tracker](https://github.com/rust-lang/rust-clippy/search?q=clippy::doc_markdown&type=Issues)
+/// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link].
+/// It can also be [`inline_link2`].
+///
+/// [chunked-example]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Example
+/// [inline_link]: https://foobar
+/// [inline_link2]: https://foobar
+/// The `main` function is the entry point of the program. Here it only calls the `foo_bar` and
+/// `multiline_ticks` functions.
+///
+/// expression of the type  `_ <bit_op> m <cmp_op> c` (where `<bit_op>`
+/// is one of {`&`, '|'} and `<cmp_op>` is one of {`!=`, `>=`, `>` ,
+/// `be_sure_we_got_to_the_end_of_it`
+fn main() {
+    foo_bar();
+    multiline_codeblock();
+    test_emphasis();
+    test_units();
+}
+
+/// ## `CamelCaseThing`
+/// Talks about `CamelCaseThing`. Titles should be ignored; see issue #897.
+///
+/// # `CamelCaseThing`
+///
+/// Not a title #897 `CamelCaseThing`
+/// `be_sure_we_got_to_the_end_of_it`
+fn issue897() {
+}
+
+/// I am confused by brackets? (`x_y`)
+/// I am confused by brackets? (foo `x_y`)
+/// I am confused by brackets? (`x_y` foo)
+/// `be_sure_we_got_to_the_end_of_it`
+fn issue900() {
+}
+
+/// Diesel queries also have a similar problem to [Iterator][iterator], where
+/// /// More talking
+/// returning them from a function requires exposing the implementation of that
+/// function. The [`helper_types`][helper_types] module exists to help with this,
+/// but you might want to hide the return type or have it conditionally change.
+/// Boxing can achieve both.
+///
+/// [iterator]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html
+/// [helper_types]: ../helper_types/index.html
+/// `be_sure_we_got_to_the_end_of_it`
+fn issue883() {
+}
+
+/// `foo_bar
+/// baz_quz`
+/// [foo
+/// bar](https://doc.rust-lang.org/stable/std/iter/trait.IteratorFooBar.html)
+fn multiline() {
+}
+
+/** E.g., serialization of an empty list: `FooBar`
+```
+That's in a code block: `PackedNode`
+```
+
+And `BarQuz` too.
+`be_sure_we_got_to_the_end_of_it`
+*/
+fn issue1073() {
+}
+
+/** E.g., serialization of an empty list: `FooBar`
+```
+That's in a code block: PackedNode
+```
+
+And `BarQuz` too.
+`be_sure_we_got_to_the_end_of_it`
+*/
+fn issue1073_alt() {
+}
+
+/// Tests more than three quotes:
+/// ````
+/// DoNotWarn
+/// ```
+/// StillDont
+/// ````
+/// `be_sure_we_got_to_the_end_of_it`
+fn four_quotes() {
+}
+
+#[cfg_attr(feature = "a", doc = " ```")]
+#[cfg_attr(not(feature = "a"), doc = " ```ignore")]
+/// fn main() {
+///     let s = "localhost:10000".to_string();
+///     println!("{}", s);
+/// }
+/// ```
+fn issue_1469() {}
+
+/**
+ * This is a doc comment that should not be a list
+ *This would also be an error under a strict common mark interpretation
+ */
+fn issue_1920() {}
+
+/// An iterator over `mycrate::Collection`'s values.
+/// It should not lint a `'static` lifetime in ticks.
+fn issue_2210() {}
+
+/// This should not cause the lint to trigger:
+/// #REQ-data-family.lint_partof_exists
+fn issue_2343() {}
+
+/// This should not cause an ICE:
+/// __|_ _|__||_|
+fn pulldown_cmark_crash() {}
+
+/// This should not lint
+/// (regression test for #7758)
+/// [plain text][path::to::item]
+fn intra_doc_link() {}
+
+// issue #7033 - generic_const_exprs ICE
+struct S<T, const N: usize>
+where [(); N.checked_next_power_of_two().unwrap()]: {
+    arr: [T; N.checked_next_power_of_two().unwrap()],
+    n: usize,
+}
+
+impl<T: Copy + Default, const N: usize> S<T, N>
+where [(); N.checked_next_power_of_two().unwrap()]: {
+    fn new() -> Self {
+        Self {
+            arr: [T::default(); N.checked_next_power_of_two().unwrap()],
+            n: 0,
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
new file mode 100644 (file)
index 0000000..f3cf966
--- /dev/null
@@ -0,0 +1,215 @@
+// run-rustfix
+//! This file tests for the `DOC_MARKDOWN` lint.
+
+#![allow(dead_code, incomplete_features)]
+#![warn(clippy::doc_markdown)]
+#![feature(custom_inner_attributes, generic_const_exprs, const_option)]
+#![rustfmt::skip]
+
+/// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
+/// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun
+/// which should be reported only once despite being __doubly bad__.
+/// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.
+/// Import an item from ::awesome::global::blob:: (Intended postfix)
+/// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted)
+/// That's not code ~NotInCodeBlock~.
+/// be_sure_we_got_to_the_end_of_it
+fn foo_bar() {
+}
+
+/// That one tests multiline ticks.
+/// ```rust
+/// foo_bar FOO_BAR
+/// _foo bar_
+/// ```
+///
+/// ~~~rust
+/// foo_bar FOO_BAR
+/// _foo bar_
+/// ~~~
+/// be_sure_we_got_to_the_end_of_it
+fn multiline_codeblock() {
+}
+
+/// This _is a test for
+/// multiline
+/// emphasis_.
+/// be_sure_we_got_to_the_end_of_it
+fn test_emphasis() {
+}
+
+/// This tests units. See also #835.
+/// kiB MiB GiB TiB PiB EiB
+/// kib Mib Gib Tib Pib Eib
+/// kB MB GB TB PB EB
+/// kb Mb Gb Tb Pb Eb
+/// 32kiB 32MiB 32GiB 32TiB 32PiB 32EiB
+/// 32kib 32Mib 32Gib 32Tib 32Pib 32Eib
+/// 32kB 32MB 32GB 32TB 32PB 32EB
+/// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb
+/// NaN
+/// be_sure_we_got_to_the_end_of_it
+fn test_units() {
+}
+
+/// This tests allowed identifiers.
+/// KiB MiB GiB TiB PiB EiB
+/// DirectX
+/// ECMAScript
+/// GPLv2 GPLv3
+/// GitHub GitLab
+/// IPv4 IPv6
+/// ClojureScript CoffeeScript JavaScript PureScript TypeScript
+/// NaN NaNs
+/// OAuth GraphQL
+/// OCaml
+/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS
+/// WebGL
+/// TensorFlow
+/// TrueType
+/// iOS macOS FreeBSD
+/// TeX LaTeX BibTeX BibLaTeX
+/// MinGW
+/// CamelCase (see also #2395)
+/// be_sure_we_got_to_the_end_of_it
+fn test_allowed() {
+}
+
+/// This test has [a link_with_underscores][chunked-example] inside it. See #823.
+/// See also [the issue tracker](https://github.com/rust-lang/rust-clippy/search?q=clippy::doc_markdown&type=Issues)
+/// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link].
+/// It can also be [inline_link2].
+///
+/// [chunked-example]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Example
+/// [inline_link]: https://foobar
+/// [inline_link2]: https://foobar
+/// The `main` function is the entry point of the program. Here it only calls the `foo_bar` and
+/// `multiline_ticks` functions.
+///
+/// expression of the type  `_ <bit_op> m <cmp_op> c` (where `<bit_op>`
+/// is one of {`&`, '|'} and `<cmp_op>` is one of {`!=`, `>=`, `>` ,
+/// be_sure_we_got_to_the_end_of_it
+fn main() {
+    foo_bar();
+    multiline_codeblock();
+    test_emphasis();
+    test_units();
+}
+
+/// ## CamelCaseThing
+/// Talks about `CamelCaseThing`. Titles should be ignored; see issue #897.
+///
+/// # CamelCaseThing
+///
+/// Not a title #897 CamelCaseThing
+/// be_sure_we_got_to_the_end_of_it
+fn issue897() {
+}
+
+/// I am confused by brackets? (`x_y`)
+/// I am confused by brackets? (foo `x_y`)
+/// I am confused by brackets? (`x_y` foo)
+/// be_sure_we_got_to_the_end_of_it
+fn issue900() {
+}
+
+/// Diesel queries also have a similar problem to [Iterator][iterator], where
+/// /// More talking
+/// returning them from a function requires exposing the implementation of that
+/// function. The [`helper_types`][helper_types] module exists to help with this,
+/// but you might want to hide the return type or have it conditionally change.
+/// Boxing can achieve both.
+///
+/// [iterator]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html
+/// [helper_types]: ../helper_types/index.html
+/// be_sure_we_got_to_the_end_of_it
+fn issue883() {
+}
+
+/// `foo_bar
+/// baz_quz`
+/// [foo
+/// bar](https://doc.rust-lang.org/stable/std/iter/trait.IteratorFooBar.html)
+fn multiline() {
+}
+
+/** E.g., serialization of an empty list: FooBar
+```
+That's in a code block: `PackedNode`
+```
+
+And BarQuz too.
+be_sure_we_got_to_the_end_of_it
+*/
+fn issue1073() {
+}
+
+/** E.g., serialization of an empty list: FooBar
+```
+That's in a code block: PackedNode
+```
+
+And BarQuz too.
+be_sure_we_got_to_the_end_of_it
+*/
+fn issue1073_alt() {
+}
+
+/// Tests more than three quotes:
+/// ````
+/// DoNotWarn
+/// ```
+/// StillDont
+/// ````
+/// be_sure_we_got_to_the_end_of_it
+fn four_quotes() {
+}
+
+#[cfg_attr(feature = "a", doc = " ```")]
+#[cfg_attr(not(feature = "a"), doc = " ```ignore")]
+/// fn main() {
+///     let s = "localhost:10000".to_string();
+///     println!("{}", s);
+/// }
+/// ```
+fn issue_1469() {}
+
+/**
+ * This is a doc comment that should not be a list
+ *This would also be an error under a strict common mark interpretation
+ */
+fn issue_1920() {}
+
+/// An iterator over mycrate::Collection's values.
+/// It should not lint a `'static` lifetime in ticks.
+fn issue_2210() {}
+
+/// This should not cause the lint to trigger:
+/// #REQ-data-family.lint_partof_exists
+fn issue_2343() {}
+
+/// This should not cause an ICE:
+/// __|_ _|__||_|
+fn pulldown_cmark_crash() {}
+
+/// This should not lint
+/// (regression test for #7758)
+/// [plain text][path::to::item]
+fn intra_doc_link() {}
+
+// issue #7033 - generic_const_exprs ICE
+struct S<T, const N: usize>
+where [(); N.checked_next_power_of_two().unwrap()]: {
+    arr: [T; N.checked_next_power_of_two().unwrap()],
+    n: usize,
+}
+
+impl<T: Copy + Default, const N: usize> S<T, N>
+where [(); N.checked_next_power_of_two().unwrap()]: {
+    fn new() -> Self {
+        Self {
+            arr: [T::default(); N.checked_next_power_of_two().unwrap()],
+            n: 0,
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
new file mode 100644 (file)
index 0000000..31132f8
--- /dev/null
@@ -0,0 +1,184 @@
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:9:9
+   |
+LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
+   |         ^^^^^^^ help: try: ``foo_bar``
+   |
+   = note: `-D clippy::doc-markdown` implied by `-D warnings`
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:9:51
+   |
+LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
+   |                                                   ^^^^^^^^ help: try: ``foo::bar``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:10:83
+   |
+LL | /// Markdown is _weird_. I mean _really weird_. This /_ is ok. So is `_`. But not Foo::some_fun
+   |                                                                                   ^^^^^^^^^^^^^ help: try: ``Foo::some_fun``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:12:13
+   |
+LL | /// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.
+   |             ^^^^^^^^^^^^^^^^ help: try: ``::a::global:path``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:12:36
+   |
+LL | /// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``::another::global::path``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:13:25
+   |
+LL | /// Import an item from ::awesome::global::blob:: (Intended postfix)
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``::awesome::global::blob::``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:14:31
+   |
+LL | /// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted)
+   |                               ^^^^^ help: try: ``::Cat``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:15:22
+   |
+LL | /// That's not code ~NotInCodeBlock~.
+   |                      ^^^^^^^^^^^^^^ help: try: ``NotInCodeBlock``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:16:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:30:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:37:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:51:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:74:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:78:22
+   |
+LL | /// This test has [a link_with_underscores][chunked-example] inside it. See #823.
+   |                      ^^^^^^^^^^^^^^^^^^^^^ help: try: ``link_with_underscores``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:81:21
+   |
+LL | /// It can also be [inline_link2].
+   |                     ^^^^^^^^^^^^ help: try: ``inline_link2``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:91:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:99:8
+   |
+LL | /// ## CamelCaseThing
+   |        ^^^^^^^^^^^^^^ help: try: ``CamelCaseThing``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:102:7
+   |
+LL | /// # CamelCaseThing
+   |       ^^^^^^^^^^^^^^ help: try: ``CamelCaseThing``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:104:22
+   |
+LL | /// Not a title #897 CamelCaseThing
+   |                      ^^^^^^^^^^^^^^ help: try: ``CamelCaseThing``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:105:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:112:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:125:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:136:43
+   |
+LL | /** E.g., serialization of an empty list: FooBar
+   |                                           ^^^^^^ help: try: ``FooBar``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:141:5
+   |
+LL | And BarQuz too.
+   |     ^^^^^^ help: try: ``BarQuz``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:142:1
+   |
+LL | be_sure_we_got_to_the_end_of_it
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:147:43
+   |
+LL | /** E.g., serialization of an empty list: FooBar
+   |                                           ^^^^^^ help: try: ``FooBar``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:152:5
+   |
+LL | And BarQuz too.
+   |     ^^^^^^ help: try: ``BarQuz``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:153:1
+   |
+LL | be_sure_we_got_to_the_end_of_it
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:164:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: ``be_sure_we_got_to_the_end_of_it``
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:183:22
+   |
+LL | /// An iterator over mycrate::Collection's values.
+   |                      ^^^^^^^^^^^^^^^^^^^ help: try: ``mycrate::Collection``
+
+error: aborting due to 30 previous errors
+
diff --git a/src/tools/clippy/tests/ui/doc/doc.rs b/src/tools/clippy/tests/ui/doc/doc.rs
deleted file mode 100644 (file)
index 342208e..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-//! This file tests for the `DOC_MARKDOWN` lint.
-
-#![allow(dead_code, incomplete_features)]
-#![warn(clippy::doc_markdown)]
-#![feature(custom_inner_attributes, generic_const_exprs, const_option)]
-#![rustfmt::skip]
-
-/// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
-/// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun
-/// which should be reported only once despite being __doubly bad__.
-/// Here be ::a::global:path.
-/// That's not code ~NotInCodeBlock~.
-/// be_sure_we_got_to_the_end_of_it
-fn foo_bar() {
-}
-
-/// That one tests multiline ticks.
-/// ```rust
-/// foo_bar FOO_BAR
-/// _foo bar_
-/// ```
-///
-/// ~~~rust
-/// foo_bar FOO_BAR
-/// _foo bar_
-/// ~~~
-/// be_sure_we_got_to_the_end_of_it
-fn multiline_codeblock() {
-}
-
-/// This _is a test for
-/// multiline
-/// emphasis_.
-/// be_sure_we_got_to_the_end_of_it
-fn test_emphasis() {
-}
-
-/// This tests units. See also #835.
-/// kiB MiB GiB TiB PiB EiB
-/// kib Mib Gib Tib Pib Eib
-/// kB MB GB TB PB EB
-/// kb Mb Gb Tb Pb Eb
-/// 32kiB 32MiB 32GiB 32TiB 32PiB 32EiB
-/// 32kib 32Mib 32Gib 32Tib 32Pib 32Eib
-/// 32kB 32MB 32GB 32TB 32PB 32EB
-/// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb
-/// NaN
-/// be_sure_we_got_to_the_end_of_it
-fn test_units() {
-}
-
-/// This tests allowed identifiers.
-/// KiB MiB GiB TiB PiB EiB
-/// DirectX
-/// ECMAScript
-/// GPLv2 GPLv3
-/// GitHub GitLab
-/// IPv4 IPv6
-/// ClojureScript CoffeeScript JavaScript PureScript TypeScript
-/// NaN NaNs
-/// OAuth GraphQL
-/// OCaml
-/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS
-/// WebGL
-/// TensorFlow
-/// TrueType
-/// iOS macOS FreeBSD
-/// TeX LaTeX BibTeX BibLaTeX
-/// MinGW
-/// CamelCase (see also #2395)
-/// be_sure_we_got_to_the_end_of_it
-fn test_allowed() {
-}
-
-/// This test has [a link_with_underscores][chunked-example] inside it. See #823.
-/// See also [the issue tracker](https://github.com/rust-lang/rust-clippy/search?q=clippy::doc_markdown&type=Issues)
-/// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link].
-/// It can also be [inline_link2].
-///
-/// [chunked-example]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Example
-/// [inline_link]: https://foobar
-/// [inline_link2]: https://foobar
-/// The `main` function is the entry point of the program. Here it only calls the `foo_bar` and
-/// `multiline_ticks` functions.
-///
-/// expression of the type  `_ <bit_op> m <cmp_op> c` (where `<bit_op>`
-/// is one of {`&`, '|'} and `<cmp_op>` is one of {`!=`, `>=`, `>` ,
-/// be_sure_we_got_to_the_end_of_it
-fn main() {
-    foo_bar();
-    multiline_codeblock();
-    test_emphasis();
-    test_units();
-}
-
-/// ## CamelCaseThing
-/// Talks about `CamelCaseThing`. Titles should be ignored; see issue #897.
-///
-/// # CamelCaseThing
-///
-/// Not a title #897 CamelCaseThing
-/// be_sure_we_got_to_the_end_of_it
-fn issue897() {
-}
-
-/// I am confused by brackets? (`x_y`)
-/// I am confused by brackets? (foo `x_y`)
-/// I am confused by brackets? (`x_y` foo)
-/// be_sure_we_got_to_the_end_of_it
-fn issue900() {
-}
-
-/// Diesel queries also have a similar problem to [Iterator][iterator], where
-/// /// More talking
-/// returning them from a function requires exposing the implementation of that
-/// function. The [`helper_types`][helper_types] module exists to help with this,
-/// but you might want to hide the return type or have it conditionally change.
-/// Boxing can achieve both.
-///
-/// [iterator]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html
-/// [helper_types]: ../helper_types/index.html
-/// be_sure_we_got_to_the_end_of_it
-fn issue883() {
-}
-
-/// `foo_bar
-/// baz_quz`
-/// [foo
-/// bar](https://doc.rust-lang.org/stable/std/iter/trait.IteratorFooBar.html)
-fn multiline() {
-}
-
-/** E.g., serialization of an empty list: FooBar
-```
-That's in a code block: `PackedNode`
-```
-
-And BarQuz too.
-be_sure_we_got_to_the_end_of_it
-*/
-fn issue1073() {
-}
-
-/** E.g., serialization of an empty list: FooBar
-```
-That's in a code block: PackedNode
-```
-
-And BarQuz too.
-be_sure_we_got_to_the_end_of_it
-*/
-fn issue1073_alt() {
-}
-
-/// Tests more than three quotes:
-/// ````
-/// DoNotWarn
-/// ```
-/// StillDont
-/// ````
-/// be_sure_we_got_to_the_end_of_it
-fn four_quotes() {
-}
-
-/// See [NIST SP 800-56A, revision 2].
-///
-/// [NIST SP 800-56A, revision 2]:
-///     https://github.com/rust-lang/rust-clippy/issues/902#issuecomment-261919419
-fn issue_902_comment() {}
-
-#[cfg_attr(feature = "a", doc = " ```")]
-#[cfg_attr(not(feature = "a"), doc = " ```ignore")]
-/// fn main() {
-///     let s = "localhost:10000".to_string();
-///     println!("{}", s);
-/// }
-/// ```
-fn issue_1469() {}
-
-/**
- * This is a doc comment that should not be a list
- *This would also be an error under a strict common mark interpretation
- */
-fn issue_1920() {}
-
-/// Ok: <http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels>
-///
-/// Not ok: http://www.unicode.org
-/// Not ok: https://www.unicode.org
-/// Not ok: http://www.unicode.org/
-/// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
-fn issue_1832() {}
-
-/// An iterator over mycrate::Collection's values.
-/// It should not lint a `'static` lifetime in ticks.
-fn issue_2210() {}
-
-/// This should not cause the lint to trigger:
-/// #REQ-data-family.lint_partof_exists
-fn issue_2343() {}
-
-/// This should not cause an ICE:
-/// __|_ _|__||_|
-fn pulldown_cmark_crash() {}
-
-/// This should not lint
-/// (regression test for #7758)
-/// [plain text][path::to::item]
-fn intra_doc_link() {}
-
-// issue #7033 - generic_const_exprs ICE
-struct S<T, const N: usize>
-where [(); N.checked_next_power_of_two().unwrap()]: {
-    arr: [T; N.checked_next_power_of_two().unwrap()],
-    n: usize,
-}
-
-impl<T: Copy + Default, const N: usize> S<T, N>
-where [(); N.checked_next_power_of_two().unwrap()]: {
-    fn new() -> Self {
-        Self {
-            arr: [T::default(); N.checked_next_power_of_two().unwrap()],
-            n: 0,
-        }
-    }
-}
diff --git a/src/tools/clippy/tests/ui/doc/doc.stderr b/src/tools/clippy/tests/ui/doc/doc.stderr
deleted file mode 100644 (file)
index 7eab8a8..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-error: you should put `foo_bar` between ticks in the documentation
-  --> $DIR/doc.rs:8:9
-   |
-LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
-   |         ^^^^^^^
-   |
-   = note: `-D clippy::doc-markdown` implied by `-D warnings`
-
-error: you should put `foo::bar` between ticks in the documentation
-  --> $DIR/doc.rs:8:51
-   |
-LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
-   |                                                   ^^^^^^^^
-
-error: you should put `Foo::some_fun` between ticks in the documentation
-  --> $DIR/doc.rs:9:83
-   |
-LL | /// Markdown is _weird_. I mean _really weird_. This /_ is ok. So is `_`. But not Foo::some_fun
-   |                                                                                   ^^^^^^^^^^^^^
-
-error: you should put `a::global:path` between ticks in the documentation
-  --> $DIR/doc.rs:11:15
-   |
-LL | /// Here be ::a::global:path.
-   |               ^^^^^^^^^^^^^^
-
-error: you should put `NotInCodeBlock` between ticks in the documentation
-  --> $DIR/doc.rs:12:22
-   |
-LL | /// That's not code ~NotInCodeBlock~.
-   |                      ^^^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:13:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:27:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:34:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:48:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:71:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `link_with_underscores` between ticks in the documentation
-  --> $DIR/doc.rs:75:22
-   |
-LL | /// This test has [a link_with_underscores][chunked-example] inside it. See #823.
-   |                      ^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `inline_link2` between ticks in the documentation
-  --> $DIR/doc.rs:78:21
-   |
-LL | /// It can also be [inline_link2].
-   |                     ^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:88:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `CamelCaseThing` between ticks in the documentation
-  --> $DIR/doc.rs:96:8
-   |
-LL | /// ## CamelCaseThing
-   |        ^^^^^^^^^^^^^^
-
-error: you should put `CamelCaseThing` between ticks in the documentation
-  --> $DIR/doc.rs:99:7
-   |
-LL | /// # CamelCaseThing
-   |       ^^^^^^^^^^^^^^
-
-error: you should put `CamelCaseThing` between ticks in the documentation
-  --> $DIR/doc.rs:101:22
-   |
-LL | /// Not a title #897 CamelCaseThing
-   |                      ^^^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:102:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:109:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:122:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `FooBar` between ticks in the documentation
-  --> $DIR/doc.rs:133:43
-   |
-LL | /** E.g., serialization of an empty list: FooBar
-   |                                           ^^^^^^
-
-error: you should put `BarQuz` between ticks in the documentation
-  --> $DIR/doc.rs:138:5
-   |
-LL | And BarQuz too.
-   |     ^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:139:1
-   |
-LL | be_sure_we_got_to_the_end_of_it
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `FooBar` between ticks in the documentation
-  --> $DIR/doc.rs:144:43
-   |
-LL | /** E.g., serialization of an empty list: FooBar
-   |                                           ^^^^^^
-
-error: you should put `BarQuz` between ticks in the documentation
-  --> $DIR/doc.rs:149:5
-   |
-LL | And BarQuz too.
-   |     ^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:150:1
-   |
-LL | be_sure_we_got_to_the_end_of_it
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:161:5
-   |
-LL | /// be_sure_we_got_to_the_end_of_it
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:188:13
-   |
-LL | /// Not ok: http://www.unicode.org
-   |             ^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:189:13
-   |
-LL | /// Not ok: https://www.unicode.org
-   |             ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:190:13
-   |
-LL | /// Not ok: http://www.unicode.org/
-   |             ^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:191:13
-   |
-LL | /// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: you should put `mycrate::Collection` between ticks in the documentation
-  --> $DIR/doc.rs:194:22
-   |
-LL | /// An iterator over mycrate::Collection's values.
-   |                      ^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 31 previous errors
-
diff --git a/src/tools/clippy/tests/ui/doc/issue_1832.rs b/src/tools/clippy/tests/ui/doc/issue_1832.rs
new file mode 100644 (file)
index 0000000..10586f1
--- /dev/null
@@ -0,0 +1,9 @@
+/// Ok: <http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels>
+///
+/// Not ok: http://www.unicode.org
+/// Not ok: https://www.unicode.org
+/// Not ok: http://www.unicode.org/
+/// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
+fn issue_1832() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/doc/issue_902.rs b/src/tools/clippy/tests/ui/doc/issue_902.rs
new file mode 100644 (file)
index 0000000..4b0c835
--- /dev/null
@@ -0,0 +1,7 @@
+/// See [NIST SP 800-56A, revision 2].
+///
+/// [NIST SP 800-56A, revision 2]:
+///     https://github.com/rust-lang/rust-clippy/issues/902#issuecomment-261919419
+fn issue_902_comment() {}
+
+fn main() {}
index 45ca34e2a8c8b34a2e6ede2509ad9367abac2709..9670e5c24fb3ecbcf5a9febdca1e2a93ddf61c07 100644 (file)
@@ -18,11 +18,11 @@ LL | /// This paragraph has `unbalanced_tick marks and should stop_linting.
    |
    = help: a backtick may be missing a pair
 
-error: you should put `should_be` between ticks in the documentation
+error: item in documentation is missing backticks
   --> $DIR/unbalanced_ticks.rs:15:32
    |
 LL | /// This paragraph is fine and should_be linted normally.
-   |                                ^^^^^^^^^
+   |                                ^^^^^^^^^ help: try: ``should_be``
 
 error: backticks are unbalanced
   --> $DIR/unbalanced_ticks.rs:17:1
@@ -32,11 +32,11 @@ LL | /// Double unbalanced backtick from ``here to here` should lint.
    |
    = help: a backtick may be missing a pair
 
-error: you should put `not_fine` between ticks in the documentation
+error: item in documentation is missing backticks
   --> $DIR/unbalanced_ticks.rs:30:8
    |
 LL | /// ## not_fine
-   |        ^^^^^^^^
+   |        ^^^^^^^^ help: try: ``not_fine``
 
 error: backticks are unbalanced
   --> $DIR/unbalanced_ticks.rs:32:1
@@ -54,11 +54,11 @@ LL | /// - This `item has unbalanced tick marks
    |
    = help: a backtick may be missing a pair
 
-error: you should put `backticks_here` between ticks in the documentation
+error: item in documentation is missing backticks
   --> $DIR/unbalanced_ticks.rs:35:23
    |
 LL | /// - This item needs backticks_here
-   |                       ^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^ help: try: ``backticks_here``
 
 error: aborting due to 8 previous errors
 
index c77a74a58f22c6072dcfb295ea22794afbe1309c..30fdd3b087371226352c9b07dd81f60119f744b3 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::missing_errors_doc)]
 #![allow(clippy::result_unit_err)]
 #![allow(clippy::unnecessary_wraps)]
index b5a81419daee35d295197158c9e20d5a17f21871..c7b616e2897087c01ee59976e37fe287afb6dbbc 100644 (file)
@@ -1,5 +1,5 @@
 error: docs for function returning `Result` missing `# Errors` section
-  --> $DIR/doc_errors.rs:8:1
+  --> $DIR/doc_errors.rs:7:1
    |
 LL | / pub fn pub_fn_missing_errors_header() -> Result<(), ()> {
 LL | |     unimplemented!();
@@ -9,7 +9,7 @@ LL | | }
    = note: `-D clippy::missing-errors-doc` implied by `-D warnings`
 
 error: docs for function returning `Result` missing `# Errors` section
-  --> $DIR/doc_errors.rs:12:1
+  --> $DIR/doc_errors.rs:11:1
    |
 LL | / pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> {
 LL | |     unimplemented!();
@@ -17,7 +17,7 @@ LL | | }
    | |_^
 
 error: docs for function returning `Result` missing `# Errors` section
-  --> $DIR/doc_errors.rs:17:1
+  --> $DIR/doc_errors.rs:16:1
    |
 LL | / pub fn pub_fn_returning_io_result() -> io::Result<()> {
 LL | |     unimplemented!();
@@ -25,7 +25,7 @@ LL | | }
    | |_^
 
 error: docs for function returning `Result` missing `# Errors` section
-  --> $DIR/doc_errors.rs:22:1
+  --> $DIR/doc_errors.rs:21:1
    |
 LL | / pub async fn async_pub_fn_returning_io_result() -> io::Result<()> {
 LL | |     unimplemented!();
@@ -33,7 +33,7 @@ LL | | }
    | |_^
 
 error: docs for function returning `Result` missing `# Errors` section
-  --> $DIR/doc_errors.rs:52:5
+  --> $DIR/doc_errors.rs:51:5
    |
 LL | /     pub fn pub_method_missing_errors_header() -> Result<(), ()> {
 LL | |         unimplemented!();
@@ -41,7 +41,7 @@ LL | |     }
    | |_____^
 
 error: docs for function returning `Result` missing `# Errors` section
-  --> $DIR/doc_errors.rs:57:5
+  --> $DIR/doc_errors.rs:56:5
    |
 LL | /     pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> {
 LL | |         unimplemented!();
@@ -49,7 +49,7 @@ LL | |     }
    | |_____^
 
 error: docs for function returning `Result` missing `# Errors` section
-  --> $DIR/doc_errors.rs:86:5
+  --> $DIR/doc_errors.rs:85:5
    |
 LL |     fn trait_method_missing_errors_header() -> Result<(), ()>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 03bb30f9083ac4f3c21ab23a635747ef8ba128fd..4464a21b3b654bdf89b238a5c0594b61edbf06ce 100644 (file)
@@ -125,3 +125,8 @@ impl T {
         pub unsafe fn f() {}
     }
 }
+
+/// # Implementation safety
+pub unsafe trait DocumentedUnsafeTraitWithImplementationHeader {
+    fn method();
+}
index 447fbb9e1bff3440c35200354408ccdeb9fe60b1..add8a91e26b85a2b9745a73053ff73d418a54cdd 100644 (file)
@@ -60,7 +60,7 @@ LL | | }
    |
    = help: remove the prefixes and use full paths to the variants instead of glob imports
 
-error: all variants have the same prefix: `With`
+error: all variants have the same prefix: `WithOut`
   --> $DIR/enum_variants.rs:81:1
    |
 LL | / enum Seallll {
index 8e6a32b7be33d2eccde04199653c2d467942f3c0..aad78319d48209549db51ff8e3de027a5b4a8b59 100644 (file)
@@ -1,5 +1,3 @@
-// edition:2018
-
 #[warn(clippy::eval_order_dependence)]
 #[allow(
     unused_assignments,
index 4f611e308e18619e50f0b408ed7c07f60c28b47d..7c6265a08790deee6d8df446b49846dab095e770 100644 (file)
@@ -1,48 +1,48 @@
 error: unsequenced read of `x`
-  --> $DIR/eval_order_dependence.rs:16:9
+  --> $DIR/eval_order_dependence.rs:14:9
    |
 LL |     } + x;
    |         ^
    |
    = note: `-D clippy::eval-order-dependence` implied by `-D warnings`
 note: whether read occurs before this write depends on evaluation order
-  --> $DIR/eval_order_dependence.rs:14:9
+  --> $DIR/eval_order_dependence.rs:12:9
    |
 LL |         x = 1;
    |         ^^^^^
 
 error: unsequenced read of `x`
-  --> $DIR/eval_order_dependence.rs:19:5
+  --> $DIR/eval_order_dependence.rs:17:5
    |
 LL |     x += {
    |     ^
    |
 note: whether read occurs before this write depends on evaluation order
-  --> $DIR/eval_order_dependence.rs:20:9
+  --> $DIR/eval_order_dependence.rs:18:9
    |
 LL |         x = 20;
    |         ^^^^^^
 
 error: unsequenced read of `x`
-  --> $DIR/eval_order_dependence.rs:32:12
+  --> $DIR/eval_order_dependence.rs:30:12
    |
 LL |         a: x,
    |            ^
    |
 note: whether read occurs before this write depends on evaluation order
-  --> $DIR/eval_order_dependence.rs:34:13
+  --> $DIR/eval_order_dependence.rs:32:13
    |
 LL |             x = 6;
    |             ^^^^^
 
 error: unsequenced read of `x`
-  --> $DIR/eval_order_dependence.rs:41:9
+  --> $DIR/eval_order_dependence.rs:39:9
    |
 LL |         x += {
    |         ^
    |
 note: whether read occurs before this write depends on evaluation order
-  --> $DIR/eval_order_dependence.rs:42:13
+  --> $DIR/eval_order_dependence.rs:40:13
    |
 LL |             x = 20;
    |             ^^^^^^
index 495cd97e05e15d472bef961da5a2e9eab1573814..5d5af4e4632970afe821f9b42b82eae5bd445e08 100644 (file)
@@ -1,5 +1,4 @@
 #![deny(clippy::fallible_impl_from)]
-#![allow(clippy::if_then_panic)]
 
 // docs example
 struct Foo(i32);
index f5d0b98c10862cd11a4db14d65c484f90c988dd4..4e0f08a1215c0401fa8f18493fb8ad0a833dcd63 100644 (file)
@@ -1,5 +1,5 @@
 error: consider implementing `TryFrom` instead
-  --> $DIR/fallible_impl_from.rs:6:1
+  --> $DIR/fallible_impl_from.rs:5:1
    |
 LL | / impl From<String> for Foo {
 LL | |     fn from(s: String) -> Self {
@@ -15,13 +15,13 @@ LL | #![deny(clippy::fallible_impl_from)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail
 note: potential failure(s)
-  --> $DIR/fallible_impl_from.rs:8:13
+  --> $DIR/fallible_impl_from.rs:7:13
    |
 LL |         Foo(s.parse().unwrap())
    |             ^^^^^^^^^^^^^^^^^^
 
 error: consider implementing `TryFrom` instead
-  --> $DIR/fallible_impl_from.rs:27:1
+  --> $DIR/fallible_impl_from.rs:26:1
    |
 LL | / impl From<usize> for Invalid {
 LL | |     fn from(i: usize) -> Invalid {
@@ -34,14 +34,14 @@ LL | | }
    |
    = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail
 note: potential failure(s)
-  --> $DIR/fallible_impl_from.rs:30:13
+  --> $DIR/fallible_impl_from.rs:29:13
    |
 LL |             panic!();
    |             ^^^^^^^^
-   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: consider implementing `TryFrom` instead
-  --> $DIR/fallible_impl_from.rs:36:1
+  --> $DIR/fallible_impl_from.rs:35:1
    |
 LL | / impl From<Option<String>> for Invalid {
 LL | |     fn from(s: Option<String>) -> Invalid {
@@ -54,7 +54,7 @@ LL | | }
    |
    = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail
 note: potential failure(s)
-  --> $DIR/fallible_impl_from.rs:38:17
+  --> $DIR/fallible_impl_from.rs:37:17
    |
 LL |         let s = s.unwrap();
    |                 ^^^^^^^^^^
@@ -65,10 +65,10 @@ LL |         } else if s.parse::<u32>().unwrap() != 42 {
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |             panic!("{:?}", s);
    |             ^^^^^^^^^^^^^^^^^
-   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: consider implementing `TryFrom` instead
-  --> $DIR/fallible_impl_from.rs:54:1
+  --> $DIR/fallible_impl_from.rs:53:1
    |
 LL | / impl<'a> From<&'a mut <Box<u32> as ProjStrTrait>::ProjString> for Invalid {
 LL | |     fn from(s: &'a mut <Box<u32> as ProjStrTrait>::ProjString) -> Invalid {
@@ -81,13 +81,13 @@ LL | | }
    |
    = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail
 note: potential failure(s)
-  --> $DIR/fallible_impl_from.rs:56:12
+  --> $DIR/fallible_impl_from.rs:55:12
    |
 LL |         if s.parse::<u32>().ok().unwrap() != 42 {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |             panic!("{:?}", s);
    |             ^^^^^^^^^^^^^^^^^
-   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 4 previous errors
 
index 73fc750511c78684cdd8650d03e6ce1dc40582b1..64cb7b1cfb80f6c33ff5e81f7af29cceb1e8b73d 100644 (file)
@@ -16,6 +16,8 @@ fn main() {
     r##"foo {}
 " bar"##.to_string();
 
+    let _ = String::new();
+
     "foo".to_string();
     format!("{:?}", "foo"); // Don't warn about `Debug`.
     format!("{:8}", "foo");
index 2f4595650cbf3c8d3cdd716e3ea32a0e24113b58..a065b1b5683c1b9ccbfeb81df5cf1b96d7d12c4d 100644 (file)
@@ -18,6 +18,8 @@ fn main() {
 " bar"##
     );
 
+    let _ = format!("");
+
     format!("{}", "foo");
     format!("{:?}", "foo"); // Don't warn about `Debug`.
     format!("{:8}", "foo");
index 701399b32d62834a9d993339b83df1f5ba8d03ab..58ad7499bb26f530c5202239ac79858ab1aaa79c 100644 (file)
@@ -34,64 +34,70 @@ LL ~ " bar"##.to_string();
    |
 
 error: useless use of `format!`
-  --> $DIR/format.rs:21:5
+  --> $DIR/format.rs:21:13
+   |
+LL |     let _ = format!("");
+   |             ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()`
+
+error: useless use of `format!`
+  --> $DIR/format.rs:23:5
    |
 LL |     format!("{}", "foo");
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:25:5
+  --> $DIR/format.rs:27:5
    |
 LL |     format!("{:+}", "foo"); // Warn when the format makes no difference.
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:26:5
+  --> $DIR/format.rs:28:5
    |
 LL |     format!("{:<}", "foo"); // Warn when the format makes no difference.
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:31:5
+  --> $DIR/format.rs:33:5
    |
 LL |     format!("{}", arg);
    |     ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:35:5
+  --> $DIR/format.rs:37:5
    |
 LL |     format!("{:+}", arg); // Warn when the format makes no difference.
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:36:5
+  --> $DIR/format.rs:38:5
    |
 LL |     format!("{:<}", arg); // Warn when the format makes no difference.
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:63:5
+  --> $DIR/format.rs:65:5
    |
 LL |     format!("{}", 42.to_string());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:65:5
+  --> $DIR/format.rs:67:5
    |
 LL |     format!("{}", x.display().to_string());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:69:18
+  --> $DIR/format.rs:71:18
    |
 LL |     let _ = Some(format!("{}", a + "bar"));
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:73:22
+  --> $DIR/format.rs:75:22
    |
 LL |     let _s: String = format!("{}", &*v.join("/n"));
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()`
 
-error: aborting due to 14 previous errors
+error: aborting due to 15 previous errors
 
index 8376566c4d62d57fcfa1c51198500c4ac517e904..69b5e1c722e0320df446f0fb6a01d74d20fead7f 100644 (file)
@@ -5,6 +5,7 @@
 #![allow(unused_variables)]
 #![allow(clippy::assertions_on_constants)]
 #![allow(clippy::eq_op)]
+#![allow(clippy::print_literal)]
 #![warn(clippy::to_string_in_format_args)]
 
 use std::io::{stdout, Write};
@@ -97,9 +98,20 @@ fn main() {
     println!("{}", Z(1));
     println!("{}", **x);
     println!("{}", ***x_ref);
+    // https://github.com/rust-lang/rust-clippy/issues/7903
+    println!("{foo}{bar}", foo = "foo", bar = "bar");
+    println!("{foo}{bar}", foo = "foo", bar = "bar");
+    println!("{foo}{bar}", bar = "bar", foo = "foo");
+    println!("{foo}{bar}", bar = "bar", foo = "foo");
 
+    // negative tests
     println!("error: something failed at {}", Somewhere.to_string());
+    // The next two tests are negative because caching the string might be faster than calling `<X as
+    // Display>::fmt` twice.
     println!("{} and again {0}", x.to_string());
+    println!("{foo}{foo}", foo = "foo".to_string());
     my_macro!();
     println!("error: something failed at {}", my_other_macro!());
+    // https://github.com/rust-lang/rust-clippy/issues/7903
+    println!("{foo}{foo:?}", foo = "foo".to_string());
 }
index 164cc07066dc3b892022b616b34f4130083c12ce..3a434c5bf002a3350a08a0da2988747de925bcc9 100644 (file)
@@ -5,6 +5,7 @@
 #![allow(unused_variables)]
 #![allow(clippy::assertions_on_constants)]
 #![allow(clippy::eq_op)]
+#![allow(clippy::print_literal)]
 #![warn(clippy::to_string_in_format_args)]
 
 use std::io::{stdout, Write};
@@ -97,9 +98,20 @@ fn main() {
     println!("{}", Z(1).to_string());
     println!("{}", x.to_string());
     println!("{}", x_ref.to_string());
+    // https://github.com/rust-lang/rust-clippy/issues/7903
+    println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar");
+    println!("{foo}{bar}", foo = "foo", bar = "bar".to_string());
+    println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo");
+    println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
 
+    // negative tests
     println!("error: something failed at {}", Somewhere.to_string());
+    // The next two tests are negative because caching the string might be faster than calling `<X as
+    // Display>::fmt` twice.
     println!("{} and again {0}", x.to_string());
+    println!("{foo}{foo}", foo = "foo".to_string());
     my_macro!();
     println!("error: something failed at {}", my_other_macro!());
+    // https://github.com/rust-lang/rust-clippy/issues/7903
+    println!("{foo}{foo:?}", foo = "foo".to_string());
 }
index 9cfc97edeafb8215fabae9014bc1b543840a650c..c0cbca507958d1306cfbf008fb3b1d16e2f3959d 100644 (file)
@@ -1,5 +1,5 @@
 error: `to_string` applied to a type that implements `Display` in `format!` args
-  --> $DIR/format_args.rs:75:72
+  --> $DIR/format_args.rs:76:72
    |
 LL |     let _ = format!("error: something failed at {}", Location::caller().to_string());
    |                                                                        ^^^^^^^^^^^^ help: remove this
@@ -7,100 +7,124 @@ LL |     let _ = format!("error: something failed at {}", Location::caller().to_
    = note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
 
 error: `to_string` applied to a type that implements `Display` in `write!` args
-  --> $DIR/format_args.rs:79:27
+  --> $DIR/format_args.rs:80:27
    |
 LL |         Location::caller().to_string()
    |                           ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `writeln!` args
-  --> $DIR/format_args.rs:84:27
+  --> $DIR/format_args.rs:85:27
    |
 LL |         Location::caller().to_string()
    |                           ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `print!` args
-  --> $DIR/format_args.rs:86:63
+  --> $DIR/format_args.rs:87:63
    |
 LL |     print!("error: something failed at {}", Location::caller().to_string());
    |                                                               ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:87:65
+  --> $DIR/format_args.rs:88:65
    |
 LL |     println!("error: something failed at {}", Location::caller().to_string());
    |                                                                 ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `eprint!` args
-  --> $DIR/format_args.rs:88:64
+  --> $DIR/format_args.rs:89:64
    |
 LL |     eprint!("error: something failed at {}", Location::caller().to_string());
    |                                                                ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `eprintln!` args
-  --> $DIR/format_args.rs:89:66
+  --> $DIR/format_args.rs:90:66
    |
 LL |     eprintln!("error: something failed at {}", Location::caller().to_string());
    |                                                                  ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `format_args!` args
-  --> $DIR/format_args.rs:90:77
+  --> $DIR/format_args.rs:91:77
    |
 LL |     let _ = format_args!("error: something failed at {}", Location::caller().to_string());
    |                                                                             ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `assert!` args
-  --> $DIR/format_args.rs:91:70
+  --> $DIR/format_args.rs:92:70
    |
 LL |     assert!(true, "error: something failed at {}", Location::caller().to_string());
    |                                                                      ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `assert_eq!` args
-  --> $DIR/format_args.rs:92:73
+  --> $DIR/format_args.rs:93:73
    |
 LL |     assert_eq!(0, 0, "error: something failed at {}", Location::caller().to_string());
    |                                                                         ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `assert_ne!` args
-  --> $DIR/format_args.rs:93:73
+  --> $DIR/format_args.rs:94:73
    |
 LL |     assert_ne!(0, 0, "error: something failed at {}", Location::caller().to_string());
    |                                                                         ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `panic!` args
-  --> $DIR/format_args.rs:94:63
+  --> $DIR/format_args.rs:95:63
    |
 LL |     panic!("error: something failed at {}", Location::caller().to_string());
    |                                                               ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:95:20
+  --> $DIR/format_args.rs:96:20
    |
 LL |     println!("{}", X(1).to_string());
    |                    ^^^^^^^^^^^^^^^^ help: use this: `*X(1)`
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:96:20
+  --> $DIR/format_args.rs:97:20
    |
 LL |     println!("{}", Y(&X(1)).to_string());
    |                    ^^^^^^^^^^^^^^^^^^^^ help: use this: `***Y(&X(1))`
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:97:24
+  --> $DIR/format_args.rs:98:24
    |
 LL |     println!("{}", Z(1).to_string());
    |                        ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:98:20
+  --> $DIR/format_args.rs:99:20
    |
 LL |     println!("{}", x.to_string());
    |                    ^^^^^^^^^^^^^ help: use this: `**x`
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:99:20
+  --> $DIR/format_args.rs:100:20
    |
 LL |     println!("{}", x_ref.to_string());
    |                    ^^^^^^^^^^^^^^^^^ help: use this: `***x_ref`
 
-error: aborting due to 17 previous errors
+error: `to_string` applied to a type that implements `Display` in `println!` args
+  --> $DIR/format_args.rs:102:39
+   |
+LL |     println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar");
+   |                                       ^^^^^^^^^^^^ help: remove this
+
+error: `to_string` applied to a type that implements `Display` in `println!` args
+  --> $DIR/format_args.rs:103:52
+   |
+LL |     println!("{foo}{bar}", foo = "foo", bar = "bar".to_string());
+   |                                                    ^^^^^^^^^^^^ help: remove this
+
+error: `to_string` applied to a type that implements `Display` in `println!` args
+  --> $DIR/format_args.rs:104:39
+   |
+LL |     println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo");
+   |                                       ^^^^^^^^^^^^ help: remove this
+
+error: `to_string` applied to a type that implements `Display` in `println!` args
+  --> $DIR/format_args.rs:105:52
+   |
+LL |     println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
+   |                                                    ^^^^^^^^^^^^ help: remove this
+
+error: aborting due to 21 previous errors
 
index a8c06c2bde6645e418bd8d3f76599e24be4d9c2e..b24ddf7321e4000cf7fe20cee6ca5485ab6fab0f 100644 (file)
@@ -51,6 +51,7 @@ fn main() {
     assert_ne!(0, 0, "error: {}", format!("something failed at {}", Location::caller()));
     panic!("error: {}", format!("something failed at {}", Location::caller()));
 
+    // negative tests
     println!("error: {}", format_args!("something failed at {}", Location::caller()));
     println!("error: {:>70}", format!("something failed at {}", Location::caller()));
     println!("error: {} {0}", format!("something failed at {}", Location::caller()));
index d3a920de4b6ad8a685f3c04096a3afd414826998..858036692d68f401d36c464754b82662f150c540 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::future_not_send)]
 
 use std::cell::Cell;
index c734051ccf320b086567185414793a707c50a379..3cc05e2fdbec65c0b9574b0c45b924f63bcd6ca5 100644 (file)
@@ -1,12 +1,12 @@
 error: future cannot be sent between threads safely
-  --> $DIR/future_not_send.rs:8:62
+  --> $DIR/future_not_send.rs:7:62
    |
 LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                                                              ^^^^ future returned by `private_future` is not `Send`
    |
    = note: `-D clippy::future-not-send` implied by `-D warnings`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/future_not_send.rs:9:5
+  --> $DIR/future_not_send.rs:8:5
    |
 LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                         -- has type `std::rc::Rc<[u8]>` which is not `Send`
@@ -16,7 +16,7 @@ LL | }
    | - `rc` is later dropped here
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/future_not_send.rs:9:5
+  --> $DIR/future_not_send.rs:8:5
    |
 LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                                       ---- has type `&std::cell::Cell<usize>` which is not `Send`
@@ -27,13 +27,13 @@ LL | }
    = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> $DIR/future_not_send.rs:12:42
+  --> $DIR/future_not_send.rs:11:42
    |
 LL | pub async fn public_future(rc: Rc<[u8]>) {
    |                                          ^ future returned by `public_future` is not `Send`
    |
 note: future is not `Send` as this value is used across an await
-  --> $DIR/future_not_send.rs:13:5
+  --> $DIR/future_not_send.rs:12:5
    |
 LL | pub async fn public_future(rc: Rc<[u8]>) {
    |                            -- has type `std::rc::Rc<[u8]>` which is not `Send`
@@ -44,45 +44,45 @@ LL | }
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
 
 error: future cannot be sent between threads safely
-  --> $DIR/future_not_send.rs:20:63
+  --> $DIR/future_not_send.rs:19:63
    |
 LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                                                               ^^^^ future returned by `private_future2` is not `Send`
    |
 note: captured value is not `Send`
-  --> $DIR/future_not_send.rs:20:26
+  --> $DIR/future_not_send.rs:19:26
    |
 LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                          ^^ has type `std::rc::Rc<[u8]>` which is not `Send`
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
-  --> $DIR/future_not_send.rs:20:40
+  --> $DIR/future_not_send.rs:19:40
    |
 LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                                        ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`
    = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> $DIR/future_not_send.rs:24:43
+  --> $DIR/future_not_send.rs:23:43
    |
 LL | pub async fn public_future2(rc: Rc<[u8]>) {}
    |                                           ^ future returned by `public_future2` is not `Send`
    |
 note: captured value is not `Send`
-  --> $DIR/future_not_send.rs:24:29
+  --> $DIR/future_not_send.rs:23:29
    |
 LL | pub async fn public_future2(rc: Rc<[u8]>) {}
    |                             ^^ has type `std::rc::Rc<[u8]>` which is not `Send`
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
 
 error: future cannot be sent between threads safely
-  --> $DIR/future_not_send.rs:35:39
+  --> $DIR/future_not_send.rs:34:39
    |
 LL |     async fn private_future(&self) -> usize {
    |                                       ^^^^^ future returned by `private_future` is not `Send`
    |
 note: future is not `Send` as this value is used across an await
-  --> $DIR/future_not_send.rs:36:9
+  --> $DIR/future_not_send.rs:35:9
    |
 LL |     async fn private_future(&self) -> usize {
    |                             ----- has type `&Dummy` which is not `Send`
@@ -94,13 +94,13 @@ LL |     }
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> $DIR/future_not_send.rs:40:39
+  --> $DIR/future_not_send.rs:39:39
    |
 LL |     pub async fn public_future(&self) {
    |                                       ^ future returned by `public_future` is not `Send`
    |
 note: future is not `Send` as this value is used across an await
-  --> $DIR/future_not_send.rs:41:9
+  --> $DIR/future_not_send.rs:40:9
    |
 LL |     pub async fn public_future(&self) {
    |                                ----- has type `&Dummy` which is not `Send`
@@ -111,13 +111,13 @@ LL |     }
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> $DIR/future_not_send.rs:50:37
+  --> $DIR/future_not_send.rs:49:37
    |
 LL | async fn generic_future<T>(t: T) -> T
    |                                     ^ future returned by `generic_future` is not `Send`
    |
 note: future is not `Send` as this value is used across an await
-  --> $DIR/future_not_send.rs:55:5
+  --> $DIR/future_not_send.rs:54:5
    |
 LL |     let rt = &t;
    |         -- has type `&T` which is not `Send`
@@ -129,13 +129,13 @@ LL | }
    = note: `T` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> $DIR/future_not_send.rs:66:34
+  --> $DIR/future_not_send.rs:65:34
    |
 LL | async fn unclear_future<T>(t: T) {}
    |                                  ^ future returned by `unclear_future` is not `Send`
    |
 note: captured value is not `Send`
-  --> $DIR/future_not_send.rs:66:28
+  --> $DIR/future_not_send.rs:65:28
    |
 LL | async fn unclear_future<T>(t: T) {}
    |                            ^ has type `T` which is not `Send`
index dc3fb1ceac9a44ba1dd69d063040b49f9feff534..b7012b43d29766d154786e866357b15b838d5756 100644 (file)
@@ -1,6 +1,9 @@
 #![warn(clippy::all)]
 #![warn(clippy::if_not_else)]
 
+fn foo() -> bool {
+    unimplemented!()
+}
 fn bla() -> bool {
     unimplemented!()
 }
@@ -16,4 +19,11 @@ fn main() {
     } else {
         println!("Bunny");
     }
+    if !foo() {
+        println!("Foo");
+    } else if !bla() {
+        println!("Bugs");
+    } else {
+        println!("Bunny");
+    }
 }
index 53d1b86d02a962a639631ea29c6415573cb8ee51..8c8cc44bb035882e2484a96a8874351632c6be89 100644 (file)
@@ -1,5 +1,5 @@
 error: unnecessary boolean `not` operation
-  --> $DIR/if_not_else.rs:9:5
+  --> $DIR/if_not_else.rs:12:5
    |
 LL | /     if !bla() {
 LL | |         println!("Bugs");
@@ -12,7 +12,7 @@ LL | |     }
    = help: remove the `!` and swap the blocks of the `if`/`else`
 
 error: unnecessary `!=` operation
-  --> $DIR/if_not_else.rs:14:5
+  --> $DIR/if_not_else.rs:17:5
    |
 LL | /     if 4 != 5 {
 LL | |         println!("Bugs");
diff --git a/src/tools/clippy/tests/ui/if_then_panic.fixed b/src/tools/clippy/tests/ui/if_then_panic.fixed
deleted file mode 100644 (file)
index 0998f8f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// run-rustfix
-#![warn(clippy::if_then_panic)]
-
-fn main() {
-    let a = vec![1, 2, 3];
-    let c = Some(2);
-    if !a.is_empty()
-        && a.len() == 3
-        && c != None
-        && !a.is_empty()
-        && a.len() == 3
-        && !a.is_empty()
-        && a.len() == 3
-        && !a.is_empty()
-        && a.len() == 3
-    {
-        panic!("qaqaq{:?}", a);
-    }
-    assert!(a.is_empty(), "qaqaq{:?}", a);
-    assert!(a.is_empty(), "qwqwq");
-    if a.len() == 3 {
-        println!("qwq");
-        println!("qwq");
-        println!("qwq");
-    }
-    if let Some(b) = c {
-        panic!("orz {}", b);
-    }
-    if a.len() == 3 {
-        panic!("qaqaq");
-    } else {
-        println!("qwq");
-    }
-    let b = vec![1, 2, 3];
-    assert!(!b.is_empty(), "panic1");
-    assert!(!(b.is_empty() && a.is_empty()), "panic2");
-    assert!(!(a.is_empty() && !b.is_empty()), "panic3");
-    assert!(!(b.is_empty() || a.is_empty()), "panic4");
-    assert!(!(a.is_empty() || !b.is_empty()), "panic5");
-}
diff --git a/src/tools/clippy/tests/ui/if_then_panic.rs b/src/tools/clippy/tests/ui/if_then_panic.rs
deleted file mode 100644 (file)
index 10433c8..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// run-rustfix
-#![warn(clippy::if_then_panic)]
-
-fn main() {
-    let a = vec![1, 2, 3];
-    let c = Some(2);
-    if !a.is_empty()
-        && a.len() == 3
-        && c != None
-        && !a.is_empty()
-        && a.len() == 3
-        && !a.is_empty()
-        && a.len() == 3
-        && !a.is_empty()
-        && a.len() == 3
-    {
-        panic!("qaqaq{:?}", a);
-    }
-    if !a.is_empty() {
-        panic!("qaqaq{:?}", a);
-    }
-    if !a.is_empty() {
-        panic!("qwqwq");
-    }
-    if a.len() == 3 {
-        println!("qwq");
-        println!("qwq");
-        println!("qwq");
-    }
-    if let Some(b) = c {
-        panic!("orz {}", b);
-    }
-    if a.len() == 3 {
-        panic!("qaqaq");
-    } else {
-        println!("qwq");
-    }
-    let b = vec![1, 2, 3];
-    if b.is_empty() {
-        panic!("panic1");
-    }
-    if b.is_empty() && a.is_empty() {
-        panic!("panic2");
-    }
-    if a.is_empty() && !b.is_empty() {
-        panic!("panic3");
-    }
-    if b.is_empty() || a.is_empty() {
-        panic!("panic4");
-    }
-    if a.is_empty() || !b.is_empty() {
-        panic!("panic5");
-    }
-}
diff --git a/src/tools/clippy/tests/ui/if_then_panic.stderr b/src/tools/clippy/tests/ui/if_then_panic.stderr
deleted file mode 100644 (file)
index 5bb62f8..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-error: only a `panic!` in `if`-then statement
-  --> $DIR/if_then_panic.rs:19:5
-   |
-LL | /     if !a.is_empty() {
-LL | |         panic!("qaqaq{:?}", a);
-LL | |     }
-   | |_____^ help: try: `assert!(a.is_empty(), "qaqaq{:?}", a);`
-   |
-   = note: `-D clippy::if-then-panic` implied by `-D warnings`
-
-error: only a `panic!` in `if`-then statement
-  --> $DIR/if_then_panic.rs:22:5
-   |
-LL | /     if !a.is_empty() {
-LL | |         panic!("qwqwq");
-LL | |     }
-   | |_____^ help: try: `assert!(a.is_empty(), "qwqwq");`
-
-error: only a `panic!` in `if`-then statement
-  --> $DIR/if_then_panic.rs:39:5
-   |
-LL | /     if b.is_empty() {
-LL | |         panic!("panic1");
-LL | |     }
-   | |_____^ help: try: `assert!(!b.is_empty(), "panic1");`
-
-error: only a `panic!` in `if`-then statement
-  --> $DIR/if_then_panic.rs:42:5
-   |
-LL | /     if b.is_empty() && a.is_empty() {
-LL | |         panic!("panic2");
-LL | |     }
-   | |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
-
-error: only a `panic!` in `if`-then statement
-  --> $DIR/if_then_panic.rs:45:5
-   |
-LL | /     if a.is_empty() && !b.is_empty() {
-LL | |         panic!("panic3");
-LL | |     }
-   | |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
-
-error: only a `panic!` in `if`-then statement
-  --> $DIR/if_then_panic.rs:48:5
-   |
-LL | /     if b.is_empty() || a.is_empty() {
-LL | |         panic!("panic4");
-LL | |     }
-   | |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
-
-error: only a `panic!` in `if`-then statement
-  --> $DIR/if_then_panic.rs:51:5
-   |
-LL | /     if a.is_empty() || !b.is_empty() {
-LL | |         panic!("panic5");
-LL | |     }
-   | |_____^ help: try: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
-
-error: aborting due to 7 previous errors
-
index aa69b0974101c822a06a790c742bed645e46813b..fd96ca3f466eabe7cc9ed034040925a658f274c9 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // aux-build:implicit_hasher_macros.rs
 #![deny(clippy::implicit_hasher)]
 #![allow(unused)]
index 3f5f56b923fe2453b25e792bc9b5a912f880cd90..59b0fba2a4cfee460b8e2d120a91b01fb1c3d952 100644 (file)
@@ -1,11 +1,11 @@
 error: impl for `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:17:35
+  --> $DIR/implicit_hasher.rs:16:35
    |
 LL | impl<K: Hash + Eq, V> Foo<i8> for HashMap<K, V> {
    |                                   ^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/implicit_hasher.rs:3:9
+  --> $DIR/implicit_hasher.rs:2:9
    |
 LL | #![deny(clippy::implicit_hasher)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL |         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default:
    |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:26:36
+  --> $DIR/implicit_hasher.rs:25:36
    |
 LL | impl<K: Hash + Eq, V> Foo<i8> for (HashMap<K, V>,) {
    |                                    ^^^^^^^^^^^^^
@@ -34,7 +34,7 @@ LL |         ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Defa
    |           ~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:31:19
+  --> $DIR/implicit_hasher.rs:30:19
    |
 LL | impl Foo<i16> for HashMap<String, String> {
    |                   ^^^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL |         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default:
    |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashSet` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:48:32
+  --> $DIR/implicit_hasher.rs:47:32
    |
 LL | impl<T: Hash + Eq> Foo<i8> for HashSet<T> {
    |                                ^^^^^^^^^^
@@ -64,7 +64,7 @@ LL |         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default:
    |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashSet` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:53:19
+  --> $DIR/implicit_hasher.rs:52:19
    |
 LL | impl Foo<i16> for HashSet<String> {
    |                   ^^^^^^^^^^^^^^^
@@ -79,7 +79,7 @@ LL |         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default:
    |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:70:23
+  --> $DIR/implicit_hasher.rs:69:23
    |
 LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
    |                       ^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32, S>, _s
    |           +++++++++++++++++++++++++++++            ~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashSet` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:70:53
+  --> $DIR/implicit_hasher.rs:69:53
    |
 LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
    |                                                     ^^^^^^^^^^^^
@@ -101,7 +101,7 @@ LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set:
    |           +++++++++++++++++++++++++++++                                          ~~~~~~~~~~~~~~~
 
 error: impl for `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:74:43
+  --> $DIR/implicit_hasher.rs:73:43
    |
 LL |         impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {
    |                                           ^^^^^^^^^^^^^
@@ -120,7 +120,7 @@ LL |                 (HashMap::default(), HashMap::with_capacity_and_hasher(10,
    |                  ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:82:33
+  --> $DIR/implicit_hasher.rs:81:33
    |
 LL |         pub fn $name(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
    |                                 ^^^^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL |         pub fn $name<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i
    |                     +++++++++++++++++++++++++++++            ~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashSet` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:82:63
+  --> $DIR/implicit_hasher.rs:81:63
    |
 LL |         pub fn $name(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
    |                                                               ^^^^^^^^^^^^
@@ -150,7 +150,7 @@ LL |         pub fn $name<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i
    |                     +++++++++++++++++++++++++++++                                          ~~~~~~~~~~~~~~~
 
 error: parameter of type `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:101:35
+  --> $DIR/implicit_hasher.rs:100:35
    |
 LL | pub async fn election_vote(_data: HashMap<i32, i32>) {}
    |                                   ^^^^^^^^^^^^^^^^^
index 7698b88a88c8aa80a143ac27ab11e145a880ef51..a51f7bc6a29ffff52a301b84053f3c8f58bddc53 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // run-rustfix
 
 #![warn(clippy::implicit_return)]
index 45bbc2ec670e05463d1a0f8d6f8d5fc557561cfe..03f8ec49d51e5457a57e2c9a71e30669fb984b1d 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // run-rustfix
 
 #![warn(clippy::implicit_return)]
index 5e078b15ce393f6070b3f932ec0553d0c880f91f..522bc3bf895a7a3159dccdb74e56fe032c10c483 100644 (file)
@@ -1,5 +1,5 @@
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:13:5
+  --> $DIR/implicit_return.rs:12:5
    |
 LL |     true
    |     ^^^^ help: add `return` as shown: `return true`
@@ -7,85 +7,85 @@ LL |     true
    = note: `-D clippy::implicit-return` implied by `-D warnings`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:17:15
+  --> $DIR/implicit_return.rs:16:15
    |
 LL |     if true { true } else { false }
    |               ^^^^ help: add `return` as shown: `return true`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:17:29
+  --> $DIR/implicit_return.rs:16:29
    |
 LL |     if true { true } else { false }
    |                             ^^^^^ help: add `return` as shown: `return false`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:23:17
+  --> $DIR/implicit_return.rs:22:17
    |
 LL |         true => false,
    |                 ^^^^^ help: add `return` as shown: `return false`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:24:20
+  --> $DIR/implicit_return.rs:23:20
    |
 LL |         false => { true },
    |                    ^^^^ help: add `return` as shown: `return true`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:37:9
+  --> $DIR/implicit_return.rs:36:9
    |
 LL |         break true;
    |         ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:44:13
+  --> $DIR/implicit_return.rs:43:13
    |
 LL |             break true;
    |             ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:52:13
+  --> $DIR/implicit_return.rs:51:13
    |
 LL |             break true;
    |             ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:70:18
+  --> $DIR/implicit_return.rs:69:18
    |
 LL |     let _ = || { true };
    |                  ^^^^ help: add `return` as shown: `return true`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:71:16
+  --> $DIR/implicit_return.rs:70:16
    |
 LL |     let _ = || true;
    |                ^^^^ help: add `return` as shown: `return true`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:79:5
+  --> $DIR/implicit_return.rs:78:5
    |
 LL |     format!("test {}", "test")
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `return` as shown: `return format!("test {}", "test")`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:88:5
+  --> $DIR/implicit_return.rs:87:5
    |
 LL |     m!(true, false)
    |     ^^^^^^^^^^^^^^^ help: add `return` as shown: `return m!(true, false)`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:94:13
+  --> $DIR/implicit_return.rs:93:13
    |
 LL |             break true;
    |             ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:99:17
+  --> $DIR/implicit_return.rs:98:17
    |
 LL |                 break 'outer false;
    |                 ^^^^^^^^^^^^^^^^^^ help: change `break` to `return` as shown: `return false`
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:114:5
+  --> $DIR/implicit_return.rs:113:5
    |
 LL | /     loop {
 LL | |         m!(true);
@@ -100,7 +100,7 @@ LL +     }
    |
 
 error: missing `return` statement
-  --> $DIR/implicit_return.rs:128:5
+  --> $DIR/implicit_return.rs:127:5
    |
 LL |     true
    |     ^^^^ help: add `return` as shown: `return true`
index d1025743790a9747bfb95c6bb746d0b1e15b917c..eb66d1afddce39dfce67d421a7229232b52b2b6f 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 #![warn(clippy::inconsistent_struct_constructor)]
 #![allow(clippy::redundant_field_names)]
 #![allow(clippy::unnecessary_operation)]
index b095aa64a2174371e94d9f2c240ed910c9c893ca..5caadc7c62083fb2b214df04ded3b16e2bb665f7 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 #![warn(clippy::inconsistent_struct_constructor)]
 #![allow(clippy::redundant_field_names)]
 #![allow(clippy::unnecessary_operation)]
index ef308dedb1661c331703d68d9ab973477f473d51..c90189e964f09e68cea01babbb5d25ba03689909 100644 (file)
@@ -1,5 +1,5 @@
 error: struct constructor field order is inconsistent with struct definition field order
-  --> $DIR/inconsistent_struct_constructor.rs:34:9
+  --> $DIR/inconsistent_struct_constructor.rs:33:9
    |
 LL |         Foo { y, x, z };
    |         ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }`
@@ -7,7 +7,7 @@ LL |         Foo { y, x, z };
    = note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings`
 
 error: struct constructor field order is inconsistent with struct definition field order
-  --> $DIR/inconsistent_struct_constructor.rs:56:9
+  --> $DIR/inconsistent_struct_constructor.rs:55:9
    |
 LL | /         Foo {
 LL | |             z,
diff --git a/src/tools/clippy/tests/ui/issue-7447.stderr b/src/tools/clippy/tests/ui/issue-7447.stderr
new file mode 100644 (file)
index 0000000..463a48b
--- /dev/null
@@ -0,0 +1,19 @@
+error: sub-expression diverges
+  --> $DIR/issue-7447.rs:23:15
+   |
+LL |     byte_view(panic!());
+   |               ^^^^^^^^
+   |
+   = note: `-D clippy::diverging-sub-expression` implied by `-D warnings`
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: sub-expression diverges
+  --> $DIR/issue-7447.rs:24:19
+   |
+LL |     group_entries(panic!());
+   |                   ^^^^^^^^
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
index cc699b79e433ca39756717f16714487a05421da7..d9d48189bd74e741f381f9449783ecefd5cce514 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![allow(dead_code)]
 
 async fn sink1<'a>(_: &'a str) {} // lint
index 0426508e622f8fd471a61e0464e1ba53ccf537a3..20419457b47f0ee3018f9ec888939e1d96cfbae4 100644 (file)
@@ -1,5 +1,5 @@
 error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
-  --> $DIR/issue_4266.rs:4:1
+  --> $DIR/issue_4266.rs:3:1
    |
 LL | async fn sink1<'a>(_: &'a str) {} // lint
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,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)
-  --> $DIR/issue_4266.rs:8:1
+  --> $DIR/issue_4266.rs:7:1
    |
 LL | async fn one_to_one<'a>(s: &'a str) -> &'a str {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index b9d66347c27487b9857e99e2be575796273ac6b7..1e938e72b57775356d326a9f0bac9dcae6b57525 100644 (file)
@@ -1,5 +1,3 @@
-// edition:2018
-
 #![warn(clippy::len_without_is_empty)]
 #![allow(dead_code, unused)]
 
index 3282709bcd6717f664ef135c6132b38e9ab3a389..a1f48f7610b44857edf7f6f8f9e6dbbc520c1a0d 100644 (file)
@@ -1,5 +1,5 @@
 error: struct `PubOne` has a public `len` method, but no `is_empty` method
-  --> $DIR/len_without_is_empty.rs:9:5
+  --> $DIR/len_without_is_empty.rs:7:5
    |
 LL |     pub fn len(&self) -> isize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     pub fn len(&self) -> isize {
    = note: `-D clippy::len-without-is-empty` implied by `-D warnings`
 
 error: trait `PubTraitsToo` has a `len` method but no (possibly inherited) `is_empty` method
-  --> $DIR/len_without_is_empty.rs:57:1
+  --> $DIR/len_without_is_empty.rs:55:1
    |
 LL | / pub trait PubTraitsToo {
 LL | |     fn len(&self) -> isize;
@@ -15,45 +15,45 @@ LL | | }
    | |_^
 
 error: struct `HasIsEmpty` has a public `len` method, but a private `is_empty` method
-  --> $DIR/len_without_is_empty.rs:70:5
+  --> $DIR/len_without_is_empty.rs:68:5
    |
 LL |     pub fn len(&self) -> isize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `is_empty` defined here
-  --> $DIR/len_without_is_empty.rs:74:5
+  --> $DIR/len_without_is_empty.rs:72:5
    |
 LL |     fn is_empty(&self) -> bool {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: struct `HasWrongIsEmpty` has a public `len` method, but the `is_empty` method has an unexpected signature
-  --> $DIR/len_without_is_empty.rs:82:5
+  --> $DIR/len_without_is_empty.rs:80:5
    |
 LL |     pub fn len(&self) -> isize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `is_empty` defined here
-  --> $DIR/len_without_is_empty.rs:86:5
+  --> $DIR/len_without_is_empty.rs:84:5
    |
 LL |     pub fn is_empty(&self, x: u32) -> bool {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected signature: `(&self) -> bool`
 
 error: struct `MismatchedSelf` has a public `len` method, but the `is_empty` method has an unexpected signature
-  --> $DIR/len_without_is_empty.rs:94:5
+  --> $DIR/len_without_is_empty.rs:92:5
    |
 LL |     pub fn len(self) -> isize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `is_empty` defined here
-  --> $DIR/len_without_is_empty.rs:98:5
+  --> $DIR/len_without_is_empty.rs:96:5
    |
 LL |     pub fn is_empty(&self) -> bool {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected signature: `(self) -> bool`
 
 error: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty` method
-  --> $DIR/len_without_is_empty.rs:173:1
+  --> $DIR/len_without_is_empty.rs:171:1
    |
 LL | / pub trait DependsOnFoo: Foo {
 LL | |     fn len(&mut self) -> usize;
@@ -61,33 +61,33 @@ LL | | }
    | |_^
 
 error: struct `OptionalLen3` has a public `len` method, but the `is_empty` method has an unexpected signature
-  --> $DIR/len_without_is_empty.rs:218:5
+  --> $DIR/len_without_is_empty.rs:216:5
    |
 LL |     pub fn len(&self) -> usize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `is_empty` defined here
-  --> $DIR/len_without_is_empty.rs:223:5
+  --> $DIR/len_without_is_empty.rs:221:5
    |
 LL |     pub fn is_empty(&self) -> Option<bool> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected signature: `(&self) -> bool`
 
 error: struct `ResultLen` has a public `len` method, but the `is_empty` method has an unexpected signature
-  --> $DIR/len_without_is_empty.rs:230:5
+  --> $DIR/len_without_is_empty.rs:228:5
    |
 LL |     pub fn len(&self) -> Result<usize, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `is_empty` defined here
-  --> $DIR/len_without_is_empty.rs:235:5
+  --> $DIR/len_without_is_empty.rs:233:5
    |
 LL |     pub fn is_empty(&self) -> Option<bool> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected signature: `(&self) -> bool` or `(&self) -> Result<bool>
 
 error: this returns a `Result<_, ()>`
-  --> $DIR/len_without_is_empty.rs:230:5
+  --> $DIR/len_without_is_empty.rs:228:5
    |
 LL |     pub fn len(&self) -> Result<usize, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +96,7 @@ LL |     pub fn len(&self) -> Result<usize, ()> {
    = help: use a custom `Error` type instead
 
 error: this returns a `Result<_, ()>`
-  --> $DIR/len_without_is_empty.rs:242:5
+  --> $DIR/len_without_is_empty.rs:240:5
    |
 LL |     pub fn len(&self) -> Result<usize, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +104,7 @@ LL |     pub fn len(&self) -> Result<usize, ()> {
    = help: use a custom `Error` type instead
 
 error: this returns a `Result<_, ()>`
-  --> $DIR/len_without_is_empty.rs:246:5
+  --> $DIR/len_without_is_empty.rs:244:5
    |
 LL |     pub fn is_empty(&self) -> Result<bool, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -112,7 +112,7 @@ LL |     pub fn is_empty(&self) -> Result<bool, ()> {
    = help: use a custom `Error` type instead
 
 error: this returns a `Result<_, ()>`
-  --> $DIR/len_without_is_empty.rs:253:5
+  --> $DIR/len_without_is_empty.rs:251:5
    |
 LL |     pub fn len(&self) -> Result<usize, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index a72a74b9131d8bb21fb3b2431fd344c2d069706c..e60ce8492fc7716f70f3f490086d03d76904f07f 100644 (file)
@@ -2,7 +2,8 @@
 
 #![warn(clippy::mixed_case_hex_literals)]
 #![warn(clippy::zero_prefixed_literal)]
-#![allow(clippy::unseparated_literal_suffix)]
+#![warn(clippy::unseparated_literal_suffix)]
+#![warn(clippy::separated_literal_suffix)]
 #![allow(dead_code)]
 
 fn main() {
index 99542e20f785fea9f916c59976b20850fcd8edc7..365b240747352d76bc06b3e802e04f0049dabec6 100644 (file)
@@ -1,25 +1,65 @@
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:12:15
+   |
+LL |     let ok4 = 0xab_cd_i32;
+   |               ^^^^^^^^^^^ help: remove the underscore: `0xab_cdi32`
+   |
+   = note: `-D clippy::separated-literal-suffix` implied by `-D warnings`
+
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:13:15
+   |
+LL |     let ok5 = 0xAB_CD_u32;
+   |               ^^^^^^^^^^^ help: remove the underscore: `0xAB_CDu32`
+
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:14:15
+   |
+LL |     let ok5 = 0xAB_CD_isize;
+   |               ^^^^^^^^^^^^^ help: remove the underscore: `0xAB_CDisize`
+
 error: inconsistent casing in hexadecimal literal
-  --> $DIR/literals.rs:14:17
+  --> $DIR/literals.rs:15:17
    |
 LL |     let fail1 = 0xabCD;
    |                 ^^^^^^
    |
    = note: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`
 
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:16:17
+   |
+LL |     let fail2 = 0xabCD_u32;
+   |                 ^^^^^^^^^^ help: remove the underscore: `0xabCDu32`
+
 error: inconsistent casing in hexadecimal literal
-  --> $DIR/literals.rs:15:17
+  --> $DIR/literals.rs:16:17
    |
 LL |     let fail2 = 0xabCD_u32;
    |                 ^^^^^^^^^^
 
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:17:17
+   |
+LL |     let fail2 = 0xabCD_isize;
+   |                 ^^^^^^^^^^^^ help: remove the underscore: `0xabCDisize`
+
 error: inconsistent casing in hexadecimal literal
-  --> $DIR/literals.rs:16:17
+  --> $DIR/literals.rs:17:17
    |
 LL |     let fail2 = 0xabCD_isize;
    |                 ^^^^^^^^^^^^
 
+error: integer type suffix should be separated by an underscore
+  --> $DIR/literals.rs:18:27
+   |
+LL |     let fail_multi_zero = 000_123usize;
+   |                           ^^^^^^^^^^^^ help: add an underscore: `000_123_usize`
+   |
+   = note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`
+
 error: this is a decimal constant
-  --> $DIR/literals.rs:17:27
+  --> $DIR/literals.rs:18:27
    |
 LL |     let fail_multi_zero = 000_123usize;
    |                           ^^^^^^^^^^^^
@@ -34,8 +74,14 @@ help: if you mean to use an octal constant, use `0o`
 LL |     let fail_multi_zero = 0o123usize;
    |                           ~~~~~~~~~~
 
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:21:16
+   |
+LL |     let ok10 = 0_i64;
+   |                ^^^^^ help: remove the underscore: `0i64`
+
 error: this is a decimal constant
-  --> $DIR/literals.rs:21:17
+  --> $DIR/literals.rs:22:17
    |
 LL |     let fail8 = 0123;
    |                 ^^^^
@@ -49,8 +95,14 @@ help: if you mean to use an octal constant, use `0o`
 LL |     let fail8 = 0o123;
    |                 ~~~~~
 
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:31:16
+   |
+LL |     let ok17 = 0x123_4567_8901_usize;
+   |                ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901usize`
+
 error: digits grouped inconsistently by underscores
-  --> $DIR/literals.rs:33:18
+  --> $DIR/literals.rs:34:18
    |
 LL |     let fail19 = 12_3456_21;
    |                  ^^^^^^^^^^ help: consider: `12_345_621`
@@ -58,19 +110,19 @@ LL |     let fail19 = 12_3456_21;
    = note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
 
 error: digits grouped inconsistently by underscores
-  --> $DIR/literals.rs:34:18
+  --> $DIR/literals.rs:35:18
    |
 LL |     let fail22 = 3__4___23;
    |                  ^^^^^^^^^ help: consider: `3_423`
 
 error: digits grouped inconsistently by underscores
-  --> $DIR/literals.rs:35:18
+  --> $DIR/literals.rs:36:18
    |
 LL |     let fail23 = 3__16___23;
    |                  ^^^^^^^^^^ help: consider: `31_623`
 
 error: digits of hex or binary literal not grouped by four
-  --> $DIR/literals.rs:37:18
+  --> $DIR/literals.rs:38:18
    |
 LL |     let fail24 = 0xAB_ABC_AB;
    |                  ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB`
@@ -78,10 +130,10 @@ LL |     let fail24 = 0xAB_ABC_AB;
    = note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
 
 error: digits of hex or binary literal not grouped by four
-  --> $DIR/literals.rs:38:18
+  --> $DIR/literals.rs:39:18
    |
 LL |     let fail25 = 0b01_100_101;
    |                  ^^^^^^^^^^^^ help: consider: `0b0110_0101`
 
-error: aborting due to 10 previous errors
+error: aborting due to 18 previous errors
 
index 70d49d9f2c4ae1edd8497e9133f3598369431148..9171558f3a2d74d1f79d2c9b62d6a3282db33b82 100644 (file)
@@ -1,4 +1,3 @@
-// compile-flags: --edition 2018
 // aux-build:macro_rules.rs
 // aux-build:macro_use_helper.rs
 // aux-build:proc_macro_derive.rs
index 68370023861145dc15a29d4a6696138e06910d05..cd01fd43f6d325eefb79e07d1bc71753ef1a164c 100644 (file)
@@ -1,4 +1,3 @@
-// compile-flags: --edition 2018
 // aux-build:macro_rules.rs
 // aux-build:macro_use_helper.rs
 // aux-build:proc_macro_derive.rs
index 49314b7506d336187642b16deee4aad13d34f342..f8c86c8d9179f8af918b684eb9294c18ea4a7008 100644 (file)
@@ -1,5 +1,5 @@
 error: `macro_use` attributes are no longer needed in the Rust 2018 edition
-  --> $DIR/macro_use_imports.rs:19:5
+  --> $DIR/macro_use_imports.rs:18:5
    |
 LL |     #[macro_use]
    |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};`
@@ -7,22 +7,22 @@ LL |     #[macro_use]
    = note: `-D clippy::macro-use-imports` implied by `-D warnings`
 
 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:20:5
    |
 LL |     #[macro_use]
-   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`
+   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;`
 
 error: `macro_use` attributes are no longer needed in the Rust 2018 edition
-  --> $DIR/macro_use_imports.rs:21:5
+  --> $DIR/macro_use_imports.rs:22:5
    |
 LL |     #[macro_use]
-   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;`
+   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};`
 
 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:24: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;`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
new file mode 100644 (file)
index 0000000..11fe06c
--- /dev/null
@@ -0,0 +1,43 @@
+// revisions: edition2018 edition2021
+// [edition2018] edition:2018
+// [edition2021] edition:2021
+// run-rustfix
+#![warn(clippy::manual_assert)]
+
+fn main() {
+    let a = vec![1, 2, 3];
+    let c = Some(2);
+    if !a.is_empty()
+        && a.len() == 3
+        && c != None
+        && !a.is_empty()
+        && a.len() == 3
+        && !a.is_empty()
+        && a.len() == 3
+        && !a.is_empty()
+        && a.len() == 3
+    {
+        panic!("qaqaq{:?}", a);
+    }
+    assert!(a.is_empty(), "qaqaq{:?}", a);
+    assert!(a.is_empty(), "qwqwq");
+    if a.len() == 3 {
+        println!("qwq");
+        println!("qwq");
+        println!("qwq");
+    }
+    if let Some(b) = c {
+        panic!("orz {}", b);
+    }
+    if a.len() == 3 {
+        panic!("qaqaq");
+    } else {
+        println!("qwq");
+    }
+    let b = vec![1, 2, 3];
+    assert!(!b.is_empty(), "panic1");
+    assert!(!(b.is_empty() && a.is_empty()), "panic2");
+    assert!(!(a.is_empty() && !b.is_empty()), "panic3");
+    assert!(!(b.is_empty() || a.is_empty()), "panic4");
+    assert!(!(a.is_empty() || !b.is_empty()), "panic5");
+}
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
new file mode 100644 (file)
index 0000000..03c0347
--- /dev/null
@@ -0,0 +1,60 @@
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:22:5
+   |
+LL | /     if !a.is_empty() {
+LL | |         panic!("qaqaq{:?}", a);
+LL | |     }
+   | |_____^ help: try: `assert!(a.is_empty(), "qaqaq{:?}", a);`
+   |
+   = note: `-D clippy::manual-assert` implied by `-D warnings`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:25:5
+   |
+LL | /     if !a.is_empty() {
+LL | |         panic!("qwqwq");
+LL | |     }
+   | |_____^ help: try: `assert!(a.is_empty(), "qwqwq");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:42:5
+   |
+LL | /     if b.is_empty() {
+LL | |         panic!("panic1");
+LL | |     }
+   | |_____^ help: try: `assert!(!b.is_empty(), "panic1");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:45:5
+   |
+LL | /     if b.is_empty() && a.is_empty() {
+LL | |         panic!("panic2");
+LL | |     }
+   | |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:48:5
+   |
+LL | /     if a.is_empty() && !b.is_empty() {
+LL | |         panic!("panic3");
+LL | |     }
+   | |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:51:5
+   |
+LL | /     if b.is_empty() || a.is_empty() {
+LL | |         panic!("panic4");
+LL | |     }
+   | |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:54:5
+   |
+LL | /     if a.is_empty() || !b.is_empty() {
+LL | |         panic!("panic5");
+LL | |     }
+   | |_____^ help: try: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
new file mode 100644 (file)
index 0000000..11fe06c
--- /dev/null
@@ -0,0 +1,43 @@
+// revisions: edition2018 edition2021
+// [edition2018] edition:2018
+// [edition2021] edition:2021
+// run-rustfix
+#![warn(clippy::manual_assert)]
+
+fn main() {
+    let a = vec![1, 2, 3];
+    let c = Some(2);
+    if !a.is_empty()
+        && a.len() == 3
+        && c != None
+        && !a.is_empty()
+        && a.len() == 3
+        && !a.is_empty()
+        && a.len() == 3
+        && !a.is_empty()
+        && a.len() == 3
+    {
+        panic!("qaqaq{:?}", a);
+    }
+    assert!(a.is_empty(), "qaqaq{:?}", a);
+    assert!(a.is_empty(), "qwqwq");
+    if a.len() == 3 {
+        println!("qwq");
+        println!("qwq");
+        println!("qwq");
+    }
+    if let Some(b) = c {
+        panic!("orz {}", b);
+    }
+    if a.len() == 3 {
+        panic!("qaqaq");
+    } else {
+        println!("qwq");
+    }
+    let b = vec![1, 2, 3];
+    assert!(!b.is_empty(), "panic1");
+    assert!(!(b.is_empty() && a.is_empty()), "panic2");
+    assert!(!(a.is_empty() && !b.is_empty()), "panic3");
+    assert!(!(b.is_empty() || a.is_empty()), "panic4");
+    assert!(!(a.is_empty() || !b.is_empty()), "panic5");
+}
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
new file mode 100644 (file)
index 0000000..03c0347
--- /dev/null
@@ -0,0 +1,60 @@
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:22:5
+   |
+LL | /     if !a.is_empty() {
+LL | |         panic!("qaqaq{:?}", a);
+LL | |     }
+   | |_____^ help: try: `assert!(a.is_empty(), "qaqaq{:?}", a);`
+   |
+   = note: `-D clippy::manual-assert` implied by `-D warnings`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:25:5
+   |
+LL | /     if !a.is_empty() {
+LL | |         panic!("qwqwq");
+LL | |     }
+   | |_____^ help: try: `assert!(a.is_empty(), "qwqwq");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:42:5
+   |
+LL | /     if b.is_empty() {
+LL | |         panic!("panic1");
+LL | |     }
+   | |_____^ help: try: `assert!(!b.is_empty(), "panic1");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:45:5
+   |
+LL | /     if b.is_empty() && a.is_empty() {
+LL | |         panic!("panic2");
+LL | |     }
+   | |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:48:5
+   |
+LL | /     if a.is_empty() && !b.is_empty() {
+LL | |         panic!("panic3");
+LL | |     }
+   | |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:51:5
+   |
+LL | /     if b.is_empty() || a.is_empty() {
+LL | |         panic!("panic4");
+LL | |     }
+   | |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:54:5
+   |
+LL | /     if a.is_empty() || !b.is_empty() {
+LL | |         panic!("panic5");
+LL | |     }
+   | |_____^ help: try: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_assert.fixed b/src/tools/clippy/tests/ui/manual_assert.fixed
new file mode 100644 (file)
index 0000000..11fe06c
--- /dev/null
@@ -0,0 +1,43 @@
+// revisions: edition2018 edition2021
+// [edition2018] edition:2018
+// [edition2021] edition:2021
+// run-rustfix
+#![warn(clippy::manual_assert)]
+
+fn main() {
+    let a = vec![1, 2, 3];
+    let c = Some(2);
+    if !a.is_empty()
+        && a.len() == 3
+        && c != None
+        && !a.is_empty()
+        && a.len() == 3
+        && !a.is_empty()
+        && a.len() == 3
+        && !a.is_empty()
+        && a.len() == 3
+    {
+        panic!("qaqaq{:?}", a);
+    }
+    assert!(a.is_empty(), "qaqaq{:?}", a);
+    assert!(a.is_empty(), "qwqwq");
+    if a.len() == 3 {
+        println!("qwq");
+        println!("qwq");
+        println!("qwq");
+    }
+    if let Some(b) = c {
+        panic!("orz {}", b);
+    }
+    if a.len() == 3 {
+        panic!("qaqaq");
+    } else {
+        println!("qwq");
+    }
+    let b = vec![1, 2, 3];
+    assert!(!b.is_empty(), "panic1");
+    assert!(!(b.is_empty() && a.is_empty()), "panic2");
+    assert!(!(a.is_empty() && !b.is_empty()), "panic3");
+    assert!(!(b.is_empty() || a.is_empty()), "panic4");
+    assert!(!(a.is_empty() || !b.is_empty()), "panic5");
+}
diff --git a/src/tools/clippy/tests/ui/manual_assert.rs b/src/tools/clippy/tests/ui/manual_assert.rs
new file mode 100644 (file)
index 0000000..8713426
--- /dev/null
@@ -0,0 +1,57 @@
+// revisions: edition2018 edition2021
+// [edition2018] edition:2018
+// [edition2021] edition:2021
+// run-rustfix
+#![warn(clippy::manual_assert)]
+
+fn main() {
+    let a = vec![1, 2, 3];
+    let c = Some(2);
+    if !a.is_empty()
+        && a.len() == 3
+        && c != None
+        && !a.is_empty()
+        && a.len() == 3
+        && !a.is_empty()
+        && a.len() == 3
+        && !a.is_empty()
+        && a.len() == 3
+    {
+        panic!("qaqaq{:?}", a);
+    }
+    if !a.is_empty() {
+        panic!("qaqaq{:?}", a);
+    }
+    if !a.is_empty() {
+        panic!("qwqwq");
+    }
+    if a.len() == 3 {
+        println!("qwq");
+        println!("qwq");
+        println!("qwq");
+    }
+    if let Some(b) = c {
+        panic!("orz {}", b);
+    }
+    if a.len() == 3 {
+        panic!("qaqaq");
+    } else {
+        println!("qwq");
+    }
+    let b = vec![1, 2, 3];
+    if b.is_empty() {
+        panic!("panic1");
+    }
+    if b.is_empty() && a.is_empty() {
+        panic!("panic2");
+    }
+    if a.is_empty() && !b.is_empty() {
+        panic!("panic3");
+    }
+    if b.is_empty() || a.is_empty() {
+        panic!("panic4");
+    }
+    if a.is_empty() || !b.is_empty() {
+        panic!("panic5");
+    }
+}
index 5184f6fdb88b3991850aead57bf02ea0a75b46cf..136cc96be70cafa57951fc7edd89c784892803b1 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 #![warn(clippy::manual_async_fn)]
 #![allow(unused)]
 
index 68c0e591f0b6eed6b4ffd5eeb1b8bd0fde47bae1..ddc453ffdb7500958c5e26cbf62a65a4859640f7 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 #![warn(clippy::manual_async_fn)]
 #![allow(unused)]
 
index 51f1a52b6dd65154d3b50d0a56bedfb8d24c37c9..7435f46074c8167287b383f5cee7f67c3e5afb0f 100644 (file)
@@ -1,5 +1,5 @@
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:8:1
+  --> $DIR/manual_async_fn.rs:7:1
    |
 LL | fn fut() -> impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL | fn fut() -> impl Future<Output = i32> { 42 }
    |                                       ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:13:1
+  --> $DIR/manual_async_fn.rs:12:1
    |
 LL | fn fut2() ->impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -30,7 +30,7 @@ LL | fn fut2() ->impl Future<Output = i32> { 42 }
    |                                       ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:18:1
+  --> $DIR/manual_async_fn.rs:17:1
    |
 LL | fn fut3()-> impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL | fn fut3()-> impl Future<Output = i32> { 42 }
    |                                       ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:22:1
+  --> $DIR/manual_async_fn.rs:21:1
    |
 LL | fn empty_fut() -> impl Future<Output = ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL | fn empty_fut() -> impl Future<Output = ()> {}
    |                                            ~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:27:1
+  --> $DIR/manual_async_fn.rs:26:1
    |
 LL | fn empty_fut2() ->impl Future<Output = ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -75,7 +75,7 @@ LL | fn empty_fut2() ->impl Future<Output = ()> {}
    |                                            ~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:32:1
+  --> $DIR/manual_async_fn.rs:31:1
    |
 LL | fn empty_fut3()-> impl Future<Output = ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL | fn empty_fut3()-> impl Future<Output = ()> {}
    |                                            ~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:36:1
+  --> $DIR/manual_async_fn.rs:35:1
    |
 LL | fn core_fut() -> impl core::future::Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -105,7 +105,7 @@ LL | fn core_fut() -> impl core::future::Future<Output = i32> { 42 }
    |                                                          ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:58:5
+  --> $DIR/manual_async_fn.rs:57:5
    |
 LL |     fn inh_fut() -> impl Future<Output = i32> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -125,7 +125,7 @@ LL +             let c = 21;
  ...
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:93:1
+  --> $DIR/manual_async_fn.rs:92:1
    |
 LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -140,7 +140,7 @@ LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { 42 }
    |                                                      ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:102:1
+  --> $DIR/manual_async_fn.rs:101:1
    |
 LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 40d01df6379a696496028454027d8acaba84f1c8..294d79abc0459fe481a9125f07b1fd8faf67ac69 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // run-rustfix
 
 #![warn(clippy::manual_map)]
index cfef0c5cc4ec66207834005b7b151d666737c0fa..d11bf5ecb825ae28a1ae76ba6f1594199e37dfc8 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // run-rustfix
 
 #![warn(clippy::manual_map)]
index cdc2c0e62a9b9434838946240bbbc1f44e3a7f5c..0036b8151ded0514259d03687784e3597716b977 100644 (file)
@@ -1,5 +1,5 @@
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:15:5
+  --> $DIR/manual_map_option.rs:14:5
    |
 LL | /     match Some(0) {
 LL | |         Some(_) => Some(2),
@@ -10,7 +10,7 @@ LL | |     };
    = note: `-D clippy::manual-map` implied by `-D warnings`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:20:5
+  --> $DIR/manual_map_option.rs:19:5
    |
 LL | /     match Some(0) {
 LL | |         Some(x) => Some(x + 1),
@@ -19,7 +19,7 @@ LL | |     };
    | |_____^ help: try this: `Some(0).map(|x| x + 1)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:25:5
+  --> $DIR/manual_map_option.rs:24:5
    |
 LL | /     match Some("") {
 LL | |         Some(x) => Some(x.is_empty()),
@@ -28,7 +28,7 @@ LL | |     };
    | |_____^ help: try this: `Some("").map(|x| x.is_empty())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:30:5
+  --> $DIR/manual_map_option.rs:29:5
    |
 LL | /     if let Some(x) = Some(0) {
 LL | |         Some(!x)
@@ -38,7 +38,7 @@ LL | |     };
    | |_____^ help: try this: `Some(0).map(|x| !x)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:37:5
+  --> $DIR/manual_map_option.rs:36:5
    |
 LL | /     match Some(0) {
 LL | |         Some(x) => { Some(std::convert::identity(x)) }
@@ -47,7 +47,7 @@ LL | |     };
    | |_____^ help: try this: `Some(0).map(std::convert::identity)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:42:5
+  --> $DIR/manual_map_option.rs:41:5
    |
 LL | /     match Some(&String::new()) {
 LL | |         Some(x) => Some(str::len(x)),
@@ -56,7 +56,7 @@ LL | |     };
    | |_____^ help: try this: `Some(&String::new()).map(|x| str::len(x))`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:52:5
+  --> $DIR/manual_map_option.rs:51:5
    |
 LL | /     match &Some([0, 1]) {
 LL | |         Some(x) => Some(x[0]),
@@ -65,7 +65,7 @@ LL | |     };
    | |_____^ help: try this: `Some([0, 1]).as_ref().map(|x| x[0])`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:57:5
+  --> $DIR/manual_map_option.rs:56:5
    |
 LL | /     match &Some(0) {
 LL | |         &Some(x) => Some(x * 2),
@@ -74,7 +74,7 @@ LL | |     };
    | |_____^ help: try this: `Some(0).map(|x| x * 2)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:62:5
+  --> $DIR/manual_map_option.rs:61:5
    |
 LL | /     match Some(String::new()) {
 LL | |         Some(ref x) => Some(x.is_empty()),
@@ -83,7 +83,7 @@ LL | |     };
    | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:67:5
+  --> $DIR/manual_map_option.rs:66:5
    |
 LL | /     match &&Some(String::new()) {
 LL | |         Some(x) => Some(x.len()),
@@ -92,7 +92,7 @@ LL | |     };
    | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:72:5
+  --> $DIR/manual_map_option.rs:71:5
    |
 LL | /     match &&Some(0) {
 LL | |         &&Some(x) => Some(x + x),
@@ -101,7 +101,7 @@ LL | |     };
    | |_____^ help: try this: `Some(0).map(|x| x + x)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:85:9
+  --> $DIR/manual_map_option.rs:84:9
    |
 LL | /         match &mut Some(String::new()) {
 LL | |             Some(x) => Some(x.push_str("")),
@@ -110,7 +110,7 @@ LL | |         };
    | |_________^ help: try this: `Some(String::new()).as_mut().map(|x| x.push_str(""))`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:91:5
+  --> $DIR/manual_map_option.rs:90:5
    |
 LL | /     match &mut Some(String::new()) {
 LL | |         Some(ref x) => Some(x.len()),
@@ -119,7 +119,7 @@ LL | |     };
    | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:96:5
+  --> $DIR/manual_map_option.rs:95:5
    |
 LL | /     match &mut &Some(String::new()) {
 LL | |         Some(x) => Some(x.is_empty()),
@@ -128,7 +128,7 @@ LL | |     };
    | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:101:5
+  --> $DIR/manual_map_option.rs:100:5
    |
 LL | /     match Some((0, 1, 2)) {
 LL | |         Some((x, y, z)) => Some(x + y + z),
@@ -137,7 +137,7 @@ LL | |     };
    | |_____^ help: try this: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:106:5
+  --> $DIR/manual_map_option.rs:105:5
    |
 LL | /     match Some([1, 2, 3]) {
 LL | |         Some([first, ..]) => Some(first),
@@ -146,7 +146,7 @@ LL | |     };
    | |_____^ help: try this: `Some([1, 2, 3]).map(|[first, ..]| first)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:111:5
+  --> $DIR/manual_map_option.rs:110:5
    |
 LL | /     match &Some((String::new(), "test")) {
 LL | |         Some((x, y)) => Some((y, x)),
@@ -155,7 +155,7 @@ LL | |     };
    | |_____^ help: try this: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:169:5
+  --> $DIR/manual_map_option.rs:168:5
    |
 LL | /     match Some(0) {
 LL | |         Some(x) => Some(vec![x]),
@@ -164,7 +164,7 @@ LL | |     };
    | |_____^ help: try this: `Some(0).map(|x| vec![x])`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:174:5
+  --> $DIR/manual_map_option.rs:173:5
    |
 LL | /     match option_env!("") {
 LL | |         Some(x) => Some(String::from(x)),
@@ -173,7 +173,7 @@ LL | |     };
    | |_____^ help: try this: `option_env!("").map(String::from)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:194:12
+  --> $DIR/manual_map_option.rs:193:12
    |
 LL |       } else if let Some(x) = Some(0) {
    |  ____________^
@@ -184,7 +184,7 @@ LL | |     };
    | |_____^ help: try this: `{ Some(0).map(|x| x + 1) }`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:202:12
+  --> $DIR/manual_map_option.rs:201:12
    |
 LL |       } else if let Some(x) = Some(0) {
    |  ____________^
index ff91c4498ec62afd43c12497579a6a66925fd42a..845986a4eadabeee40414a90d26162cbb4ba5007 100644 (file)
@@ -100,6 +100,13 @@ fn overlapping() {
         _ => (),
     }
 
+    // Issue #7829
+    match 0 {
+        -1..=1 => (),
+        -2..=2 => (),
+        _ => (),
+    }
+
     if let None = Some(42) {
         // nothing
     } else if let None = Some(42) {
index 50246486bb6fc9371206f17adfe284b5e722a566..7e3674ab8c9f2c633094cce82c11d3351ebb8cb8 100644 (file)
@@ -1,5 +1,5 @@
 #![warn(clippy::match_ref_pats)]
-#![allow(clippy::equatable_if_let)]
+#![allow(clippy::equatable_if_let, clippy::enum_variant_names)]
 
 fn ref_pats() {
     {
index 208a4bba3d23c40d5cf2cbe4a2f650c18ba584b5..ac555c87d83b21a14beecece000d2cd7a55cbbdf 100644 (file)
@@ -12,6 +12,49 @@ fn as_str_match() {
     }
 }
 
+fn non_alphabetic() {
+    let var = "~!@#$%^&*()-_=+FOO";
+
+    match var.to_ascii_lowercase().as_str() {
+        "1234567890" => {},
+        "~!@#$%^&*()-_=+foo" => {},
+        "\n\r\t\x7F" => {},
+        _ => {},
+    }
+}
+
+fn unicode_cased() {
+    let var = "ВОДЫ";
+
+    match var.to_lowercase().as_str() {
+        "水" => {},
+        "νερό" => {},
+        "воды" => {},
+        "물" => {},
+        _ => {},
+    }
+}
+
+fn titlecase() {
+    let var = "BarDz";
+
+    match var.to_lowercase().as_str() {
+        "foolj" => {},
+        "bardz" => {},
+        _ => {},
+    }
+}
+
+fn no_case_equivalent() {
+    let var = "barʁ";
+
+    match var.to_uppercase().as_str() {
+        "FOOɕ" => {},
+        "BARʁ" => {},
+        _ => {},
+    }
+}
+
 fn addrof_unary_match() {
     let var = "BAR";
 
@@ -70,6 +113,49 @@ fn as_str_match_mismatch() {
     }
 }
 
+fn non_alphabetic_mismatch() {
+    let var = "~!@#$%^&*()-_=+FOO";
+
+    match var.to_ascii_lowercase().as_str() {
+        "1234567890" => {},
+        "~!@#$%^&*()-_=+Foo" => {},
+        "\n\r\t\x7F" => {},
+        _ => {},
+    }
+}
+
+fn unicode_cased_mismatch() {
+    let var = "ВОДЫ";
+
+    match var.to_lowercase().as_str() {
+        "水" => {},
+        "νερό" => {},
+        "Воды" => {},
+        "물" => {},
+        _ => {},
+    }
+}
+
+fn titlecase_mismatch() {
+    let var = "BarDz";
+
+    match var.to_lowercase().as_str() {
+        "foolj" => {},
+        "barDz" => {},
+        _ => {},
+    }
+}
+
+fn no_case_equivalent_mismatch() {
+    let var = "barʁ";
+
+    match var.to_uppercase().as_str() {
+        "FOOɕ" => {},
+        "bARʁ" => {},
+        _ => {},
+    }
+}
+
 fn addrof_unary_match_mismatch() {
     let var = "BAR";
 
index fa023477a9c334d20c7a934e93091b270bd41bf0..92baa40ef28f06f99746326de19b31e53055d703 100644 (file)
@@ -1,5 +1,5 @@
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:68:9
+  --> $DIR/match_str_case_mismatch.rs:111:9
    |
 LL |         "Bar" => {},
    |         ^^^^^
@@ -11,7 +11,51 @@ LL |         "bar" => {},
    |         ~~~~~
 
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:78:9
+  --> $DIR/match_str_case_mismatch.rs:121:9
+   |
+LL |         "~!@#$%^&*()-_=+Foo" => {},
+   |         ^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider changing the case of this arm to respect `to_ascii_lowercase`
+   |
+LL |         "~!@#$%^&*()-_=+foo" => {},
+   |         ~~~~~~~~~~~~~~~~~~~~
+
+error: this `match` arm has a differing case than its expression
+  --> $DIR/match_str_case_mismatch.rs:133:9
+   |
+LL |         "Воды" => {},
+   |         ^^^^^^
+   |
+help: consider changing the case of this arm to respect `to_lowercase`
+   |
+LL |         "воды" => {},
+   |         ~~~~~~
+
+error: this `match` arm has a differing case than its expression
+  --> $DIR/match_str_case_mismatch.rs:144:9
+   |
+LL |         "barDz" => {},
+   |         ^^^^^^
+   |
+help: consider changing the case of this arm to respect `to_lowercase`
+   |
+LL |         "bardz" => {},
+   |         ~~~~~~
+
+error: this `match` arm has a differing case than its expression
+  --> $DIR/match_str_case_mismatch.rs:154:9
+   |
+LL |         "bARʁ" => {},
+   |         ^^^^^^
+   |
+help: consider changing the case of this arm to respect `to_uppercase`
+   |
+LL |         "BARʁ" => {},
+   |         ~~~~~~
+
+error: this `match` arm has a differing case than its expression
+  --> $DIR/match_str_case_mismatch.rs:164:9
    |
 LL |         "Bar" => {},
    |         ^^^^^
@@ -22,7 +66,7 @@ LL |         "bar" => {},
    |         ~~~~~
 
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:93:9
+  --> $DIR/match_str_case_mismatch.rs:179:9
    |
 LL |         "bAR" => {},
    |         ^^^^^
@@ -32,5 +76,5 @@ help: consider changing the case of this arm to respect `to_ascii_uppercase`
 LL |         "BAR" => {},
    |         ~~~~~
 
-error: aborting due to 3 previous errors
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr
new file mode 100644 (file)
index 0000000..2a40120
--- /dev/null
@@ -0,0 +1,35 @@
+error: `Err(_)` matches all errors
+  --> $DIR/match_wild_err_arm.rs:14:9
+   |
+LL |         Err(_) => panic!("err"),
+   |         ^^^^^^
+   |
+   = note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
+   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+
+error: `Err(_)` matches all errors
+  --> $DIR/match_wild_err_arm.rs:20:9
+   |
+LL |         Err(_) => panic!(),
+   |         ^^^^^^
+   |
+   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+
+error: `Err(_)` matches all errors
+  --> $DIR/match_wild_err_arm.rs:26:9
+   |
+LL |         Err(_) => {
+   |         ^^^^^^
+   |
+   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+
+error: `Err(_e)` matches all errors
+  --> $DIR/match_wild_err_arm.rs:34:9
+   |
+LL |         Err(_e) => panic!(),
+   |         ^^^^^^^
+   |
+   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr
new file mode 100644 (file)
index 0000000..2a40120
--- /dev/null
@@ -0,0 +1,35 @@
+error: `Err(_)` matches all errors
+  --> $DIR/match_wild_err_arm.rs:14:9
+   |
+LL |         Err(_) => panic!("err"),
+   |         ^^^^^^
+   |
+   = note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
+   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+
+error: `Err(_)` matches all errors
+  --> $DIR/match_wild_err_arm.rs:20:9
+   |
+LL |         Err(_) => panic!(),
+   |         ^^^^^^
+   |
+   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+
+error: `Err(_)` matches all errors
+  --> $DIR/match_wild_err_arm.rs:26:9
+   |
+LL |         Err(_) => {
+   |         ^^^^^^
+   |
+   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+
+error: `Err(_e)` matches all errors
+  --> $DIR/match_wild_err_arm.rs:34:9
+   |
+LL |         Err(_e) => panic!(),
+   |         ^^^^^^^
+   |
+   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+
+error: aborting due to 4 previous errors
+
index 823be65efe065703b8481ced833636d15b245373..0a86144b95d5bcc59b148e298783caa02d017217 100644 (file)
@@ -1,3 +1,6 @@
+// revisions: edition2018 edition2021
+// [edition2018] edition:2018
+// [edition2021] edition:2021
 #![feature(exclusive_range_pattern)]
 #![allow(clippy::match_same_arms)]
 #![warn(clippy::match_wild_err_arm)]
diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.stderr
deleted file mode 100644 (file)
index 6a2a029..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-error: `Err(_)` matches all errors
-  --> $DIR/match_wild_err_arm.rs:11:9
-   |
-LL |         Err(_) => panic!("err"),
-   |         ^^^^^^
-   |
-   = note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
-   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
-
-error: `Err(_)` matches all errors
-  --> $DIR/match_wild_err_arm.rs:17:9
-   |
-LL |         Err(_) => panic!(),
-   |         ^^^^^^
-   |
-   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
-
-error: `Err(_)` matches all errors
-  --> $DIR/match_wild_err_arm.rs:23:9
-   |
-LL |         Err(_) => {
-   |         ^^^^^^
-   |
-   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
-
-error: `Err(_e)` matches all errors
-  --> $DIR/match_wild_err_arm.rs:31:9
-   |
-LL |         Err(_e) => panic!(),
-   |         ^^^^^^^
-   |
-   = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
-
-error: aborting due to 4 previous errors
-
index c441b35b9920390c89edfc6ac504716cf25eae2f..977ce54327b3d984a4f61fca7c2967b734a3ce57 100644 (file)
@@ -1,5 +1,4 @@
 // aux-build:option_helpers.rs
-// edition:2018
 
 #![warn(clippy::all, clippy::pedantic)]
 #![allow(
index 4643e09e2702835ac9803b6050b49f1ba7267171..b63672dd6fdbb546dac805e74727f9bf8982851f 100644 (file)
@@ -1,5 +1,5 @@
 error: methods called `new` usually return `Self`
-  --> $DIR/methods.rs:105:5
+  --> $DIR/methods.rs:104:5
    |
 LL | /     fn new() -> i32 {
 LL | |         0
@@ -9,7 +9,7 @@ LL | |     }
    = note: `-D clippy::new-ret-no-self` implied by `-D warnings`
 
 error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead
-  --> $DIR/methods.rs:126:13
+  --> $DIR/methods.rs:125:13
    |
 LL |       let _ = v.iter().filter(|&x| {
    |  _____________^
index a9bf7140a1e594ae61cf64f9a000ee6716b669b3..148531c285d3d310ed9011992604cf8a5d4c4b43 100644 (file)
@@ -3,7 +3,6 @@
 // injected intrinsics by the compiler.
 #![allow(dead_code)]
 #![feature(global_asm)]
-
 //! Some garbage docs for the crate here
 #![doc = "More garbage"]
 
@@ -90,10 +89,10 @@ fn also_undocumented2() {}
 }
 /// dox
 pub mod public_interface {
-    pub use internal_impl::documented as foo;
-    pub use internal_impl::globbed::*;
-    pub use internal_impl::undocumented1 as bar;
-    pub use internal_impl::{documented, undocumented2};
+    pub use crate::internal_impl::documented as foo;
+    pub use crate::internal_impl::globbed::*;
+    pub use crate::internal_impl::undocumented1 as bar;
+    pub use crate::internal_impl::{documented, undocumented2};
 }
 
 fn main() {}
index a876dc078ebff96f25c8e34efad90156b896a70a..7a3a448c9d6c2730e407e220b73297e57e576119 100644 (file)
@@ -1,5 +1,5 @@
 error: missing documentation for a type alias
-  --> $DIR/missing-doc.rs:10:1
+  --> $DIR/missing-doc.rs:9:1
    |
 LL | type Typedef = String;
    | ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,37 +7,37 @@ LL | type Typedef = String;
    = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
 
 error: missing documentation for a type alias
-  --> $DIR/missing-doc.rs:11:1
+  --> $DIR/missing-doc.rs:10:1
    |
 LL | pub type PubTypedef = String;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a module
-  --> $DIR/missing-doc.rs:13:1
+  --> $DIR/missing-doc.rs:12:1
    |
 LL | mod module_no_dox {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a module
-  --> $DIR/missing-doc.rs:14:1
+  --> $DIR/missing-doc.rs:13:1
    |
 LL | pub mod pub_module_no_dox {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/missing-doc.rs:18:1
+  --> $DIR/missing-doc.rs:17:1
    |
 LL | pub fn foo2() {}
    | ^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/missing-doc.rs:19:1
+  --> $DIR/missing-doc.rs:18:1
    |
 LL | fn foo3() {}
    | ^^^^^^^^^^^^
 
 error: missing documentation for an enum
-  --> $DIR/missing-doc.rs:33:1
+  --> $DIR/missing-doc.rs:32:1
    |
 LL | / enum Baz {
 LL | |     BazA { a: isize, b: isize },
@@ -46,31 +46,31 @@ LL | | }
    | |_^
 
 error: missing documentation for a variant
-  --> $DIR/missing-doc.rs:34:5
+  --> $DIR/missing-doc.rs:33:5
    |
 LL |     BazA { a: isize, b: isize },
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a struct field
-  --> $DIR/missing-doc.rs:34:12
+  --> $DIR/missing-doc.rs:33:12
    |
 LL |     BazA { a: isize, b: isize },
    |            ^^^^^^^^
 
 error: missing documentation for a struct field
-  --> $DIR/missing-doc.rs:34:22
+  --> $DIR/missing-doc.rs:33:22
    |
 LL |     BazA { a: isize, b: isize },
    |                      ^^^^^^^^
 
 error: missing documentation for a variant
-  --> $DIR/missing-doc.rs:35:5
+  --> $DIR/missing-doc.rs:34:5
    |
 LL |     BarB,
    |     ^^^^
 
 error: missing documentation for an enum
-  --> $DIR/missing-doc.rs:38:1
+  --> $DIR/missing-doc.rs:37:1
    |
 LL | / pub enum PubBaz {
 LL | |     PubBazA { a: isize },
@@ -78,43 +78,43 @@ LL | | }
    | |_^
 
 error: missing documentation for a variant
-  --> $DIR/missing-doc.rs:39:5
+  --> $DIR/missing-doc.rs:38:5
    |
 LL |     PubBazA { a: isize },
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a struct field
-  --> $DIR/missing-doc.rs:39:15
+  --> $DIR/missing-doc.rs:38:15
    |
 LL |     PubBazA { a: isize },
    |               ^^^^^^^^
 
 error: missing documentation for a constant
-  --> $DIR/missing-doc.rs:59:1
+  --> $DIR/missing-doc.rs:58:1
    |
 LL | const FOO: u32 = 0;
    | ^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a constant
-  --> $DIR/missing-doc.rs:66:1
+  --> $DIR/missing-doc.rs:65:1
    |
 LL | pub const FOO4: u32 = 0;
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a static
-  --> $DIR/missing-doc.rs:68:1
+  --> $DIR/missing-doc.rs:67:1
    |
 LL | static BAR: u32 = 0;
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a static
-  --> $DIR/missing-doc.rs:75:1
+  --> $DIR/missing-doc.rs:74:1
    |
 LL | pub static BAR4: u32 = 0;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a module
-  --> $DIR/missing-doc.rs:77:1
+  --> $DIR/missing-doc.rs:76:1
    |
 LL | / mod internal_impl {
 LL | |     /// dox
@@ -126,31 +126,31 @@ LL | | }
    | |_^
 
 error: missing documentation for a function
-  --> $DIR/missing-doc.rs:80:5
+  --> $DIR/missing-doc.rs:79:5
    |
 LL |     pub fn undocumented1() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/missing-doc.rs:81:5
+  --> $DIR/missing-doc.rs:80:5
    |
 LL |     pub fn undocumented2() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/missing-doc.rs:82:5
+  --> $DIR/missing-doc.rs:81:5
    |
 LL |     fn undocumented3() {}
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/missing-doc.rs:87:9
+  --> $DIR/missing-doc.rs:86:9
    |
 LL |         pub fn also_undocumented1() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/missing-doc.rs:88:9
+  --> $DIR/missing-doc.rs:87:9
    |
 LL |         fn also_undocumented2() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
index 2e1379a58a67bbd2a32f1676fa684445e194cda9..7dc44529206d551a423dbfea3762038b3b610074 100644 (file)
@@ -1,6 +1,5 @@
 #![warn(clippy::missing_panics_doc)]
 #![allow(clippy::option_map_unit_fn)]
-
 fn main() {}
 
 /// This needs to be documented
index b863063b626dbe68183eda66c717ef6156b78881..60282939ef0334008f00c7d78ea12693c2b22595 100644 (file)
@@ -1,5 +1,5 @@
 error: docs for function which may panic missing `# Panics` section
-  --> $DIR/missing_panics_doc.rs:7:1
+  --> $DIR/missing_panics_doc.rs:6:1
    |
 LL | / pub fn unwrap() {
 LL | |     let result = Err("Hi");
@@ -9,13 +9,13 @@ LL | | }
    |
    = note: `-D clippy::missing-panics-doc` implied by `-D warnings`
 note: first possible panic found here
-  --> $DIR/missing_panics_doc.rs:9:5
+  --> $DIR/missing_panics_doc.rs:8:5
    |
 LL |     result.unwrap()
    |     ^^^^^^^^^^^^^^^
 
 error: docs for function which may panic missing `# Panics` section
-  --> $DIR/missing_panics_doc.rs:13:1
+  --> $DIR/missing_panics_doc.rs:12:1
    |
 LL | / pub fn panic() {
 LL | |     panic!("This function panics")
@@ -23,14 +23,14 @@ LL | | }
    | |_^
    |
 note: first possible panic found here
-  --> $DIR/missing_panics_doc.rs:14:5
+  --> $DIR/missing_panics_doc.rs:13:5
    |
 LL |     panic!("This function panics")
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: docs for function which may panic missing `# Panics` section
-  --> $DIR/missing_panics_doc.rs:18:1
+  --> $DIR/missing_panics_doc.rs:17:1
    |
 LL | / pub fn todo() {
 LL | |     todo!()
@@ -38,14 +38,14 @@ LL | | }
    | |_^
    |
 note: first possible panic found here
-  --> $DIR/missing_panics_doc.rs:19:5
+  --> $DIR/missing_panics_doc.rs:18:5
    |
 LL |     todo!()
    |     ^^^^^^^
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: docs for function which may panic missing `# Panics` section
-  --> $DIR/missing_panics_doc.rs:23:1
+  --> $DIR/missing_panics_doc.rs:22:1
    |
 LL | / pub fn inner_body(opt: Option<u32>) {
 LL | |     opt.map(|x| {
@@ -57,14 +57,14 @@ LL | | }
    | |_^
    |
 note: first possible panic found here
-  --> $DIR/missing_panics_doc.rs:26:13
+  --> $DIR/missing_panics_doc.rs:25:13
    |
 LL |             panic!()
    |             ^^^^^^^^
-   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: docs for function which may panic missing `# Panics` section
-  --> $DIR/missing_panics_doc.rs:32:1
+  --> $DIR/missing_panics_doc.rs:31:1
    |
 LL | / pub fn unreachable_and_panic() {
 LL | |     if true { unreachable!() } else { panic!() }
@@ -72,14 +72,14 @@ LL | | }
    | |_^
    |
 note: first possible panic found here
-  --> $DIR/missing_panics_doc.rs:33:39
+  --> $DIR/missing_panics_doc.rs:32:39
    |
 LL |     if true { unreachable!() } else { panic!() }
    |                                       ^^^^^^^^
-   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: docs for function which may panic missing `# Panics` section
-  --> $DIR/missing_panics_doc.rs:37:1
+  --> $DIR/missing_panics_doc.rs:36:1
    |
 LL | / pub fn assert_eq() {
 LL | |     let x = 0;
@@ -88,14 +88,14 @@ LL | | }
    | |_^
    |
 note: first possible panic found here
-  --> $DIR/missing_panics_doc.rs:39:5
+  --> $DIR/missing_panics_doc.rs:38:5
    |
 LL |     assert_eq!(x, 0);
    |     ^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: docs for function which may panic missing `# Panics` section
-  --> $DIR/missing_panics_doc.rs:43:1
+  --> $DIR/missing_panics_doc.rs:42:1
    |
 LL | / pub fn assert_ne() {
 LL | |     let x = 0;
@@ -104,7 +104,7 @@ LL | | }
    | |_^
    |
 note: first possible panic found here
-  --> $DIR/missing_panics_doc.rs:45:5
+  --> $DIR/missing_panics_doc.rs:44:5
    |
 LL |     assert_ne!(x, 0);
    |     ^^^^^^^^^^^^^^^^
index 7a8137778b44607cd397c03b04205f43e27aeb84..04b6283da3c3b88d8a5b16c44edfd5d53133dbe6 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // FIXME: run-rustfix waiting on multi-span suggestions
 
 #![warn(clippy::needless_borrow)]
index 365ecd68d8ff2e9cabc8e0635670712e744d17b1..db3b52b8850e1cfd252e3eda54933f1abe4f8b60 100644 (file)
@@ -1,5 +1,5 @@
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:60:14
+  --> $DIR/needless_borrow_pat.rs:59:14
    |
 LL |         Some(ref x) => x,
    |              ^^^^^ help: try this: `x`
@@ -7,7 +7,7 @@ LL |         Some(ref x) => x,
    = note: `-D clippy::needless-borrow` implied by `-D warnings`
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:66:14
+  --> $DIR/needless_borrow_pat.rs:65:14
    |
 LL |         Some(ref x) => *x,
    |              ^^^^^
@@ -18,7 +18,7 @@ LL |         Some(x) => x,
    |              ~     ~
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:72:14
+  --> $DIR/needless_borrow_pat.rs:71:14
    |
 LL |         Some(ref x) => {
    |              ^^^^^
@@ -31,19 +31,19 @@ LL ~             f1(x);
    |
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:82:14
+  --> $DIR/needless_borrow_pat.rs:81:14
    |
 LL |         Some(ref x) => m1!(x),
    |              ^^^^^ help: try this: `x`
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:87:15
+  --> $DIR/needless_borrow_pat.rs:86:15
    |
 LL |     let _ = |&ref x: &&String| {
    |               ^^^^^ help: try this: `x`
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:92:10
+  --> $DIR/needless_borrow_pat.rs:91:10
    |
 LL |     let (ref y,) = (&x,);
    |          ^^^^^
@@ -55,13 +55,13 @@ LL ~     let _: &String = y;
    |
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:102:14
+  --> $DIR/needless_borrow_pat.rs:101:14
    |
 LL |         Some(ref x) => x.0,
    |              ^^^^^ help: try this: `x`
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:112:14
+  --> $DIR/needless_borrow_pat.rs:111:14
    |
 LL |         E::A(ref x) | E::B(ref x) => *x,
    |              ^^^^^         ^^^^^
@@ -72,13 +72,13 @@ LL |         E::A(x) | E::B(x) => x,
    |              ~         ~     ~
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:118:21
+  --> $DIR/needless_borrow_pat.rs:117:21
    |
 LL |         if let Some(ref x) = Some(&String::new());
    |                     ^^^^^ help: try this: `x`
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:126:12
+  --> $DIR/needless_borrow_pat.rs:125:12
    |
 LL | fn f2<'a>(&ref x: &&'a String) -> &'a String {
    |            ^^^^^
@@ -91,13 +91,13 @@ LL ~     x
    |
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:133:11
+  --> $DIR/needless_borrow_pat.rs:132:11
    |
 LL |     fn f(&ref x: &&String) {
    |           ^^^^^ help: try this: `x`
 
 error: this pattern creates a reference to a reference
-  --> $DIR/needless_borrow_pat.rs:141:11
+  --> $DIR/needless_borrow_pat.rs:140:11
    |
 LL |     fn f(&ref x: &&String) {
    |           ^^^^^
index 1d77382bf2cd1132549232dd03fe41af93de9389..b07c4a2381031f2f4c617c4e355e904c8243f9a6 100644 (file)
@@ -27,6 +27,11 @@ fn multiple_in_and_out_2<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
     x
 }
 
+// No error; multiple input refs
+async fn func<'a>(args: &[&'a str]) -> Option<&'a str> {
+    args.get(0).cloned()
+}
+
 // No error; static involved.
 fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 {
     x
index 33a6de1618d12c1a509df271c43b8f57e11d9282..4114e6f1832fc694ddbffecd65819900de31df43 100644 (file)
@@ -19,133 +19,133 @@ 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:45:1
+  --> $DIR/needless_lifetimes.rs:50: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:50:1
+  --> $DIR/needless_lifetimes.rs:55: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:62:1
+  --> $DIR/needless_lifetimes.rs:67:1
    |
 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:86:1
+  --> $DIR/needless_lifetimes.rs:91:1
    |
 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:116:5
+  --> $DIR/needless_lifetimes.rs:121: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:125:5
+  --> $DIR/needless_lifetimes.rs:130: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:144:1
+  --> $DIR/needless_lifetimes.rs:149:1
    |
 LL | fn struct_with_lt<'a>(_foo: Foo<'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:174:1
+  --> $DIR/needless_lifetimes.rs:179: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:180:1
+  --> $DIR/needless_lifetimes.rs:185:1
    |
 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:199:1
+  --> $DIR/needless_lifetimes.rs:204: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:207:1
+  --> $DIR/needless_lifetimes.rs:212: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:243:1
+  --> $DIR/needless_lifetimes.rs:248:1
    |
 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:250:9
+  --> $DIR/needless_lifetimes.rs:255: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:254:9
+  --> $DIR/needless_lifetimes.rs:259: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:267:9
+  --> $DIR/needless_lifetimes.rs:272: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:296:5
+  --> $DIR/needless_lifetimes.rs:301:5
    |
 LL |     fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b 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:299:5
+  --> $DIR/needless_lifetimes.rs:304: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:308:5
+  --> $DIR/needless_lifetimes.rs:313: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:320:5
+  --> $DIR/needless_lifetimes.rs:325: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:335:5
+  --> $DIR/needless_lifetimes.rs:340: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:348:5
+  --> $DIR/needless_lifetimes.rs:353: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:351:5
+  --> $DIR/needless_lifetimes.rs:356:5
    |
 LL |     fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 9c999e12b4cbc4c6d5a3afed29e97cffa3638623..812ce7163cd50ab215cd7130493b1e816d71ccf4 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 
 #![feature(let_else)]
 #![allow(unused)]
index da7dcf4f0a9ea377596a830996947f6d5afa60fb..c42567b517c9115819b3446d5c5281c0da273884 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 
 #![feature(let_else)]
 #![allow(unused)]
index 2e802cff1e686917ddef5a3c5e1ba7421c617ec4..74dda971fdabb632633f4a125ba15d6e2d5ad1a3 100644 (file)
@@ -1,5 +1,5 @@
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:25:5
+  --> $DIR/needless_return.rs:24:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^^ help: remove `return`: `true`
@@ -7,187 +7,187 @@ LL |     return true;
    = note: `-D clippy::needless-return` implied by `-D warnings`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:29:5
+  --> $DIR/needless_return.rs:28:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:34:9
+  --> $DIR/needless_return.rs:33:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:36:9
+  --> $DIR/needless_return.rs:35:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^^ help: remove `return`: `false`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:42:17
+  --> $DIR/needless_return.rs:41:17
    |
 LL |         true => return false,
    |                 ^^^^^^^^^^^^ help: remove `return`: `false`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:44:13
+  --> $DIR/needless_return.rs:43:13
    |
 LL |             return true;
    |             ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:51:9
+  --> $DIR/needless_return.rs:50:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:53:16
+  --> $DIR/needless_return.rs:52:16
    |
 LL |     let _ = || return true;
    |                ^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:61:5
+  --> $DIR/needless_return.rs:60:5
    |
 LL |     return;
    |     ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:66:9
+  --> $DIR/needless_return.rs:65:9
    |
 LL |         return;
    |         ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:68:9
+  --> $DIR/needless_return.rs:67:9
    |
 LL |         return;
    |         ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:75:14
+  --> $DIR/needless_return.rs:74:14
    |
 LL |         _ => return,
    |              ^^^^^^ help: replace `return` with an empty block: `{}`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:90:9
+  --> $DIR/needless_return.rs:89:9
    |
 LL |         return String::from("test");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:92:9
+  --> $DIR/needless_return.rs:91:9
    |
 LL |         return String::new();
    |         ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:113:32
+  --> $DIR/needless_return.rs:112:32
    |
 LL |         bar.unwrap_or_else(|_| return)
    |                                ^^^^^^ help: replace `return` with an empty block: `{}`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:118:13
+  --> $DIR/needless_return.rs:117:13
    |
 LL |             return;
    |             ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:120:20
+  --> $DIR/needless_return.rs:119:20
    |
 LL |         let _ = || return;
    |                    ^^^^^^ help: replace `return` with an empty block: `{}`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:126:32
+  --> $DIR/needless_return.rs:125:32
    |
 LL |         res.unwrap_or_else(|_| return Foo)
    |                                ^^^^^^^^^^ help: remove `return`: `Foo`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:135:5
+  --> $DIR/needless_return.rs:134:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:139:5
+  --> $DIR/needless_return.rs:138:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:144:9
+  --> $DIR/needless_return.rs:143:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:146:9
+  --> $DIR/needless_return.rs:145:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^^ help: remove `return`: `false`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:152:17
+  --> $DIR/needless_return.rs:151:17
    |
 LL |         true => return false,
    |                 ^^^^^^^^^^^^ help: remove `return`: `false`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:154:13
+  --> $DIR/needless_return.rs:153:13
    |
 LL |             return true;
    |             ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:161:9
+  --> $DIR/needless_return.rs:160:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:163:16
+  --> $DIR/needless_return.rs:162:16
    |
 LL |     let _ = || return true;
    |                ^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:171:5
+  --> $DIR/needless_return.rs:170:5
    |
 LL |     return;
    |     ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:176:9
+  --> $DIR/needless_return.rs:175:9
    |
 LL |         return;
    |         ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:178:9
+  --> $DIR/needless_return.rs:177:9
    |
 LL |         return;
    |         ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:185:14
+  --> $DIR/needless_return.rs:184:14
    |
 LL |         _ => return,
    |              ^^^^^^ help: replace `return` with an empty block: `{}`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:200:9
+  --> $DIR/needless_return.rs:199:9
    |
 LL |         return String::from("test");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:202:9
+  --> $DIR/needless_return.rs:201:9
    |
 LL |         return String::new();
    |         ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()`
index 58415b4aede260b668dbd3db7a0f9a56bc56ecd8..961f6f409ddd2202916bfe14c17111d208359592 100644 (file)
@@ -15,8 +15,8 @@ struct InstSplit {
 impl MaybeInst {
     fn fill(&mut self) {
         let filled = match *self {
-            MaybeInst::Split1(goto1) => panic!(1),
-            MaybeInst::Split2(goto2) => panic!(2),
+            MaybeInst::Split1(goto1) => panic!("1"),
+            MaybeInst::Split2(goto2) => panic!("2"),
             _ => unimplemented!(),
         };
         unimplemented!()
index 4077f1920a3837758a6f02f6f5b5ea8c6a2b078e..9cb6a9d1ecc9bc9e91c0cf071c748ab45a962711 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
 #![allow(clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let)]
index 2f414e129d5a77c9952b88bd8e9efa5d0acc4249..b3ba5eb870a693e65053cf50bbc1c914520fbe4a 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
 #![allow(clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let)]
index 803d941c36df8b2d8aa80ca7fa381ee8c35c780a..685bb48ea37bc05baf1945d6a66b7c12f69c0934 100644 (file)
@@ -1,5 +1,5 @@
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:7:5
+  --> $DIR/option_if_let_else.rs:6:5
    |
 LL | /     if let Some(x) = string {
 LL | |         (true, x)
@@ -11,19 +11,19 @@ LL | |     }
    = note: `-D clippy::option-if-let-else` implied by `-D warnings`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:25:13
+  --> $DIR/option_if_let_else.rs:24:13
    |
 LL |     let _ = if let Some(s) = *string { s.len() } else { 0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:26:13
+  --> $DIR/option_if_let_else.rs:25:13
    |
 LL |     let _ = if let Some(s) = &num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:27:13
+  --> $DIR/option_if_let_else.rs:26:13
    |
 LL |       let _ = if let Some(s) = &mut num {
    |  _____________^
@@ -43,13 +43,13 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:33:13
+  --> $DIR/option_if_let_else.rs:32:13
    |
 LL |     let _ = if let Some(ref s) = num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:34:13
+  --> $DIR/option_if_let_else.rs:33:13
    |
 LL |       let _ = if let Some(mut s) = num {
    |  _____________^
@@ -69,7 +69,7 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:40:13
+  --> $DIR/option_if_let_else.rs:39:13
    |
 LL |       let _ = if let Some(ref mut s) = num {
    |  _____________^
@@ -89,7 +89,7 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:49:5
+  --> $DIR/option_if_let_else.rs:48:5
    |
 LL | /     if let Some(x) = arg {
 LL | |         let y = x * x;
@@ -108,7 +108,7 @@ LL +     })
    |
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:62:13
+  --> $DIR/option_if_let_else.rs:61:13
    |
 LL |       let _ = if let Some(x) = arg {
    |  _____________^
@@ -120,7 +120,7 @@ LL | |     };
    | |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)`
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:71:13
+  --> $DIR/option_if_let_else.rs:70:13
    |
 LL |       let _ = if let Some(x) = arg {
    |  _____________^
@@ -143,13 +143,13 @@ LL ~     }, |x| x * x * x * x);
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:100:13
+  --> $DIR/option_if_let_else.rs:99:13
    |
 LL |     let _ = if let Some(x) = optional { x + 2 } else { 5 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:109:13
+  --> $DIR/option_if_let_else.rs:108:13
    |
 LL |       let _ = if let Some(x) = Some(0) {
    |  _____________^
@@ -171,13 +171,13 @@ LL ~         });
    |
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:137:13
+  --> $DIR/option_if_let_else.rs:136:13
    |
 LL |     let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or_else(|| s.len(), |x| s.len() + x)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:141:13
+  --> $DIR/option_if_let_else.rs:140:13
    |
 LL |       let _ = if let Some(x) = Some(0) {
    |  _____________^
index 3d3c19a1be5199e70c2a08f6c439aaca2e8a9645..e75eb1b6eadd85ca225d830e3cb8ffe96bf584fa 100644 (file)
@@ -1,6 +1,5 @@
 #![warn(clippy::panic_in_result_fn)]
 #![allow(clippy::unnecessary_wraps)]
-
 struct A;
 
 impl A {
index f56c2d03c664fb2d98448f7127c92acabb6b2bdc..78d09b8b2108a134b0c91a4c37e5bbd238de6387 100644 (file)
@@ -1,5 +1,5 @@
 error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
-  --> $DIR/panic_in_result_fn.rs:7:5
+  --> $DIR/panic_in_result_fn.rs:6:5
    |
 LL | /     fn result_with_panic() -> Result<bool, String> // should emit lint
 LL | |     {
@@ -10,14 +10,14 @@ LL | |     }
    = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
    = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
-  --> $DIR/panic_in_result_fn.rs:9:9
+  --> $DIR/panic_in_result_fn.rs:8:9
    |
 LL |         panic!("error");
    |         ^^^^^^^^^^^^^^^
-   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
-  --> $DIR/panic_in_result_fn.rs:12:5
+  --> $DIR/panic_in_result_fn.rs:11:5
    |
 LL | /     fn result_with_unimplemented() -> Result<bool, String> // should emit lint
 LL | |     {
@@ -27,14 +27,14 @@ LL | |     }
    |
    = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
-  --> $DIR/panic_in_result_fn.rs:14:9
+  --> $DIR/panic_in_result_fn.rs:13:9
    |
 LL |         unimplemented!();
    |         ^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
-  --> $DIR/panic_in_result_fn.rs:17:5
+  --> $DIR/panic_in_result_fn.rs:16:5
    |
 LL | /     fn result_with_unreachable() -> Result<bool, String> // should emit lint
 LL | |     {
@@ -44,14 +44,14 @@ LL | |     }
    |
    = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
-  --> $DIR/panic_in_result_fn.rs:19:9
+  --> $DIR/panic_in_result_fn.rs:18:9
    |
 LL |         unreachable!();
    |         ^^^^^^^^^^^^^^
    = note: this error originates in the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
-  --> $DIR/panic_in_result_fn.rs:22:5
+  --> $DIR/panic_in_result_fn.rs:21:5
    |
 LL | /     fn result_with_todo() -> Result<bool, String> // should emit lint
 LL | |     {
@@ -61,14 +61,14 @@ LL | |     }
    |
    = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
-  --> $DIR/panic_in_result_fn.rs:24:9
+  --> $DIR/panic_in_result_fn.rs:23:9
    |
 LL |         todo!("Finish this");
    |         ^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `todo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
-  --> $DIR/panic_in_result_fn.rs:53:1
+  --> $DIR/panic_in_result_fn.rs:52:1
    |
 LL | / fn function_result_with_panic() -> Result<bool, String> // should emit lint
 LL | | {
@@ -78,14 +78,14 @@ LL | | }
    |
    = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
-  --> $DIR/panic_in_result_fn.rs:55:5
+  --> $DIR/panic_in_result_fn.rs:54:5
    |
 LL |     panic!("error");
    |     ^^^^^^^^^^^^^^^
-   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
-  --> $DIR/panic_in_result_fn.rs:68:1
+  --> $DIR/panic_in_result_fn.rs:67:1
    |
 LL | / fn main() -> Result<(), String> {
 LL | |     todo!("finish main method");
@@ -95,7 +95,7 @@ LL | | }
    |
    = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
-  --> $DIR/panic_in_result_fn.rs:69:5
+  --> $DIR/panic_in_result_fn.rs:68:5
    |
 LL |     todo!("finish main method");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 99e6d2aad8dd6b46ac5229da0866d36218688f0a..67bfef06a05e8cdd3e7b73c19fbc629d5e6fbf3e 100644 (file)
@@ -1,9 +1,4 @@
-#![allow(
-    unused,
-    clippy::many_single_char_names,
-    clippy::redundant_clone,
-    clippy::if_then_panic
-)]
+#![allow(unused, clippy::many_single_char_names, clippy::redundant_clone)]
 #![warn(clippy::ptr_arg)]
 
 use std::borrow::Cow;
@@ -160,3 +155,7 @@ fn foo_str(str: &PathBuf) {
         let _ = str.clone().clone();
     }
 }
+
+// No error for types behind an alias (#7699)
+type A = Vec<u8>;
+fn aliased(a: &A) {}
index 42183447ead737cf34275a3fe9be5edf01a406c4..64594eb870c2c5067b413095f6eabdeded968ebc 100644 (file)
@@ -1,5 +1,5 @@
 error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices
-  --> $DIR/ptr_arg.rs:12:14
+  --> $DIR/ptr_arg.rs:7:14
    |
 LL | fn do_vec(x: &Vec<i64>) {
    |              ^^^^^^^^^ help: change this to: `&[i64]`
@@ -7,25 +7,25 @@ LL | fn do_vec(x: &Vec<i64>) {
    = note: `-D clippy::ptr-arg` implied by `-D warnings`
 
 error: writing `&String` instead of `&str` involves a new object where a slice will do
-  --> $DIR/ptr_arg.rs:21:14
+  --> $DIR/ptr_arg.rs:16:14
    |
 LL | fn do_str(x: &String) {
    |              ^^^^^^^ help: change this to: `&str`
 
 error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
-  --> $DIR/ptr_arg.rs:30:15
+  --> $DIR/ptr_arg.rs:25:15
    |
 LL | fn do_path(x: &PathBuf) {
    |               ^^^^^^^^ help: change this to: `&Path`
 
 error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices
-  --> $DIR/ptr_arg.rs:43:18
+  --> $DIR/ptr_arg.rs:38:18
    |
 LL |     fn do_vec(x: &Vec<i64>);
    |                  ^^^^^^^^^ help: change this to: `&[i64]`
 
 error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices
-  --> $DIR/ptr_arg.rs:56:14
+  --> $DIR/ptr_arg.rs:51:14
    |
 LL | fn cloned(x: &Vec<u8>) -> Vec<u8> {
    |              ^^^^^^^^
@@ -44,7 +44,7 @@ LL |     x.to_owned()
    |
 
 error: writing `&String` instead of `&str` involves a new object where a slice will do
-  --> $DIR/ptr_arg.rs:65:18
+  --> $DIR/ptr_arg.rs:60:18
    |
 LL | fn str_cloned(x: &String) -> String {
    |                  ^^^^^^^
@@ -67,7 +67,7 @@ LL |     x.to_string()
    |
 
 error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
-  --> $DIR/ptr_arg.rs:73:19
+  --> $DIR/ptr_arg.rs:68:19
    |
 LL | fn path_cloned(x: &PathBuf) -> PathBuf {
    |                   ^^^^^^^^
@@ -90,7 +90,7 @@ LL |     x.to_path_buf()
    |
 
 error: writing `&String` instead of `&str` involves a new object where a slice will do
-  --> $DIR/ptr_arg.rs:81:44
+  --> $DIR/ptr_arg.rs:76:44
    |
 LL | fn false_positive_capacity(x: &Vec<u8>, y: &String) {
    |                                            ^^^^^^^
@@ -109,13 +109,13 @@ LL |     let c = y;
    |             ~
 
 error: using a reference to `Cow` is not recommended
-  --> $DIR/ptr_arg.rs:95:25
+  --> $DIR/ptr_arg.rs:90:25
    |
 LL | fn test_cow_with_ref(c: &Cow<[i32]>) {}
    |                         ^^^^^^^^^^^ help: change this to: `&[i32]`
 
 error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices
-  --> $DIR/ptr_arg.rs:148:21
+  --> $DIR/ptr_arg.rs:143:21
    |
 LL |     fn foo_vec(vec: &Vec<u8>) {
    |                     ^^^^^^^^
@@ -134,7 +134,7 @@ LL |         let _ = vec.to_owned().clone();
    |                 ~~~~~~~~~~~~~~
 
 error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
-  --> $DIR/ptr_arg.rs:153:23
+  --> $DIR/ptr_arg.rs:148:23
    |
 LL |     fn foo_path(path: &PathBuf) {
    |                       ^^^^^^^^
@@ -153,7 +153,7 @@ LL |         let _ = path.to_path_buf().clone();
    |                 ~~~~~~~~~~~~~~~~~~
 
 error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
-  --> $DIR/ptr_arg.rs:158:21
+  --> $DIR/ptr_arg.rs:153:21
    |
 LL |     fn foo_str(str: &PathBuf) {
    |                     ^^^^^^^^
index ccb2e5a302e91590feb0ba2af50ae467e00e8115..e93469e5f556bd55737c0628961e540e7caf5be1 100644 (file)
@@ -104,7 +104,11 @@ fn func() -> Option<i32> {
     Some(0)
 }
 
-fn result_func(x: Result<i32, &str>) -> Result<i32, &str> {
+fn func_returning_result() -> Result<i32, i32> {
+    Ok(1)
+}
+
+fn result_func(x: Result<i32, i32>) -> Result<i32, i32> {
     let _ = x?;
 
     x?;
@@ -113,9 +117,22 @@ fn result_func(x: Result<i32, &str>) -> Result<i32, &str> {
     let y = if let Ok(x) = x {
         x
     } else {
-        return Err("some error");
+        return Err(0);
+    };
+
+    // issue #7859
+    // no warning
+    let _ = if let Ok(x) = func_returning_result() {
+        x
+    } else {
+        return Err(0);
     };
 
+    // no warning
+    if func_returning_result().is_err() {
+        return func_returning_result();
+    }
+
     Ok(y)
 }
 
index ca3722371f524b53b27ca94f15fd1a46e7d867ca..dd179e9bee8f87d57c6623617d0b646fb154c684 100644 (file)
@@ -134,7 +134,11 @@ fn f() -> Option<String> {
     Some(0)
 }
 
-fn result_func(x: Result<i32, &str>) -> Result<i32, &str> {
+fn func_returning_result() -> Result<i32, i32> {
+    Ok(1)
+}
+
+fn result_func(x: Result<i32, i32>) -> Result<i32, i32> {
     let _ = if let Ok(x) = x { x } else { return x };
 
     if x.is_err() {
@@ -145,9 +149,22 @@ fn result_func(x: Result<i32, &str>) -> Result<i32, &str> {
     let y = if let Ok(x) = x {
         x
     } else {
-        return Err("some error");
+        return Err(0);
+    };
+
+    // issue #7859
+    // no warning
+    let _ = if let Ok(x) = func_returning_result() {
+        x
+    } else {
+        return Err(0);
     };
 
+    // no warning
+    if func_returning_result().is_err() {
+        return func_returning_result();
+    }
+
     Ok(y)
 }
 
index 161588cb73cba06797561917e4ee5fe6fa3710d9..8d782b71dd6a47ae8368b0d8f8c7ba89b13b34b6 100644 (file)
@@ -101,13 +101,13 @@ LL | |     }
    | |_____^ help: replace it with: `f()?;`
 
 error: this if-let-else may be rewritten with the `?` operator
-  --> $DIR/question_mark.rs:138:13
+  --> $DIR/question_mark.rs:142:13
    |
 LL |     let _ = if let Ok(x) = x { x } else { return x };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x?`
 
 error: this block may be rewritten with the `?` operator
-  --> $DIR/question_mark.rs:140:5
+  --> $DIR/question_mark.rs:144:5
    |
 LL | /     if x.is_err() {
 LL | |         return x;
index 2d711082746e73aab40867f0bcc2285137e5aca2..16b40dcd902869d7184cb1d6b384139166d04380 100644 (file)
@@ -196,7 +196,7 @@ fn clone_then_move_cloned() {
     fn foo<F: Fn()>(_: &Alpha, _: F) {}
     let x = Alpha;
     // ok, data is moved while the clone is in use.
-    foo(&x.clone(), move || {
+    foo(&x, move || {
         let _ = x;
     });
 
index fbc90493ae94b85986e8381ef82e395fbc202e9e..9f59017b26199cad1ae2acb9fe1b96c8048ac363 100644 (file)
@@ -167,5 +167,17 @@ note: cloned value is neither consumed nor mutated
 LL |     let y = x.clone().join("matthias");
    |             ^^^^^^^^^
 
-error: aborting due to 14 previous errors
+error: redundant clone
+  --> $DIR/redundant_clone.rs:199:11
+   |
+LL |     foo(&x.clone(), move || {
+   |           ^^^^^^^^ help: remove this
+   |
+note: this value is dropped without further use
+  --> $DIR/redundant_clone.rs:199:10
+   |
+LL |     foo(&x.clone(), move || {
+   |          ^
+
+error: aborting due to 15 previous errors
 
index cd6db8ddc8864fd2a08de85ed9de26c8c31fd553..fe742a4c2f4c5acd69d1300242eb59bb0de67aa2 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // FIXME: run-rustfix waiting on multi-span suggestions
 
 #![warn(clippy::ref_binding_to_reference)]
index eb36cd516a246a9e4f581b7079efb0bacc8cc09d..c5856e15fa987b3a4c19737019941430373606ce 100644 (file)
@@ -1,5 +1,5 @@
 error: this pattern creates a reference to a reference
-  --> $DIR/ref_binding_to_reference.rs:31:14
+  --> $DIR/ref_binding_to_reference.rs:30:14
    |
 LL |         Some(ref x) => x,
    |              ^^^^^
@@ -11,7 +11,7 @@ LL |         Some(x) => &x,
    |              ~     ~~
 
 error: this pattern creates a reference to a reference
-  --> $DIR/ref_binding_to_reference.rs:37:14
+  --> $DIR/ref_binding_to_reference.rs:36:14
    |
 LL |         Some(ref x) => {
    |              ^^^^^
@@ -25,7 +25,7 @@ LL ~             &x
    |
 
 error: this pattern creates a reference to a reference
-  --> $DIR/ref_binding_to_reference.rs:47:14
+  --> $DIR/ref_binding_to_reference.rs:46:14
    |
 LL |         Some(ref x) => m2!(x),
    |              ^^^^^
@@ -36,7 +36,7 @@ LL |         Some(x) => m2!(&x),
    |              ~         ~~
 
 error: this pattern creates a reference to a reference
-  --> $DIR/ref_binding_to_reference.rs:52:15
+  --> $DIR/ref_binding_to_reference.rs:51:15
    |
 LL |     let _ = |&ref x: &&String| {
    |               ^^^^^
@@ -48,7 +48,7 @@ LL ~         let _: &&String = &x;
    |
 
 error: this pattern creates a reference to a reference
-  --> $DIR/ref_binding_to_reference.rs:58:12
+  --> $DIR/ref_binding_to_reference.rs:57:12
    |
 LL | fn f2<'a>(&ref x: &&'a String) -> &'a String {
    |            ^^^^^
@@ -61,7 +61,7 @@ LL ~     x
    |
 
 error: this pattern creates a reference to a reference
-  --> $DIR/ref_binding_to_reference.rs:65:11
+  --> $DIR/ref_binding_to_reference.rs:64:11
    |
 LL |     fn f(&ref x: &&String) {
    |           ^^^^^
@@ -73,7 +73,7 @@ LL ~         let _: &&String = &x;
    |
 
 error: this pattern creates a reference to a reference
-  --> $DIR/ref_binding_to_reference.rs:73:11
+  --> $DIR/ref_binding_to_reference.rs:72:11
    |
 LL |     fn f(&ref x: &&String) {
    |           ^^^^^
index a66c2e587c8736111e067f1b2dd8a41d583840a5..cc295b509bc51973cd1bf3f03d591bee3bc732e3 100644 (file)
@@ -6,15 +6,58 @@
 #![allow(clippy::module_name_repetitions)]
 #![allow(clippy::new_without_default)]
 #![allow(clippy::redundant_static_lifetimes)]
+#![allow(clippy::bind_instead_of_map)]
+#![allow(clippy::box_collection)]
+#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::map_unwrap_or)]
+#![allow(clippy::unwrap_used)]
+#![allow(clippy::expect_used)]
+#![allow(clippy::for_loops_over_fallibles)]
+#![allow(clippy::useless_conversion)]
+#![allow(clippy::invisible_characters)]
+#![allow(clippy::single_char_add_str)]
+#![allow(clippy::match_result_ok)]
+// uplifted lints
+#![allow(invalid_value)]
+#![allow(array_into_iter)]
+#![allow(unused_labels)]
+#![allow(drop_bounds)]
+#![allow(temporary_cstring_as_ptr)]
+#![allow(non_fmt_panics)]
+#![allow(unknown_lints)]
+#![allow(invalid_atomic_ordering)]
+#![allow(enum_intrinsics_non_enums)]
 // warn for the old lint name here, to test if the renaming worked
+#![warn(clippy::module_name_repetitions)]
+#![warn(clippy::new_without_default)]
+#![warn(clippy::redundant_static_lifetimes)]
 #![warn(clippy::cognitive_complexity)]
+#![warn(clippy::bind_instead_of_map)]
+#![warn(clippy::box_collection)]
+#![warn(clippy::blocks_in_if_conditions)]
+#![warn(clippy::blocks_in_if_conditions)]
+#![warn(clippy::map_unwrap_or)]
+#![warn(clippy::map_unwrap_or)]
+#![warn(clippy::map_unwrap_or)]
+#![warn(clippy::unwrap_used)]
+#![warn(clippy::unwrap_used)]
+#![warn(clippy::expect_used)]
+#![warn(clippy::expect_used)]
+#![warn(clippy::for_loops_over_fallibles)]
+#![warn(clippy::for_loops_over_fallibles)]
+#![warn(clippy::useless_conversion)]
+#![warn(clippy::invisible_characters)]
+#![warn(clippy::single_char_add_str)]
+#![warn(clippy::match_result_ok)]
+// uplifted lints
+#![warn(invalid_value)]
+#![warn(array_into_iter)]
+#![warn(unused_labels)]
+#![warn(drop_bounds)]
+#![warn(temporary_cstring_as_ptr)]
+#![warn(non_fmt_panics)]
+#![warn(unknown_lints)]
+#![warn(invalid_atomic_ordering)]
 #![warn(enum_intrinsics_non_enums)]
 
-#[warn(clippy::module_name_repetitions)]
 fn main() {}
-
-#[warn(clippy::new_without_default)]
-struct Foo;
-
-#[warn(clippy::redundant_static_lifetimes)]
-fn foo() {}
index fa81201a2daf305fd675ddf65668882cdb842419..377075c02464a85becebae4817f176745f490ea0 100644 (file)
@@ -6,15 +6,58 @@
 #![allow(clippy::module_name_repetitions)]
 #![allow(clippy::new_without_default)]
 #![allow(clippy::redundant_static_lifetimes)]
+#![allow(clippy::bind_instead_of_map)]
+#![allow(clippy::box_collection)]
+#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::map_unwrap_or)]
+#![allow(clippy::unwrap_used)]
+#![allow(clippy::expect_used)]
+#![allow(clippy::for_loops_over_fallibles)]
+#![allow(clippy::useless_conversion)]
+#![allow(clippy::invisible_characters)]
+#![allow(clippy::single_char_add_str)]
+#![allow(clippy::match_result_ok)]
+// uplifted lints
+#![allow(invalid_value)]
+#![allow(array_into_iter)]
+#![allow(unused_labels)]
+#![allow(drop_bounds)]
+#![allow(temporary_cstring_as_ptr)]
+#![allow(non_fmt_panics)]
+#![allow(unknown_lints)]
+#![allow(invalid_atomic_ordering)]
+#![allow(enum_intrinsics_non_enums)]
 // warn for the old lint name here, to test if the renaming worked
+#![warn(clippy::stutter)]
+#![warn(clippy::new_without_default_derive)]
+#![warn(clippy::const_static_lifetime)]
 #![warn(clippy::cyclomatic_complexity)]
+#![warn(clippy::option_and_then_some)]
+#![warn(clippy::box_vec)]
+#![warn(clippy::block_in_if_condition_expr)]
+#![warn(clippy::block_in_if_condition_stmt)]
+#![warn(clippy::option_map_unwrap_or)]
+#![warn(clippy::option_map_unwrap_or_else)]
+#![warn(clippy::result_map_unwrap_or_else)]
+#![warn(clippy::option_unwrap_used)]
+#![warn(clippy::result_unwrap_used)]
+#![warn(clippy::option_expect_used)]
+#![warn(clippy::result_expect_used)]
+#![warn(clippy::for_loop_over_option)]
+#![warn(clippy::for_loop_over_result)]
+#![warn(clippy::identity_conversion)]
+#![warn(clippy::zero_width_space)]
+#![warn(clippy::single_char_push_str)]
+#![warn(clippy::if_let_some_result)]
+// uplifted lints
+#![warn(clippy::invalid_ref)]
+#![warn(clippy::into_iter_on_array)]
+#![warn(clippy::unused_label)]
+#![warn(clippy::drop_bounds)]
+#![warn(clippy::temporary_cstring_as_ptr)]
+#![warn(clippy::panic_params)]
+#![warn(clippy::unknown_clippy_lints)]
+#![warn(clippy::invalid_atomic_ordering)]
 #![warn(clippy::mem_discriminant_non_enum)]
 
-#[warn(clippy::stutter)]
 fn main() {}
-
-#[warn(clippy::new_without_default_derive)]
-struct Foo;
-
-#[warn(clippy::const_static_lifetime)]
-fn foo() {}
index 05c7854074c60cd3ba9291173c7c70421cf17ccf..d720f10d117c097ad2df27ae1ac45e9b63e971ee 100644 (file)
+error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
+  --> $DIR/rename.rs:31:9
+   |
+LL | #![warn(clippy::stutter)]
+   |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
+   |
+   = note: `-D renamed-and-removed-lints` implied by `-D warnings`
+
+error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
+  --> $DIR/rename.rs:32:9
+   |
+LL | #![warn(clippy::new_without_default_derive)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
+
+error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
+  --> $DIR/rename.rs:33: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:10:9
+  --> $DIR/rename.rs:34:9
    |
 LL | #![warn(clippy::cyclomatic_complexity)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
+
+error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
+  --> $DIR/rename.rs:35:9
    |
-   = note: `-D renamed-and-removed-lints` implied by `-D warnings`
+LL | #![warn(clippy::option_and_then_some)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
 
-error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
-  --> $DIR/rename.rs:11:9
+error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
+  --> $DIR/rename.rs:36:9
    |
-LL | #![warn(clippy::mem_discriminant_non_enum)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
+LL | #![warn(clippy::box_vec)]
+   |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
 
-error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
-  --> $DIR/rename.rs:13:8
+error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
+  --> $DIR/rename.rs:37:9
    |
-LL | #[warn(clippy::stutter)]
-   |        ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
+LL | #![warn(clippy::block_in_if_condition_expr)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
 
-error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
-  --> $DIR/rename.rs:16:8
+error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
+  --> $DIR/rename.rs:38:9
    |
-LL | #[warn(clippy::new_without_default_derive)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
+LL | #![warn(clippy::block_in_if_condition_stmt)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
 
-error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
-  --> $DIR/rename.rs:19:8
+error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
+  --> $DIR/rename.rs:39: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:40:9
+   |
+LL | #![warn(clippy::option_map_unwrap_or_else)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
+
+error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
+  --> $DIR/rename.rs:41:9
+   |
+LL | #![warn(clippy::result_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:42:9
+   |
+LL | #![warn(clippy::option_unwrap_used)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
+
+error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
+  --> $DIR/rename.rs:43:9
+   |
+LL | #![warn(clippy::result_unwrap_used)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
+
+error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
+  --> $DIR/rename.rs:44:9
+   |
+LL | #![warn(clippy::option_expect_used)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
+
+error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
+  --> $DIR/rename.rs:45:9
+   |
+LL | #![warn(clippy::result_expect_used)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
+
+error: lint `clippy::for_loop_over_option` has been renamed to `clippy::for_loops_over_fallibles`
+  --> $DIR/rename.rs:46:9
+   |
+LL | #![warn(clippy::for_loop_over_option)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
+
+error: lint `clippy::for_loop_over_result` has been renamed to `clippy::for_loops_over_fallibles`
+  --> $DIR/rename.rs:47:9
+   |
+LL | #![warn(clippy::for_loop_over_result)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
+
+error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
+  --> $DIR/rename.rs:48:9
+   |
+LL | #![warn(clippy::identity_conversion)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
+
+error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
+  --> $DIR/rename.rs:49:9
+   |
+LL | #![warn(clippy::zero_width_space)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
+
+error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
+  --> $DIR/rename.rs:50:9
+   |
+LL | #![warn(clippy::single_char_push_str)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
+
+error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
+  --> $DIR/rename.rs:51:9
+   |
+LL | #![warn(clippy::if_let_some_result)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
+
+error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
+  --> $DIR/rename.rs:53:9
+   |
+LL | #![warn(clippy::invalid_ref)]
+   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
+
+error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
+  --> $DIR/rename.rs:54:9
+   |
+LL | #![warn(clippy::into_iter_on_array)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
+
+error: lint `clippy::unused_label` has been renamed to `unused_labels`
+  --> $DIR/rename.rs:55:9
+   |
+LL | #![warn(clippy::unused_label)]
+   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
+
+error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
+  --> $DIR/rename.rs:56:9
+   |
+LL | #![warn(clippy::drop_bounds)]
+   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
+
+error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
+  --> $DIR/rename.rs:57:9
+   |
+LL | #![warn(clippy::temporary_cstring_as_ptr)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
+
+error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
+  --> $DIR/rename.rs:58:9
+   |
+LL | #![warn(clippy::panic_params)]
+   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
+
+error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
+  --> $DIR/rename.rs:59:9
+   |
+LL | #![warn(clippy::unknown_clippy_lints)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
+
+error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
+  --> $DIR/rename.rs:60:9
+   |
+LL | #![warn(clippy::invalid_atomic_ordering)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
+
+error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
+  --> $DIR/rename.rs:61:9
    |
-LL | #[warn(clippy::const_static_lifetime)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
+LL | #![warn(clippy::mem_discriminant_non_enum)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
 
-error: aborting due to 5 previous errors
+error: aborting due to 30 previous errors
 
index a7f8f54f2be04cb98667127b87d3db75c50e1301..d7e8d02bd1998fbab6b24867d1ec325556a6e72f 100644 (file)
@@ -1,5 +1,3 @@
-// edition:2018
-
 #![warn(clippy::all, clippy::pedantic)]
 #![allow(
     clippy::missing_errors_doc,
index 69a3390b03b0b2cac0988e1f35dc1796e0bcd41d..ea962f943173aed4359f392e9ee99de13e9b8ec4 100644 (file)
@@ -1,5 +1,3 @@
-// edition:2018
-
 #![warn(clippy::all, clippy::pedantic)]
 #![allow(
     clippy::missing_errors_doc,
index 86c63946516ce84453725eff5a31b58cb1ac246c..bf8b47d5626d283095c5df5db7ed86cccc2ffb40 100644 (file)
@@ -1,5 +1,5 @@
 error: method `add` can be confused for the standard trait method `std::ops::Add::add`
-  --> $DIR/method_list_1.rs:26:5
+  --> $DIR/method_list_1.rs:24:5
    |
 LL | /     pub fn add(self, other: T) -> T {
 LL | |         unimplemented!()
@@ -10,7 +10,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Add` or choosing a less ambiguous method name
 
 error: method `as_mut` can be confused for the standard trait method `std::convert::AsMut::as_mut`
-  --> $DIR/method_list_1.rs:30:5
+  --> $DIR/method_list_1.rs:28:5
    |
 LL | /     pub fn as_mut(&mut self) -> &mut T {
 LL | |         unimplemented!()
@@ -20,7 +20,7 @@ LL | |     }
    = help: consider implementing the trait `std::convert::AsMut` or choosing a less ambiguous method name
 
 error: method `as_ref` can be confused for the standard trait method `std::convert::AsRef::as_ref`
-  --> $DIR/method_list_1.rs:34:5
+  --> $DIR/method_list_1.rs:32:5
    |
 LL | /     pub fn as_ref(&self) -> &T {
 LL | |         unimplemented!()
@@ -30,7 +30,7 @@ LL | |     }
    = help: consider implementing the trait `std::convert::AsRef` or choosing a less ambiguous method name
 
 error: method `bitand` can be confused for the standard trait method `std::ops::BitAnd::bitand`
-  --> $DIR/method_list_1.rs:38:5
+  --> $DIR/method_list_1.rs:36:5
    |
 LL | /     pub fn bitand(self, rhs: T) -> T {
 LL | |         unimplemented!()
@@ -40,7 +40,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::BitAnd` or choosing a less ambiguous method name
 
 error: method `bitor` can be confused for the standard trait method `std::ops::BitOr::bitor`
-  --> $DIR/method_list_1.rs:42:5
+  --> $DIR/method_list_1.rs:40:5
    |
 LL | /     pub fn bitor(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -50,7 +50,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::BitOr` or choosing a less ambiguous method name
 
 error: method `bitxor` can be confused for the standard trait method `std::ops::BitXor::bitxor`
-  --> $DIR/method_list_1.rs:46:5
+  --> $DIR/method_list_1.rs:44:5
    |
 LL | /     pub fn bitxor(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -60,7 +60,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::BitXor` or choosing a less ambiguous method name
 
 error: method `borrow` can be confused for the standard trait method `std::borrow::Borrow::borrow`
-  --> $DIR/method_list_1.rs:50:5
+  --> $DIR/method_list_1.rs:48:5
    |
 LL | /     pub fn borrow(&self) -> &str {
 LL | |         unimplemented!()
@@ -70,7 +70,7 @@ LL | |     }
    = help: consider implementing the trait `std::borrow::Borrow` or choosing a less ambiguous method name
 
 error: method `borrow_mut` can be confused for the standard trait method `std::borrow::BorrowMut::borrow_mut`
-  --> $DIR/method_list_1.rs:54:5
+  --> $DIR/method_list_1.rs:52:5
    |
 LL | /     pub fn borrow_mut(&mut self) -> &mut str {
 LL | |         unimplemented!()
@@ -80,7 +80,7 @@ LL | |     }
    = help: consider implementing the trait `std::borrow::BorrowMut` or choosing a less ambiguous method name
 
 error: method `clone` can be confused for the standard trait method `std::clone::Clone::clone`
-  --> $DIR/method_list_1.rs:58:5
+  --> $DIR/method_list_1.rs:56:5
    |
 LL | /     pub fn clone(&self) -> Self {
 LL | |         unimplemented!()
@@ -90,7 +90,7 @@ LL | |     }
    = help: consider implementing the trait `std::clone::Clone` or choosing a less ambiguous method name
 
 error: method `cmp` can be confused for the standard trait method `std::cmp::Ord::cmp`
-  --> $DIR/method_list_1.rs:62:5
+  --> $DIR/method_list_1.rs:60:5
    |
 LL | /     pub fn cmp(&self, other: &Self) -> Self {
 LL | |         unimplemented!()
@@ -100,7 +100,7 @@ LL | |     }
    = help: consider implementing the trait `std::cmp::Ord` or choosing a less ambiguous method name
 
 error: method `deref` can be confused for the standard trait method `std::ops::Deref::deref`
-  --> $DIR/method_list_1.rs:70:5
+  --> $DIR/method_list_1.rs:68:5
    |
 LL | /     pub fn deref(&self) -> &Self {
 LL | |         unimplemented!()
@@ -110,7 +110,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Deref` or choosing a less ambiguous method name
 
 error: method `deref_mut` can be confused for the standard trait method `std::ops::DerefMut::deref_mut`
-  --> $DIR/method_list_1.rs:74:5
+  --> $DIR/method_list_1.rs:72:5
    |
 LL | /     pub fn deref_mut(&mut self) -> &mut Self {
 LL | |         unimplemented!()
@@ -120,7 +120,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::DerefMut` or choosing a less ambiguous method name
 
 error: method `div` can be confused for the standard trait method `std::ops::Div::div`
-  --> $DIR/method_list_1.rs:78:5
+  --> $DIR/method_list_1.rs:76:5
    |
 LL | /     pub fn div(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -130,7 +130,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Div` or choosing a less ambiguous method name
 
 error: method `drop` can be confused for the standard trait method `std::ops::Drop::drop`
-  --> $DIR/method_list_1.rs:82:5
+  --> $DIR/method_list_1.rs:80:5
    |
 LL | /     pub fn drop(&mut self) {
 LL | |         unimplemented!()
index 2cdc1a06fe689dab34e495eee9466253e7836c8d..b663568806d218dd9e8ac3bb6d2206acad140550 100644 (file)
@@ -1,5 +1,3 @@
-// edition:2018
-
 #![warn(clippy::all, clippy::pedantic)]
 #![allow(
     clippy::missing_errors_doc,
index 0142e2991081c79ae4099788ea6c85ed02535428..426fe3b1adc9de12e9ba88e9f51a034407d6d007 100644 (file)
@@ -1,5 +1,5 @@
 error: method `eq` can be confused for the standard trait method `std::cmp::PartialEq::eq`
-  --> $DIR/method_list_2.rs:27:5
+  --> $DIR/method_list_2.rs:25:5
    |
 LL | /     pub fn eq(&self, other: &Self) -> bool {
 LL | |         unimplemented!()
@@ -10,7 +10,7 @@ LL | |     }
    = help: consider implementing the trait `std::cmp::PartialEq` or choosing a less ambiguous method name
 
 error: method `from_iter` can be confused for the standard trait method `std::iter::FromIterator::from_iter`
-  --> $DIR/method_list_2.rs:31:5
+  --> $DIR/method_list_2.rs:29:5
    |
 LL | /     pub fn from_iter<T>(iter: T) -> Self {
 LL | |         unimplemented!()
@@ -20,7 +20,7 @@ LL | |     }
    = help: consider implementing the trait `std::iter::FromIterator` or choosing a less ambiguous method name
 
 error: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
-  --> $DIR/method_list_2.rs:35:5
+  --> $DIR/method_list_2.rs:33:5
    |
 LL | /     pub fn from_str(s: &str) -> Result<Self, Self> {
 LL | |         unimplemented!()
@@ -30,7 +30,7 @@ LL | |     }
    = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
 
 error: method `hash` can be confused for the standard trait method `std::hash::Hash::hash`
-  --> $DIR/method_list_2.rs:39:5
+  --> $DIR/method_list_2.rs:37:5
    |
 LL | /     pub fn hash(&self, state: &mut T) {
 LL | |         unimplemented!()
@@ -40,7 +40,7 @@ LL | |     }
    = help: consider implementing the trait `std::hash::Hash` or choosing a less ambiguous method name
 
 error: method `index` can be confused for the standard trait method `std::ops::Index::index`
-  --> $DIR/method_list_2.rs:43:5
+  --> $DIR/method_list_2.rs:41:5
    |
 LL | /     pub fn index(&self, index: usize) -> &Self {
 LL | |         unimplemented!()
@@ -50,7 +50,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Index` or choosing a less ambiguous method name
 
 error: method `index_mut` can be confused for the standard trait method `std::ops::IndexMut::index_mut`
-  --> $DIR/method_list_2.rs:47:5
+  --> $DIR/method_list_2.rs:45:5
    |
 LL | /     pub fn index_mut(&mut self, index: usize) -> &mut Self {
 LL | |         unimplemented!()
@@ -60,7 +60,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::IndexMut` or choosing a less ambiguous method name
 
 error: method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter`
-  --> $DIR/method_list_2.rs:51:5
+  --> $DIR/method_list_2.rs:49:5
    |
 LL | /     pub fn into_iter(self) -> Self {
 LL | |         unimplemented!()
@@ -70,7 +70,7 @@ LL | |     }
    = help: consider implementing the trait `std::iter::IntoIterator` or choosing a less ambiguous method name
 
 error: method `mul` can be confused for the standard trait method `std::ops::Mul::mul`
-  --> $DIR/method_list_2.rs:55:5
+  --> $DIR/method_list_2.rs:53:5
    |
 LL | /     pub fn mul(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -80,7 +80,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Mul` or choosing a less ambiguous method name
 
 error: method `neg` can be confused for the standard trait method `std::ops::Neg::neg`
-  --> $DIR/method_list_2.rs:59:5
+  --> $DIR/method_list_2.rs:57:5
    |
 LL | /     pub fn neg(self) -> Self {
 LL | |         unimplemented!()
@@ -90,7 +90,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Neg` or choosing a less ambiguous method name
 
 error: method `next` can be confused for the standard trait method `std::iter::Iterator::next`
-  --> $DIR/method_list_2.rs:63:5
+  --> $DIR/method_list_2.rs:61:5
    |
 LL | /     pub fn next(&mut self) -> Option<Self> {
 LL | |         unimplemented!()
@@ -100,7 +100,7 @@ LL | |     }
    = help: consider implementing the trait `std::iter::Iterator` or choosing a less ambiguous method name
 
 error: method `not` can be confused for the standard trait method `std::ops::Not::not`
-  --> $DIR/method_list_2.rs:67:5
+  --> $DIR/method_list_2.rs:65:5
    |
 LL | /     pub fn not(self) -> Self {
 LL | |         unimplemented!()
@@ -110,7 +110,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Not` or choosing a less ambiguous method name
 
 error: method `rem` can be confused for the standard trait method `std::ops::Rem::rem`
-  --> $DIR/method_list_2.rs:71:5
+  --> $DIR/method_list_2.rs:69:5
    |
 LL | /     pub fn rem(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -120,7 +120,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Rem` or choosing a less ambiguous method name
 
 error: method `shl` can be confused for the standard trait method `std::ops::Shl::shl`
-  --> $DIR/method_list_2.rs:75:5
+  --> $DIR/method_list_2.rs:73:5
    |
 LL | /     pub fn shl(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -130,7 +130,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Shl` or choosing a less ambiguous method name
 
 error: method `shr` can be confused for the standard trait method `std::ops::Shr::shr`
-  --> $DIR/method_list_2.rs:79:5
+  --> $DIR/method_list_2.rs:77:5
    |
 LL | /     pub fn shr(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -140,7 +140,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Shr` or choosing a less ambiguous method name
 
 error: method `sub` can be confused for the standard trait method `std::ops::Sub::sub`
-  --> $DIR/method_list_2.rs:83:5
+  --> $DIR/method_list_2.rs:81:5
    |
 LL | /     pub fn sub(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
index f66b445b7b6a35249600338185df6d6bb7774bb6..4c40739d6f553874865157ad7c9cb06a1051ea0a 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 #![warn(clippy::single_component_path_imports)]
 #![allow(unused_imports)]
 
index 09d4865859584ed792063e9e6bb510a1b679c012..9280bab3c71b5cae19b6d4f7e57b47bb7a5a478f 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 #![warn(clippy::single_component_path_imports)]
 #![allow(unused_imports)]
 
index 7005fa8f125d36255c12bf6c8b93cf6644f64eba..509c88ac256a8c0dc99ecdbcac0a8dd6fe97529f 100644 (file)
@@ -1,5 +1,5 @@
 error: this import is redundant
-  --> $DIR/single_component_path_imports.rs:24:5
+  --> $DIR/single_component_path_imports.rs:23:5
    |
 LL |     use regex;
    |     ^^^^^^^^^^ help: remove it entirely
@@ -7,7 +7,7 @@ LL |     use regex;
    = note: `-D clippy::single-component-path-imports` implied by `-D warnings`
 
 error: this import is redundant
-  --> $DIR/single_component_path_imports.rs:6:1
+  --> $DIR/single_component_path_imports.rs:5:1
    |
 LL | use regex;
    | ^^^^^^^^^^ help: remove it entirely
index 05863f9a2bf488c06722209622ceae63cce12de7..e43f5d381aaa1087a928a49d86529693a74fdba9 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 #![warn(clippy::single_component_path_imports)]
 #![allow(unused_imports)]
 
index 633deea348b81d415778fc372cae9a720c5c5ffc..3c65ca3054c6919eb859317608a43151ea71eb5c 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 #![warn(clippy::single_component_path_imports)]
 #![allow(unused_imports)]
 
index 239efb393b1ab4ac058a959ebe323044cad662f1..37d5176129ff30a2d06733b35c2b2c9b5404574f 100644 (file)
@@ -1,5 +1,5 @@
 error: this import is redundant
-  --> $DIR/single_component_path_imports_macro.rs:16:1
+  --> $DIR/single_component_path_imports_macro.rs:15:1
    |
 LL | use m2; // fail
    | ^^^^^^^ help: remove it entirely
index 94117061b270da718a68172b91b920c1c18c434b..c75beb747861882c0a158a46a92b67ca5af5af6e 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::single_component_path_imports)]
 #![allow(unused_imports)]
 
index 0c3256c1ce43a71ea37159b4a65991603e493a59..cf990be1b9ff1cea7a0efe5c9509652b1a1ec271 100644 (file)
@@ -1,5 +1,5 @@
 error: this import is redundant
-  --> $DIR/single_component_path_imports_nested_first.rs:14:10
+  --> $DIR/single_component_path_imports_nested_first.rs:13:10
    |
 LL |     use {regex, serde};
    |          ^^^^^
@@ -8,7 +8,7 @@ LL |     use {regex, serde};
    = help: remove this import
 
 error: this import is redundant
-  --> $DIR/single_component_path_imports_nested_first.rs:14:17
+  --> $DIR/single_component_path_imports_nested_first.rs:13:17
    |
 LL |     use {regex, serde};
    |                 ^^^^^
@@ -16,7 +16,7 @@ LL |     use {regex, serde};
    = help: remove this import
 
 error: this import is redundant
-  --> $DIR/single_component_path_imports_nested_first.rs:5:1
+  --> $DIR/single_component_path_imports_nested_first.rs:4:1
    |
 LL | use regex;
    | ^^^^^^^^^^ help: remove it entirely
index 94319ade0ac4b9672ad2064bab6844db2e634887..48e8e530261bea39d8b1586d2f60cde8233ee65a 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::single_component_path_imports)]
 #![allow(unused_imports)]
 
index c7437b234566a95f08dd4794f7cecc2af1430adf..4fb0cf40b6e00d40bb2c0345a28457af33695442 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::single_component_path_imports)]
 #![allow(unused_imports)]
 
diff --git a/src/tools/clippy/tests/ui/string_slice.rs b/src/tools/clippy/tests/ui/string_slice.rs
new file mode 100644 (file)
index 0000000..be4dfc8
--- /dev/null
@@ -0,0 +1,10 @@
+#[warn(clippy::string_slice)]
+#[allow(clippy::no_effect)]
+
+fn main() {
+    &"Ölkanne"[1..];
+    let m = "Mötörhead";
+    &m[2..5];
+    let s = String::from(m);
+    &s[0..2];
+}
diff --git a/src/tools/clippy/tests/ui/string_slice.stderr b/src/tools/clippy/tests/ui/string_slice.stderr
new file mode 100644 (file)
index 0000000..55040bf
--- /dev/null
@@ -0,0 +1,22 @@
+error: indexing into a string may panic if the index is within a UTF-8 character
+  --> $DIR/string_slice.rs:5:6
+   |
+LL |     &"Ölkanne"[1..];
+   |      ^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::string-slice` implied by `-D warnings`
+
+error: indexing into a string may panic if the index is within a UTF-8 character
+  --> $DIR/string_slice.rs:7:6
+   |
+LL |     &m[2..5];
+   |      ^^^^^^^
+
+error: indexing into a string may panic if the index is within a UTF-8 character
+  --> $DIR/string_slice.rs:9:6
+   |
+LL |     &s[0..2];
+   |      ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unit_hash.rs b/src/tools/clippy/tests/ui/unit_hash.rs
new file mode 100644 (file)
index 0000000..989916c
--- /dev/null
@@ -0,0 +1,27 @@
+#![warn(clippy::unit_hash)]
+
+use std::collections::hash_map::DefaultHasher;
+use std::hash::Hash;
+
+enum Foo {
+    Empty,
+    WithValue(u8),
+}
+
+fn do_nothing() {}
+
+fn main() {
+    let mut state = DefaultHasher::new();
+    let my_enum = Foo::Empty;
+
+    match my_enum {
+        Foo::Empty => ().hash(&mut state),
+        Foo::WithValue(x) => x.hash(&mut state),
+    }
+
+    let res = ();
+    res.hash(&mut state);
+
+    #[allow(clippy::unit_arg)]
+    do_nothing().hash(&mut state);
+}
diff --git a/src/tools/clippy/tests/ui/unit_hash.stderr b/src/tools/clippy/tests/ui/unit_hash.stderr
new file mode 100644 (file)
index 0000000..da27629
--- /dev/null
@@ -0,0 +1,27 @@
+error: this call to `hash` on the unit type will do nothing
+  --> $DIR/unit_hash.rs:18:23
+   |
+LL |         Foo::Empty => ().hash(&mut state),
+   |                       ^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
+   |
+   = note: `-D clippy::unit-hash` implied by `-D warnings`
+   = note: the implementation of `Hash` for `()` is a no-op
+
+error: this call to `hash` on the unit type will do nothing
+  --> $DIR/unit_hash.rs:23:5
+   |
+LL |     res.hash(&mut state);
+   |     ^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
+   |
+   = note: the implementation of `Hash` for `()` is a no-op
+
+error: this call to `hash` on the unit type will do nothing
+  --> $DIR/unit_hash.rs:26:5
+   |
+LL |     do_nothing().hash(&mut state);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
+   |
+   = note: the implementation of `Hash` for `()` is a no-op
+
+error: aborting due to 3 previous errors
+
index 4f4203f5fdbf67fd59049f85769d322ae2ff73ba..2a3a506a57b1437310918767ad1fa55ab0987052 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::unused_async)]
 
 async fn foo() -> i32 {
index 8b834d205b176970c8911b5f371c1282de83feb1..cc6096d65d9f351a016e0fcd7423ac12405ba587 100644 (file)
@@ -1,5 +1,5 @@
 error: unused `async` for function with no await statements
-  --> $DIR/unused_async.rs:4:1
+  --> $DIR/unused_async.rs:3:1
    |
 LL | / async fn foo() -> i32 {
 LL | |     4
index dcf818f80763052c6d4fae4d6e282b0b67c438c2..4e33e343ce0e9c414b42abf6d5e73d6b488392c6 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 // aux-build:proc_macro_derive.rs
 
 #![warn(clippy::use_self)]
index 9da6fef7a380c792781aceadb6ffbb2258395995..7b621ff9bcabf5be14250e8740311b04516047b8 100644 (file)
@@ -1,5 +1,4 @@
 // run-rustfix
-// edition:2018
 // aux-build:proc_macro_derive.rs
 
 #![warn(clippy::use_self)]
index e14368a11aa746eddd1fffeeb88c3bc36c35982d..ecb78b3f9721b0b575a4a153e08e9833f63917b5 100644 (file)
@@ -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,163 +7,163 @@ 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`
index d8bda7e8f48a7eb32cc22fc54c4cb5d24d1ffea8..21d66d5df79ecfa0a8b1727424d38ffb1134081f 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 // aux-build:proc_macro_derive.rs
 
 #![feature(rustc_private)]
index 2cbfc5ca2e2705e0bb618bfad420339277493f22..790b849210c9b35875ff2c9b8c4d47f4c54017cd 100644 (file)
@@ -1,5 +1,5 @@
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:26:5
+  --> $DIR/used_underscore_binding.rs:25:5
    |
 LL |     _foo + 1
    |     ^^^^
@@ -7,31 +7,31 @@ LL |     _foo + 1
    = note: `-D clippy::used-underscore-binding` implied by `-D warnings`
 
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:31:20
+  --> $DIR/used_underscore_binding.rs:30:20
    |
 LL |     println!("{}", _foo);
    |                    ^^^^
 
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:32:16
+  --> $DIR/used_underscore_binding.rs:31:16
    |
 LL |     assert_eq!(_foo, _foo);
    |                ^^^^
 
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:32:22
+  --> $DIR/used_underscore_binding.rs:31:22
    |
 LL |     assert_eq!(_foo, _foo);
    |                      ^^^^
 
 error: used binding `_underscore_field` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:45:5
+  --> $DIR/used_underscore_binding.rs:44:5
    |
 LL |     s._underscore_field += 1;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: used binding `_i` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:100:16
+  --> $DIR/used_underscore_binding.rs:99:16
    |
 LL |         uses_i(_i);
    |                ^^
index 98bc1e80731ff3934643d2c565f70ad241ddd7f1..8402c33a4cd5fb695d37116caf003763dcf186bd 100644 (file)
@@ -1,8 +1,13 @@
+// edition:2015
 // run-rustfix
 // aux-build:wildcard_imports_helper.rs
 
+// the 2015 edition here is needed because edition 2018 changed the module system
+// (see https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html) which means the lint
+// no longer detects some of the cases starting with Rust 2018.
+// FIXME: We should likely add another edition 2021 test case for this lint
+
 #![warn(clippy::wildcard_imports)]
-//#![allow(clippy::redundant_pub_crate)]
 #![allow(unused)]
 #![allow(clippy::unnecessary_wraps)]
 #![warn(unused_imports)]
index 4ef61f9245b58f9420daded6c79a1d84e201edb9..faaeaade9b02bff03b30793a73638ba5a3a560eb 100644 (file)
@@ -1,8 +1,13 @@
+// edition:2015
 // run-rustfix
 // aux-build:wildcard_imports_helper.rs
 
+// the 2015 edition here is needed because edition 2018 changed the module system
+// (see https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html) which means the lint
+// no longer detects some of the cases starting with Rust 2018.
+// FIXME: We should likely add another edition 2021 test case for this lint
+
 #![warn(clippy::wildcard_imports)]
-//#![allow(clippy::redundant_pub_crate)]
 #![allow(unused)]
 #![allow(clippy::unnecessary_wraps)]
 #![warn(unused_imports)]
index d7af0c046e88694f34a1ff399931fe346cc8904c..7534a65ec9bd56c0878846b81663d05ef269cb92 100644 (file)
@@ -1,5 +1,5 @@
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:12:5
+  --> $DIR/wildcard_imports.rs:17:5
    |
 LL | use crate::fn_mod::*;
    |     ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
@@ -7,85 +7,85 @@ LL | use crate::fn_mod::*;
    = note: `-D clippy::wildcard-imports` implied by `-D warnings`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:13:5
+  --> $DIR/wildcard_imports.rs:18:5
    |
 LL | use crate::mod_mod::*;
    |     ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:14:5
+  --> $DIR/wildcard_imports.rs:19:5
    |
 LL | use crate::multi_fn_mod::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:16:5
+  --> $DIR/wildcard_imports.rs:21:5
    |
 LL | use crate::struct_mod::*;
    |     ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:20:5
+  --> $DIR/wildcard_imports.rs:25:5
    |
 LL | use wildcard_imports_helper::inner::inner_for_self_import::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:21:5
+  --> $DIR/wildcard_imports.rs:26:5
    |
 LL | use wildcard_imports_helper::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:92:13
+  --> $DIR/wildcard_imports.rs:97:13
    |
 LL |         use crate::fn_mod::*;
    |             ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:98:75
+  --> $DIR/wildcard_imports.rs:103:75
    |
 LL |         use wildcard_imports_helper::inner::inner_for_self_import::{self, *};
    |                                                                           ^ help: try: `inner_extern_foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:99:13
+  --> $DIR/wildcard_imports.rs:104:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:110:20
+  --> $DIR/wildcard_imports.rs:115:20
    |
 LL |         use self::{inner::*, inner2::*};
    |                    ^^^^^^^^ help: try: `inner::inner_foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:110:30
+  --> $DIR/wildcard_imports.rs:115:30
    |
 LL |         use self::{inner::*, inner2::*};
    |                              ^^^^^^^^^ help: try: `inner2::inner_bar`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:117:13
+  --> $DIR/wildcard_imports.rs:122:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:146:9
+  --> $DIR/wildcard_imports.rs:151:9
    |
 LL |     use crate::in_fn_test::*;
    |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:155:9
+  --> $DIR/wildcard_imports.rs:160:9
    |
 LL |     use crate:: in_fn_test::  * ;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:156:9
+  --> $DIR/wildcard_imports.rs:161:9
    |
 LL |       use crate:: fn_mod::
    |  _________^
@@ -93,37 +93,37 @@ LL | |         *;
    | |_________^ help: try: `crate:: fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:167:13
+  --> $DIR/wildcard_imports.rs:172:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:202:17
+  --> $DIR/wildcard_imports.rs:207:17
    |
 LL |             use super::*;
    |                 ^^^^^^^^ help: try: `super::insidefoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:210:13
+  --> $DIR/wildcard_imports.rs:215:13
    |
 LL |         use super_imports::*;
    |             ^^^^^^^^^^^^^^^^ help: try: `super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:219:17
+  --> $DIR/wildcard_imports.rs:224:17
    |
 LL |             use super::super::*;
    |                 ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:228:13
+  --> $DIR/wildcard_imports.rs:233:13
    |
 LL |         use super::super::super_imports::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:236:13
+  --> $DIR/wildcard_imports.rs:241:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
index 151dd0c27d57dbab4f7b4e98f485eb3993e10b3b..1b9da8a55e53fe8796ff7b92ee9b393db29b25bd 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::wrong_self_convention)]
 #![allow(dead_code)]
 
index ce23317abf651f59f66ca971aeb15e1520355cfa..590ee6d9c529d6493b8e29b755c2d3e07f982b2b 100644 (file)
@@ -1,5 +1,5 @@
 error: methods called `from_*` usually take no `self`
-  --> $DIR/wrong_self_convention.rs:17:17
+  --> $DIR/wrong_self_convention.rs:16:17
    |
 LL |     fn from_i32(self) {}
    |                 ^^^^
@@ -8,7 +8,7 @@ LL |     fn from_i32(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `from_*` usually take no `self`
-  --> $DIR/wrong_self_convention.rs:23:21
+  --> $DIR/wrong_self_convention.rs:22:21
    |
 LL |     pub fn from_i64(self) {}
    |                     ^^^^
@@ -16,7 +16,7 @@ LL |     pub fn from_i64(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
-  --> $DIR/wrong_self_convention.rs:35:15
+  --> $DIR/wrong_self_convention.rs:34:15
    |
 LL |     fn as_i32(self) {}
    |               ^^^^
@@ -24,7 +24,7 @@ LL |     fn as_i32(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `into_*` usually take `self` by value
-  --> $DIR/wrong_self_convention.rs:37:17
+  --> $DIR/wrong_self_convention.rs:36:17
    |
 LL |     fn into_i32(&self) {}
    |                 ^^^^^
@@ -32,7 +32,7 @@ LL |     fn into_i32(&self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `is_*` usually take `self` by reference or no `self`
-  --> $DIR/wrong_self_convention.rs:39:15
+  --> $DIR/wrong_self_convention.rs:38:15
    |
 LL |     fn is_i32(self) {}
    |               ^^^^
@@ -40,7 +40,7 @@ LL |     fn is_i32(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference
-  --> $DIR/wrong_self_convention.rs:41:15
+  --> $DIR/wrong_self_convention.rs:40:15
    |
 LL |     fn to_i32(self) {}
    |               ^^^^
@@ -48,7 +48,7 @@ LL |     fn to_i32(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `from_*` usually take no `self`
-  --> $DIR/wrong_self_convention.rs:43:17
+  --> $DIR/wrong_self_convention.rs:42:17
    |
 LL |     fn from_i32(self) {}
    |                 ^^^^
@@ -56,7 +56,7 @@ LL |     fn from_i32(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
-  --> $DIR/wrong_self_convention.rs:45:19
+  --> $DIR/wrong_self_convention.rs:44:19
    |
 LL |     pub fn as_i64(self) {}
    |                   ^^^^
@@ -64,7 +64,7 @@ LL |     pub fn as_i64(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `into_*` usually take `self` by value
-  --> $DIR/wrong_self_convention.rs:46:21
+  --> $DIR/wrong_self_convention.rs:45:21
    |
 LL |     pub fn into_i64(&self) {}
    |                     ^^^^^
@@ -72,7 +72,7 @@ LL |     pub fn into_i64(&self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `is_*` usually take `self` by reference or no `self`
-  --> $DIR/wrong_self_convention.rs:47:19
+  --> $DIR/wrong_self_convention.rs:46:19
    |
 LL |     pub fn is_i64(self) {}
    |                   ^^^^
@@ -80,7 +80,7 @@ LL |     pub fn is_i64(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference
-  --> $DIR/wrong_self_convention.rs:48:19
+  --> $DIR/wrong_self_convention.rs:47:19
    |
 LL |     pub fn to_i64(self) {}
    |                   ^^^^
@@ -88,7 +88,7 @@ LL |     pub fn to_i64(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `from_*` usually take no `self`
-  --> $DIR/wrong_self_convention.rs:49:21
+  --> $DIR/wrong_self_convention.rs:48:21
    |
 LL |     pub fn from_i64(self) {}
    |                     ^^^^
@@ -96,7 +96,7 @@ LL |     pub fn from_i64(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
-  --> $DIR/wrong_self_convention.rs:94:19
+  --> $DIR/wrong_self_convention.rs:93:19
    |
 LL |         fn as_i32(self) {}
    |                   ^^^^
@@ -104,7 +104,7 @@ LL |         fn as_i32(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `into_*` usually take `self` by value
-  --> $DIR/wrong_self_convention.rs:97:25
+  --> $DIR/wrong_self_convention.rs:96:25
    |
 LL |         fn into_i32_ref(&self) {}
    |                         ^^^^^
@@ -112,7 +112,7 @@ LL |         fn into_i32_ref(&self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `is_*` usually take `self` by reference or no `self`
-  --> $DIR/wrong_self_convention.rs:99:19
+  --> $DIR/wrong_self_convention.rs:98:19
    |
 LL |         fn is_i32(self) {}
    |                   ^^^^
@@ -120,7 +120,7 @@ LL |         fn is_i32(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `from_*` usually take no `self`
-  --> $DIR/wrong_self_convention.rs:103:21
+  --> $DIR/wrong_self_convention.rs:102:21
    |
 LL |         fn from_i32(self) {}
    |                     ^^^^
@@ -128,7 +128,7 @@ LL |         fn from_i32(self) {}
    = help: consider choosing a less ambiguous name
 
 error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
-  --> $DIR/wrong_self_convention.rs:118:19
+  --> $DIR/wrong_self_convention.rs:117:19
    |
 LL |         fn as_i32(self);
    |                   ^^^^
@@ -136,7 +136,7 @@ LL |         fn as_i32(self);
    = help: consider choosing a less ambiguous name
 
 error: methods called `into_*` usually take `self` by value
-  --> $DIR/wrong_self_convention.rs:121:25
+  --> $DIR/wrong_self_convention.rs:120:25
    |
 LL |         fn into_i32_ref(&self);
    |                         ^^^^^
@@ -144,7 +144,7 @@ LL |         fn into_i32_ref(&self);
    = help: consider choosing a less ambiguous name
 
 error: methods called `is_*` usually take `self` by reference or no `self`
-  --> $DIR/wrong_self_convention.rs:123:19
+  --> $DIR/wrong_self_convention.rs:122:19
    |
 LL |         fn is_i32(self);
    |                   ^^^^
@@ -152,7 +152,7 @@ LL |         fn is_i32(self);
    = help: consider choosing a less ambiguous name
 
 error: methods called `from_*` usually take no `self`
-  --> $DIR/wrong_self_convention.rs:127:21
+  --> $DIR/wrong_self_convention.rs:126:21
    |
 LL |         fn from_i32(self);
    |                     ^^^^
@@ -160,7 +160,7 @@ LL |         fn from_i32(self);
    = help: consider choosing a less ambiguous name
 
 error: methods called `into_*` usually take `self` by value
-  --> $DIR/wrong_self_convention.rs:145:25
+  --> $DIR/wrong_self_convention.rs:144:25
    |
 LL |         fn into_i32_ref(&self);
    |                         ^^^^^
@@ -168,7 +168,7 @@ LL |         fn into_i32_ref(&self);
    = help: consider choosing a less ambiguous name
 
 error: methods called `from_*` usually take no `self`
-  --> $DIR/wrong_self_convention.rs:151:21
+  --> $DIR/wrong_self_convention.rs:150:21
    |
 LL |         fn from_i32(self);
    |                     ^^^^
@@ -176,7 +176,7 @@ LL |         fn from_i32(self);
    = help: consider choosing a less ambiguous name
 
 error: methods with the following characteristics: (`to_*` and `self` type is `Copy`) usually take `self` by value
-  --> $DIR/wrong_self_convention.rs:175:22
+  --> $DIR/wrong_self_convention.rs:174:22
    |
 LL |         fn to_u64_v2(&self) -> u64 {
    |                      ^^^^^
@@ -184,7 +184,7 @@ LL |         fn to_u64_v2(&self) -> u64 {
    = help: consider choosing a less ambiguous name
 
 error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference
-  --> $DIR/wrong_self_convention.rs:184:19
+  --> $DIR/wrong_self_convention.rs:183:19
    |
 LL |         fn to_u64(self) -> u64 {
    |                   ^^^^
index 0d827c1feb3e722c4842684a441f6386ee2f2eb5..a8fe8331133778ebcf934b4b234c07c430f484c9 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::wrong_self_convention)]
 #![allow(dead_code)]
 
index 0e0d066d656b56a174ff00a9190927ca16abbf70..5bdc47f91f65b42b1376b18a7a661926c6d3805b 100644 (file)
@@ -1,5 +1,5 @@
 error: methods called `from_*` usually take no `self`
-  --> $DIR/wrong_self_convention2.rs:55:29
+  --> $DIR/wrong_self_convention2.rs:54:29
    |
 LL |         pub fn from_be_self(self) -> Self {
    |                             ^^^^
@@ -8,7 +8,7 @@ LL |         pub fn from_be_self(self) -> Self {
    = help: consider choosing a less ambiguous name
 
 error: methods called `from_*` usually take no `self`
-  --> $DIR/wrong_self_convention2.rs:64:25
+  --> $DIR/wrong_self_convention2.rs:63:25
    |
 LL |         fn from_be_self(self) -> Self;
    |                         ^^^^
index 486a0d772358531ca75e14eea62e41547ad294dd..5bb2116bd339af9ef01ddc281abb2d70416a5610 100644 (file)
@@ -1,4 +1,3 @@
-// edition:2018
 #![warn(clippy::wrong_self_convention)]
 #![allow(dead_code)]
 
index 6ce37c5949111bf20d20b66ffc00ad6170029a69..8665d8dc9a9dea4f7b1ed03b3b5a26084fdf11d3 100644 (file)
@@ -1,5 +1,5 @@
 error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference
-  --> $DIR/wrong_self_conventions_mut.rs:15:24
+  --> $DIR/wrong_self_conventions_mut.rs:14:24
    |
 LL |         pub fn to_many(&mut self) -> Option<&mut [T]> {
    |                        ^^^^^^^^^
@@ -8,7 +8,7 @@ LL |         pub fn to_many(&mut self) -> Option<&mut [T]> {
    = help: consider choosing a less ambiguous name
 
 error: methods with the following characteristics: (`to_*` and `*_mut`) usually take `self` by mutable reference
-  --> $DIR/wrong_self_conventions_mut.rs:23:28
+  --> $DIR/wrong_self_conventions_mut.rs:22:28
    |
 LL |         pub fn to_many_mut(&self) -> Option<&[T]> {
    |                            ^^^^^
index 98d1ee19f69a1ca8bdfb88a533d2d6c41eb5a34b..5fcaa452ca30e6eaf9278d3e0647fc98de15e09d 100644 (file)
@@ -242,9 +242,6 @@ fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
                 if let Some(edition) = config.parse_edition(ln) {
                     self.compile_flags.push(format!("--edition={}", edition));
                     has_edition = true;
-                    if edition == "2021" {
-                        self.compile_flags.push("-Zunstable-options".to_string());
-                    }
                 }
 
                 config.parse_and_update_revisions(ln, &mut self.revisions);
index 2485dbadab5bfdbb5bb6cb55f4ec336a90f98778..157b42e2d17f5a52f3bfdb8870178c7a0f28c7ba 100644 (file)
@@ -168,7 +168,7 @@ fn only_target() {
     let mut config = config();
     config.target = "x86_64-pc-windows-gnu".to_owned();
 
-    assert!(check_ignore(&config, "// only-i686"));
+    assert!(check_ignore(&config, "// only-x86"));
     assert!(check_ignore(&config, "// only-linux"));
     assert!(check_ignore(&config, "// only-msvc"));
     assert!(check_ignore(&config, "// only-32bit"));
index 4470272a9f86672adcf1fbf168723040f89bd8e8..3c85b9076dd1af977591fc0fcbdcd6d54a3fbf01 100644 (file)
@@ -1607,9 +1607,6 @@ fn build_all_auxiliary(&self, rustc: &mut Command) -> PathBuf {
                 get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), is_dylib);
             rustc.arg("--extern").arg(format!("{}={}/{}", aux_name, aux_dir.display(), lib_name));
         }
-        if !self.props.aux_crates.is_empty() {
-            rustc.arg("-Zunstable-options");
-        }
 
         aux_dir
     }
index d03c21dc5086fe499e14d94d00e366669467955a..6ca145a58e92af169c4c2004dc5e524c2038a0a7 100644 (file)
 ];
 
 static ASM_SUPPORTED_ARCHS: &[&str] = &[
-    "x86", "x86_64", "arm", "aarch64", "riscv32", "riscv64", "nvptx64", "hexagon", "mips",
-    "mips64", "spirv", "wasm32",
+    "x86", "x86_64", "arm", "aarch64", "riscv32",
+    "riscv64",
+    // These targets require an additional asm_experimental_arch feature.
+    // "nvptx64", "hexagon", "mips", "mips64", "spirv", "wasm32",
 ];
 
 pub fn has_asm_support(triple: &str) -> bool {
index 1f47693e02809c97db61b51247ae4e4d46744c61..04f03a360ab8fef3d9c0ff84de2d39b8a196c717 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 1f47693e02809c97db61b51247ae4e4d46744c61
+Subproject commit 04f03a360ab8fef3d9c0ff84de2d39b8a196c717
index bb9cd00f3f5829196df0a2a93d12274d82702f8a..a673e425dfff9d41610b59ae14f014486f911018 100644 (file)
@@ -414,7 +414,7 @@ function parseOptions(args) {
         "test_folder": "",
         "test_file": "",
     };
-    var correspondances = {
+    var correspondences = {
         "--resource-suffix": "resource_suffix",
         "--doc-folder": "doc_folder",
         "--test-folder": "test_folder",
@@ -423,17 +423,13 @@ function parseOptions(args) {
     };
 
     for (var i = 0; i < args.length; ++i) {
-        if (args[i] === "--resource-suffix"
-            || args[i] === "--doc-folder"
-            || args[i] === "--test-folder"
-            || args[i] === "--test-file"
-            || args[i] === "--crate-name") {
+        if (correspondences.hasOwnProperty(args[i])) {
             i += 1;
             if (i >= args.length) {
                 console.log("Missing argument after `" + args[i - 1] + "` option.");
                 return null;
             }
-            opts[correspondances[args[i - 1]]] = args[i];
+            opts[correspondences[args[i - 1]]] = args[i];
         } else if (args[i] === "--help") {
             showHelp();
             process.exit(0);
diff --git a/src/tools/rustfmt/.github/workflows/rustdoc_check.yml b/src/tools/rustfmt/.github/workflows/rustdoc_check.yml
new file mode 100644 (file)
index 0000000..ca96d30
--- /dev/null
@@ -0,0 +1,25 @@
+name: rustdoc check
+on:
+  push:
+    branches:
+      - master
+  pull_request:
+
+jobs:
+  rustdoc_check:
+    runs-on: ubuntu-latest
+    name: rustdoc check
+    steps:
+    - name: checkout
+      uses: actions/checkout@v2
+
+    - name: install rustup
+      run: |
+        curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup-init.sh
+        sh rustup-init.sh -y --default-toolchain none
+        rustup target add x86_64-unknown-linux-gnu
+
+    - name: document rustfmt
+      env:
+        RUSTDOCFLAGS: --document-private-items --enable-index-page --show-type-layout --generate-link-to-definition -Zunstable-options -Dwarnings
+      run: cargo doc -Zskip-rustdoc-fingerprint --no-deps -p rustfmt-nightly -p rustfmt-config_proc_macro
index 7a77dbe154b60f2f55224cfeae2cb41f2127c53c..13826883d2f4bdf537df1df2a687be215adbaf97 100644 (file)
@@ -2062,7 +2062,7 @@ use sit;
 Controls the strategy for how imports are grouped together.
 
 - **Default value**: `Preserve`
-- **Possible values**: `Preserve`, `StdExternalCrate`
+- **Possible values**: `Preserve`, `StdExternalCrate`, `One`
 - **Stable**: No
 
 #### `Preserve` (default):
@@ -2108,6 +2108,23 @@ use super::update::convert_publish_payload;
 use crate::models::Event;
 ```
 
+#### `One`:
+
+Discard existing import groups, and create a single group for everything
+
+```rust
+use super::schema::{Context, Payload};
+use super::update::convert_publish_payload;
+use crate::models::Event;
+use alloc::alloc::Layout;
+use broker::database::PooledConnection;
+use chrono::Utc;
+use core::f32;
+use juniper::{FieldError, FieldResult};
+use std::sync::Arc;
+use uuid::Uuid;
+```
+
 ## `reorder_modules`
 
 Reorder `mod` declarations alphabetically in group.
index e6dc6a220376db13aaea6aa795410a1c37a851c7..3073996019ee26be58d1ec8aaa233545ee8803d9 100644 (file)
@@ -59,7 +59,7 @@ example, the `issue-1111.rs` test file is configured by the file
 ## Debugging
 
 Some `rewrite_*` methods use the `debug!` macro for printing useful information.
-These messages can be printed by using the environment variable `RUST_LOG=rustfmt=DEBUG`.
+These messages can be printed by using the environment variable `RUSTFMT_LOG=rustfmt=DEBUG`.
 These traces can be helpful in understanding which part of the code was used
 and get a better grasp on the execution flow.
 
index 9c7a1c4bc341bed77ce3ee362a8eea5d01ad7974..b3d21e6fb87c79ffa3957b20a4cc405f2787f051 100644 (file)
@@ -47,7 +47,7 @@ cargo +nightly fmt
 
 ## Limitations
 
-Rustfmt tries to work on as much Rust code as possible, sometimes, the code
+Rustfmt tries to work on as much Rust code as possible. Sometimes, the code
 doesn't even need to compile! As we approach a 1.0 release we are also looking
 to limit areas of instability; in particular, post-1.0, the formatting of most
 code should not change as Rustfmt improves. However, there are some things that
@@ -102,6 +102,25 @@ read data from stdin. Alternatively, you can use `cargo fmt` to format all
 binary and library targets of your crate.
 
 You can run `rustfmt --help` for information about available arguments.
+The easiest way to run rustfmt against a project is with `cargo fmt`. `cargo fmt` works on both
+single-crate projects and [cargo workspaces](https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html).
+Please see `cargo fmt --help` for usage information.
+
+You can specify the path to your own `rustfmt` binary for cargo to use by setting the`RUSTFMT` 
+environment variable. This was added in v1.4.22, so you must have this version or newer to leverage this feature (`cargo fmt --version`)
+
+### Running `rustfmt` directly
+
+To format individual files or arbitrary codes from stdin, the `rustfmt` binary should be used. Some
+examples follow:
+
+- `rustfmt lib.rs main.rs` will format "lib.rs" and "main.rs" in place
+- `rustfmt` will read a code from stdin and write formatting to stdout
+  - `echo "fn     main() {}" | rustfmt` would emit "fn main() {}".
+
+For more information, including arguments and emit options, see `rustfmt --help`.
+
+### Verifying code is formatted
 
 When running with `--check`, Rustfmt will exit with `0` if Rustfmt would not
 make any formatting changes to the input, and `1` if Rustfmt would make changes.
@@ -129,7 +148,7 @@ rustfmt to exit with an error code if the input is not formatted correctly.
 It will also print any found differences. (Older versions of Rustfmt don't
 support `--check`, use `--write-mode diff`).
 
-A minimal Travis setup could look like this (requires Rust 1.24.0 or greater):
+A minimal Travis setup could look like this (requires Rust 1.31.0 or greater):
 
 ```yaml
 language: rust
diff --git a/src/tools/rustfmt/appveyor.yml b/src/tools/rustfmt/appveyor.yml
deleted file mode 100644 (file)
index b3dda09..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-environment:
-  global:
-    PROJECT_NAME: rustfmt
-
-build: false
-
-test_script:
-  - echo Why does no one have access to delete me?
index 7aea6222b8bc5f7a8168857e36b7b501b225b267..6a711c0171aebb99078b65ccb5a70629e7338629 100644 (file)
@@ -3,19 +3,28 @@
 ## Installation
 
 - Install [CLion](https://www.jetbrains.com/clion/), [IntelliJ Ultimate or CE](https://www.jetbrains.com/idea/) through the direct download link or using the [JetBrains Toolbox](https://www.jetbrains.com/toolbox/).
-  CLion provides a built-in debugger interface but its not free like IntelliJ CE - which does not provide the debugger interface. (IntelliJ seems to lack the toolchain for that, see this discussion [intellij-rust/issues/535](https://github.com/intellij-rust/intellij-rust/issues/535))
-  
-- Install the [Rust Plugin](https://intellij-rust.github.io/) by navigating to File -> Settings -> Plugins and press "Install JetBrains Plugin"
-  ![plugins](https://user-images.githubusercontent.com/1133787/47240861-f40af680-d3e9-11e8-9b82-cdd5c8d5f5b8.png)
+  CLion and IntelliJ Ultimate [provide a built-in debugger interface](https://github.com/intellij-rust/intellij-rust#compatible-ides) but they are not free like IntelliJ CE.
+
+- Install the [Rust Plugin](https://intellij-rust.github.io/) by navigating to File → Settings → Plugins and searching the plugin in the Marketplace
+  ![plugins](https://user-images.githubusercontent.com/6505554/83944518-6f1e5c00-a81d-11ea-9c35-e16948811ba8.png)
 
-- Press "Install" on the rust plugin
-  ![install rust](https://user-images.githubusercontent.com/1133787/47240803-c0c86780-d3e9-11e8-9265-22f735e4d7ed.png)
+- Press "Install" on the Rust plugin
+  ![install rust](https://user-images.githubusercontent.com/6505554/83944533-82c9c280-a81d-11ea-86b3-ee2e31bc7d12.png)
   
 - Restart CLion/IntelliJ
 
 ## Configuration
 
-- Open the settings window (File -> Settings) and search for "reformat"
+### Run Rustfmt on save
+
+- Open Rustfmt settings (File → Settings → Languages & Frameworks → Rust → Rustfmt) and enable "Run rustfmt on Save"
+  ![run_rustfmt_on_save](https://user-images.githubusercontent.com/6505554/83944610-3468f380-a81e-11ea-9c34-0cbd18dd4969.png)
+
+- IntellJ uses autosave, so now your files will always be formatted according to rustfmt. Alternatively you can use Ctrl+S to reformat file manually
+
+### Bind shortcut to "Reformat File with Rustfmt" action
+
+- Open the settings window (File → Settings) and search for "reformat"
   ![keymap](https://user-images.githubusercontent.com/1133787/47240922-2ae10c80-d3ea-11e8-9d8f-c798d9749240.png)
 - Right-click on "Reformat File with Rustfmt" and assign a keyboard shortcut
 
diff --git a/src/tools/rustfmt/legacy-rustfmt.toml b/src/tools/rustfmt/legacy-rustfmt.toml
deleted file mode 100644 (file)
index f976fa6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-indent_style = "Visual"
-combine_control_expr = false
index b19ecbdb07c4f425540264a618144618e7acbcab..1d2cad6675117d567194ef4e77cb521abdac7946 100644 (file)
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-10-20"
+channel = "nightly-2021-11-08"
 components = ["rustc-dev"]
index a5982820e3ded6f2de868975ac9003ee441623f4..76b66e9da80980ea30f24aa585ac64caea4ef71c 100644 (file)
@@ -451,7 +451,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
                         if next.is_doc_comment() {
                             let snippet = context.snippet(missing_span);
                             let (_, mlb) = has_newlines_before_after_comment(snippet);
-                            result.push_str(&mlb);
+                            result.push_str(mlb);
                         }
                     }
                     result.push('\n');
@@ -484,7 +484,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
                     if next.is_doc_comment() {
                         let snippet = context.snippet(missing_span);
                         let (_, mlb) = has_newlines_before_after_comment(snippet);
-                        result.push_str(&mlb);
+                        result.push_str(mlb);
                     }
                 }
                 result.push('\n');
index c3dcb84c9488d53b001f5febb9c8803039f9a27c..f653a12a8afeb95fb22d3c42475c14ca8da3947e 100644 (file)
@@ -77,7 +77,7 @@ fn test_doc_comment_is_formatted_correctly(
     ) {
         assert_eq!(
             expected_comment,
-            format!("{}", DocCommentFormatter::new(&literal, style))
+            format!("{}", DocCommentFormatter::new(literal, style))
         );
     }
 }
index 1bcc5c0dada3bd0695d9fd5c8167890ab7eff255..9d2e97c9479fc2dda6c063467b4cbde52a934b4b 100644 (file)
@@ -20,7 +20,7 @@
 };
 
 fn main() {
-    env_logger::init();
+    env_logger::Builder::from_env("RUSTFMT_LOG").init();
     let opts = make_opts();
 
     let exit_code = match execute(&opts) {
index 1d423ac34919b421a31e4f77f4e63030746082a6..759b21218c353e70787f853a6c09725bf7132b10 100644 (file)
@@ -401,12 +401,12 @@ fn get_targets_root_only(
 
 fn get_targets_recursive(
     manifest_path: Option<&Path>,
-    mut targets: &mut BTreeSet<Target>,
+    targets: &mut BTreeSet<Target>,
     visited: &mut BTreeSet<String>,
 ) -> Result<(), io::Error> {
     let metadata = get_cargo_metadata(manifest_path)?;
     for package in &metadata.packages {
-        add_targets(&package.targets, &mut targets);
+        add_targets(&package.targets, targets);
 
         // Look for local dependencies using information available since cargo v1.51
         // It's theoretically possible someone could use a newer version of rustfmt with
@@ -427,7 +427,7 @@ fn get_targets_recursive(
                     .any(|p| p.manifest_path.eq(&manifest_path))
             {
                 visited.insert(dependency.name.to_owned());
-                get_targets_recursive(Some(&manifest_path), &mut targets, visited)?;
+                get_targets_recursive(Some(&manifest_path), targets, visited)?;
             }
         }
     }
index 614638ea2abfbea7c4096c9cf5443bb7afe17041..e26e24ec55ad6c40fe495ddc41c57cba89e218c5 100644 (file)
@@ -568,7 +568,7 @@ fn format_last_child(
         } else {
             self.rewrites
                 .iter()
-                .map(|rw| utils::unicode_str_width(&rw))
+                .map(|rw| utils::unicode_str_width(rw))
                 .sum()
         } + last.tries;
         let one_line_budget = if self.child_count == 1 {
@@ -673,7 +673,7 @@ fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> Opt
                 ChainItemKind::Comment(_, CommentPosition::Top) => result.push_str(&connector),
                 _ => result.push_str(&connector),
             }
-            result.push_str(&rewrite);
+            result.push_str(rewrite);
         }
 
         Some(result)
index dc4f4516252b122267dfb3030bdc01324deeba3a..7b76c232937dc7cea63d7df07716777730cbeef2 100644 (file)
@@ -405,7 +405,7 @@ impl CodeBlockAttribute {
     /// attributes are valid rust attributes
     /// See <https://doc.rust-lang.org/rustdoc/print.html#attributes>
     fn new(attributes: &str) -> CodeBlockAttribute {
-        for attribute in attributes.split(",") {
+        for attribute in attributes.split(',') {
             match attribute.trim() {
                 "" | "rust" | "should_panic" | "no_run" | "edition2015" | "edition2018"
                 | "edition2021" => (),
@@ -563,7 +563,7 @@ fn join_block(s: &str, sep: &str) -> String {
             result.push_str(line);
             result.push_str(match iter.peek() {
                 Some(next_line) if next_line.is_empty() => sep.trim_end(),
-                Some(..) => &sep,
+                Some(..) => sep,
                 None => "",
             });
         }
@@ -622,7 +622,7 @@ fn handle_line(
         let is_last = i == count_newlines(orig);
 
         if let Some(ref mut ib) = self.item_block {
-            if ib.add_line(&line) {
+            if ib.add_line(line) {
                 return false;
             }
             self.is_prev_line_multi_line = false;
@@ -684,8 +684,8 @@ fn handle_line(
         self.item_block = None;
         if let Some(stripped) = line.strip_prefix("```") {
             self.code_block_attr = Some(CodeBlockAttribute::new(stripped))
-        } else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(&line) {
-            let ib = ItemizedBlock::new(&line);
+        } else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(line) {
+            let ib = ItemizedBlock::new(line);
             self.item_block = Some(ib);
             return false;
         }
@@ -941,7 +941,7 @@ fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle<'_>) -> (&'a s
     {
         (&line[4..], true)
     } else if let CommentStyle::Custom(opener) = *style {
-        if let Some(ref stripped) = line.strip_prefix(opener) {
+        if let Some(stripped) = line.strip_prefix(opener) {
             (stripped, true)
         } else {
             (&line[opener.trim_end().len()..], false)
@@ -1384,7 +1384,7 @@ fn next(&mut self) -> Option<Self::Item> {
             None => unreachable!(),
         };
 
-        while let Some((kind, c)) = self.base.next() {
+        for (kind, c) in self.base.by_ref() {
             // needed to set the kind of the ending character on the last line
             self.kind = kind;
             if c == '\n' {
@@ -1570,7 +1570,7 @@ pub(crate) fn recover_comment_removed(
                 context.parse_sess.span_to_filename(span),
                 vec![FormattingError::from_span(
                     span,
-                    &context.parse_sess,
+                    context.parse_sess,
                     ErrorKind::LostComment,
                 )],
             );
@@ -1675,7 +1675,7 @@ fn next(&mut self) -> Option<Self::Item> {
 fn remove_comment_header(comment: &str) -> &str {
     if comment.starts_with("///") || comment.starts_with("//!") {
         &comment[3..]
-    } else if let Some(ref stripped) = comment.strip_prefix("//") {
+    } else if let Some(stripped) = comment.strip_prefix("//") {
         stripped
     } else if (comment.starts_with("/**") && !comment.starts_with("/**/"))
         || comment.starts_with("/*!")
index e92f8e8a53152e666cec884eae3a8808bcf40d18..bce9e5d07f267a67a8c39917609d4fa38cfbf115 100644 (file)
@@ -20,7 +20,7 @@ pub enum NewlineStyle {
     Windows,
     /// Force CR (`\n).
     Unix,
-    /// `\r\n` in Windows, `\n`` on other platforms.
+    /// `\r\n` in Windows, `\n` on other platforms.
     Native,
 }
 
@@ -112,6 +112,8 @@ pub enum GroupImportsTactic {
     ///  2. other imports
     ///  3. `self` / `crate` / `super` imports
     StdExternalCrate,
+    /// Discard existing groups, and create a single group for everything
+    One,
 }
 
 #[config_type]
index 4448214f3ff2cd1ac4c2fd7e519ca8342c436289..76f2527db3dad1d69c78d8b54c7eeea4244b4469 100644 (file)
@@ -121,7 +121,7 @@ fn emits_single_xml_tree_containing_all_files() {
             format!(r#"<file name="{}">"#, bin_file),
             format!(
                 r#"<error line="2" severity="warning" message="Should be `{}`" />"#,
-                XmlEscaped(&r#"    println!("Hello, world!");"#),
+                XmlEscaped(r#"    println!("Hello, world!");"#),
             ),
             String::from("</file>"),
         ];
@@ -129,7 +129,7 @@ fn emits_single_xml_tree_containing_all_files() {
             format!(r#"<file name="{}">"#, lib_file),
             format!(
                 r#"<error line="2" severity="warning" message="Should be `{}`" />"#,
-                XmlEscaped(&r#"    println!("Greetings!");"#),
+                XmlEscaped(r#"    println!("Greetings!");"#),
             ),
             String::from("</file>"),
         ];
index 2fbbfedb566d13cbe1bb657685de4cd1fa6cd71e..7264ad8bbf365baaf0f2d7e74ff3fb8e61bd5e7d 100644 (file)
@@ -23,7 +23,7 @@ fn emit_formatted_file(
         }: FormattedFile<'_>,
     ) -> Result<EmitterResult, io::Error> {
         const CONTEXT_SIZE: usize = 3;
-        let mismatch = make_diff(&original_text, formatted_text, CONTEXT_SIZE);
+        let mismatch = make_diff(original_text, formatted_text, CONTEXT_SIZE);
         let has_diff = !mismatch.is_empty();
 
         if has_diff {
index 7f1dd363f9379a3bd971dbf87c93e4a0955a0cab..58942e442de05ba39ef3472bbb6b51850711ebfc 100644 (file)
@@ -257,7 +257,7 @@ fn needs_space_before_range(context: &RewriteContext<'_>, lhs: &ast::Expr) -> bo
                         }
                         _ => false,
                     },
-                    ast::ExprKind::Unary(_, ref expr) => needs_space_before_range(context, &expr),
+                    ast::ExprKind::Unary(_, ref expr) => needs_space_before_range(context, expr),
                     _ => false,
                 }
             }
@@ -423,7 +423,7 @@ fn rewrite_empty_block(
     prefix: &str,
     shape: Shape,
 ) -> Option<String> {
-    if block_has_statements(&block) {
+    if block_has_statements(block) {
         return None;
     }
 
@@ -1148,7 +1148,7 @@ pub(crate) fn is_empty_block(
     block: &ast::Block,
     attrs: Option<&[ast::Attribute]>,
 ) -> bool {
-    !block_has_statements(&block)
+    !block_has_statements(block)
         && !block_contains_comment(context, block)
         && attrs.map_or(true, |a| inner_attributes(a).is_empty())
 }
@@ -1207,11 +1207,11 @@ fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -
     let span = lit.span;
     let symbol = lit.token.symbol.as_str();
 
-    if symbol.starts_with("0x") {
+    if let Some(symbol_stripped) = symbol.strip_prefix("0x") {
         let hex_lit = match context.config.hex_literal_case() {
             HexLiteralCase::Preserve => None,
-            HexLiteralCase::Upper => Some(symbol[2..].to_ascii_uppercase()),
-            HexLiteralCase::Lower => Some(symbol[2..].to_ascii_lowercase()),
+            HexLiteralCase::Upper => Some(symbol_stripped.to_ascii_uppercase()),
+            HexLiteralCase::Lower => Some(symbol_stripped.to_ascii_lowercase()),
         };
         if let Some(hex_lit) = hex_lit {
             return wrap_str(
@@ -1621,7 +1621,7 @@ enum StructLitField<'a> {
     };
 
     let fields_str =
-        wrap_struct_field(context, &attrs, &fields_str, shape, v_shape, one_line_width)?;
+        wrap_struct_field(context, attrs, &fields_str, shape, v_shape, one_line_width)?;
     Some(format!("{} {{{}}}", path_str, fields_str))
 
     // FIXME if context.config.indent_style() == Visual, but we run out
@@ -1888,7 +1888,7 @@ pub(crate) fn rewrite_assign_rhs_expr<R: Rewrite>(
     shape: Shape,
     rhs_tactics: RhsTactics,
 ) -> Option<String> {
-    let last_line_width = last_line_width(&lhs).saturating_sub(if lhs.contains('\n') {
+    let last_line_width = last_line_width(lhs).saturating_sub(if lhs.contains('\n') {
         shape.indent.width()
     } else {
         0
@@ -1947,7 +1947,7 @@ pub(crate) fn rewrite_assign_rhs_with_comments<S: Into<String>, R: Rewrite>(
 
     if contains_comment {
         let rhs = rhs.trim_start();
-        combine_strs_with_missing_comments(context, &lhs, &rhs, between_span, shape, allow_extend)
+        combine_strs_with_missing_comments(context, &lhs, rhs, between_span, shape, allow_extend)
     } else {
         Some(lhs + &rhs)
     }
@@ -1962,6 +1962,9 @@ fn choose_rhs<R: Rewrite>(
     has_rhs_comment: bool,
 ) -> Option<String> {
     match orig_rhs {
+        Some(ref new_str) if new_str.is_empty() => {
+            return Some(String::new());
+        }
         Some(ref new_str)
             if !new_str.contains('\n') && unicode_str_width(new_str) <= shape.width =>
         {
index c751932273b0a8f27c494f25799a49a9dfc08f33..655aeda42bf28daab91e885b1fae84f37e355b14 100644 (file)
@@ -64,7 +64,7 @@ pub struct Opts {
 }
 
 fn main() {
-    env_logger::init();
+    env_logger::Builder::from_env("RUSTFMT_LOG").init();
     let opts = Opts::from_args();
     if let Err(e) = run(opts) {
         println!("{}", e);
index 9ef47b887cadb8809345b1dc196017bbbad92c59..7d0facb8f12cf683b93fe7e17f630ce488190652 100644 (file)
@@ -155,7 +155,7 @@ fn format_file(
         let snippet_provider = self.parse_session.snippet_provider(module.span);
         let mut visitor = FmtVisitor::from_parse_sess(
             &self.parse_session,
-            &self.config,
+            self.config,
             &snippet_provider,
             self.report.clone(),
         );
@@ -180,7 +180,7 @@ fn format_file(
             &mut visitor.buffer,
             &path,
             &visitor.skipped_range.borrow(),
-            &self.config,
+            self.config,
             &self.report,
         );
 
index 16f5d1dd4f234fe17091843ebcfa8133bacffaaa..579778edbe742704519998bd1aba4d1fd1bdf95d 100644 (file)
@@ -170,7 +170,7 @@ fn from_args(matches: &Matches, opts: &Options) -> Config {
 }
 
 fn main() {
-    env_logger::init();
+    env_logger::Builder::from_env("RUSTFMT_LOG").init();
 
     let opts = make_opts();
     let matches = opts
index 5ac799366894de843dd6250a97adc2786a1cc1e4..40e0d06f99df8d14b7279dabb7bf503c747a6fcc 100644 (file)
@@ -275,7 +275,7 @@ pub(crate) fn rewrite_top_level(
         shape: Shape,
     ) -> Option<String> {
         let vis = self.visibility.as_ref().map_or(Cow::from(""), |vis| {
-            crate::utils::format_visibility(context, &vis)
+            crate::utils::format_visibility(context, vis)
         });
         let use_str = self
             .rewrite(context, shape.offset_left(vis.len())?)
@@ -929,7 +929,7 @@ impl Rewrite for UseTree {
     fn rewrite(&self, context: &RewriteContext<'_>, mut shape: Shape) -> Option<String> {
         let mut result = String::with_capacity(256);
         let mut iter = self.path.iter().peekable();
-        while let Some(ref segment) = iter.next() {
+        while let Some(segment) = iter.next() {
             let segment_str = segment.rewrite(context, shape)?;
             result.push_str(&segment_str);
             if iter.peek().is_some() {
index 1cb1a2701c36bf24f78109c56c45d320c4da2806..50121a8b6b50e7d506d07e9a14ed645579e2d094 100644 (file)
@@ -226,7 +226,7 @@ pub(crate) fn from_fn_kind(
     fn to_str(&self, context: &RewriteContext<'_>) -> String {
         let mut result = String::with_capacity(128);
         // Vis defaultness constness unsafety abi.
-        result.push_str(&*format_visibility(context, &self.visibility));
+        result.push_str(&*format_visibility(context, self.visibility));
         result.push_str(format_defaultness(self.defaultness));
         result.push_str(format_constness(self.constness));
         result.push_str(format_async(&self.is_async));
@@ -622,7 +622,7 @@ fn both_opaque(
             fn need_empty_line(a: &ast::AssocItemKind, b: &ast::AssocItemKind) -> bool {
                 match (a, b) {
                     (TyAlias(lty), TyAlias(rty))
-                        if both_type(&lty.3, &rty.3) || both_opaque(&lty.3, &rty.3) =>
+                        if both_type(&lty.ty, &rty.ty) || both_opaque(&lty.ty, &rty.ty) =>
                     {
                         false
                     }
@@ -633,7 +633,7 @@ fn need_empty_line(a: &ast::AssocItemKind, b: &ast::AssocItemKind) -> bool {
 
             buffer.sort_by(|(_, a), (_, b)| match (&a.kind, &b.kind) {
                 (TyAlias(lty), TyAlias(rty))
-                    if both_type(&lty.3, &rty.3) || both_opaque(&lty.3, &rty.3) =>
+                    if both_type(&lty.ty, &rty.ty) || both_opaque(&lty.ty, &rty.ty) =>
                 {
                     a.ident.as_str().cmp(&b.ident.as_str())
                 }
@@ -641,8 +641,8 @@ fn need_empty_line(a: &ast::AssocItemKind, b: &ast::AssocItemKind) -> bool {
                     a.ident.as_str().cmp(&b.ident.as_str())
                 }
                 (Fn(..), Fn(..)) => a.span.lo().cmp(&b.span.lo()),
-                (TyAlias(ty), _) if is_type(&ty.3) => Ordering::Less,
-                (_, TyAlias(ty)) if is_type(&ty.3) => Ordering::Greater,
+                (TyAlias(ty), _) if is_type(&ty.ty) => Ordering::Less,
+                (_, TyAlias(ty)) if is_type(&ty.ty) => Ordering::Greater,
                 (TyAlias(..), _) => Ordering::Less,
                 (_, TyAlias(..)) => Ordering::Greater,
                 (Const(..), _) => Ordering::Less,
@@ -679,7 +679,7 @@ pub(crate) fn format_impl(
     offset: Indent,
 ) -> Option<String> {
     if let ast::ItemKind::Impl(impl_kind) = &item.kind {
-        let ast::ImplKind {
+        let ast::Impl {
             ref generics,
             ref self_ty,
             ref items,
@@ -833,7 +833,7 @@ fn format_impl_ref_and_type(
     offset: Indent,
 ) -> Option<String> {
     if let ast::ItemKind::Impl(impl_kind) = &item.kind {
-        let ast::ImplKind {
+        let ast::Impl {
             unsafety,
             polarity,
             defaultness,
@@ -1029,8 +1029,13 @@ pub(crate) fn format_trait(
     offset: Indent,
 ) -> Option<String> {
     if let ast::ItemKind::Trait(trait_kind) = &item.kind {
-        let ast::TraitKind(is_auto, unsafety, ref generics, ref generic_bounds, ref trait_items) =
-            **trait_kind;
+        let ast::Trait {
+            is_auto,
+            unsafety,
+            ref generics,
+            ref bounds,
+            ref items,
+        } = **trait_kind;
         let mut result = String::with_capacity(128);
         let header = format!(
             "{}{}{}trait ",
@@ -1048,11 +1053,11 @@ pub(crate) fn format_trait(
         result.push_str(&generics_str);
 
         // FIXME(#2055): rustfmt fails to format when there are comments between trait bounds.
-        if !generic_bounds.is_empty() {
+        if !bounds.is_empty() {
             let ident_hi = context
                 .snippet_provider
                 .span_after(item.span, &item.ident.as_str());
-            let bound_hi = generic_bounds.last().unwrap().span().hi();
+            let bound_hi = bounds.last().unwrap().span().hi();
             let snippet = context.snippet(mk_sp(ident_hi, bound_hi));
             if contains_comment(snippet) {
                 return None;
@@ -1061,7 +1066,7 @@ pub(crate) fn format_trait(
             result = rewrite_assign_rhs_with(
                 context,
                 result + ":",
-                generic_bounds,
+                bounds,
                 shape,
                 RhsTactics::ForceNextLineWithoutIndent,
             )?;
@@ -1072,10 +1077,10 @@ pub(crate) fn format_trait(
             let where_on_new_line = context.config.indent_style() != IndentStyle::Block;
 
             let where_budget = context.budget(last_line_width(&result));
-            let pos_before_where = if generic_bounds.is_empty() {
+            let pos_before_where = if bounds.is_empty() {
                 generics.where_clause.span.lo()
             } else {
-                generic_bounds[generic_bounds.len() - 1].span().hi()
+                bounds[bounds.len() - 1].span().hi()
             };
             let option = WhereClauseOption::snuggled(&generics_str);
             let where_clause_str = rewrite_where_clause(
@@ -1122,19 +1127,31 @@ pub(crate) fn format_trait(
             }
         }
 
+        let block_span = mk_sp(generics.where_clause.span.hi(), item.span.hi());
+        let snippet = context.snippet(block_span);
+        let open_pos = snippet.find_uncommented("{")? + 1;
+
         match context.config.brace_style() {
             _ if last_line_contains_single_line_comment(&result)
                 || last_line_width(&result) + 2 > context.budget(offset.width()) =>
             {
                 result.push_str(&offset.to_string_with_newline(context.config));
             }
+            _ if context.config.empty_item_single_line()
+                && items.is_empty()
+                && !result.contains('\n')
+                && !contains_comment(&snippet[open_pos..]) =>
+            {
+                result.push_str(" {}");
+                return Some(result);
+            }
             BraceStyle::AlwaysNextLine => {
                 result.push_str(&offset.to_string_with_newline(context.config));
             }
             BraceStyle::PreferSameLine => result.push(' '),
             BraceStyle::SameLineWhere => {
                 if result.contains('\n')
-                    || (!generics.where_clause.predicates.is_empty() && !trait_items.is_empty())
+                    || (!generics.where_clause.predicates.is_empty() && !items.is_empty())
                 {
                     result.push_str(&offset.to_string_with_newline(context.config));
                 } else {
@@ -1144,17 +1161,14 @@ pub(crate) fn format_trait(
         }
         result.push('{');
 
-        let block_span = mk_sp(generics.where_clause.span.hi(), item.span.hi());
-        let snippet = context.snippet(block_span);
-        let open_pos = snippet.find_uncommented("{")? + 1;
         let outer_indent_str = offset.block_only().to_string_with_newline(context.config);
 
-        if !trait_items.is_empty() || contains_comment(&snippet[open_pos..]) {
+        if !items.is_empty() || contains_comment(&snippet[open_pos..]) {
             let mut visitor = FmtVisitor::from_context(context);
             visitor.block_indent = offset.block_only().block_indent(context.config);
             visitor.last_pos = block_span.lo() + BytePos(open_pos as u32);
 
-            for item in trait_items {
+            for item in items {
                 visitor.visit_trait_item(item);
             }
 
@@ -1176,18 +1190,6 @@ pub(crate) fn format_trait(
     }
 }
 
-struct OpaqueTypeBounds<'a> {
-    generic_bounds: &'a ast::GenericBounds,
-}
-
-impl<'a> Rewrite for OpaqueTypeBounds<'a> {
-    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        self.generic_bounds
-            .rewrite(context, shape)
-            .map(|s| format!("impl {}", s))
-    }
-}
-
 pub(crate) struct TraitAliasBounds<'a> {
     generic_bounds: &'a ast::GenericBounds,
     generics: &'a ast::Generics,
@@ -1220,7 +1222,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
         } else if fits_single_line {
             Cow::from(" ")
         } else {
-            shape.indent.to_string_with_newline(&context.config)
+            shape.indent.to_string_with_newline(context.config)
         };
 
         Some(format!("{}{}{}", generic_bounds_str, space, where_str))
@@ -1238,7 +1240,7 @@ pub(crate) fn format_trait_alias(
     let alias = rewrite_ident(context, ident);
     // 6 = "trait ", 2 = " ="
     let g_shape = shape.offset_left(6)?.sub_width(2)?;
-    let generics_str = rewrite_generics(context, &alias, generics, g_shape)?;
+    let generics_str = rewrite_generics(context, alias, generics, g_shape)?;
     let vis_str = format_visibility(context, vis);
     let lhs = format!("{}trait {} =", vis_str, generics_str);
     // 1 = ";"
@@ -1386,7 +1388,7 @@ fn format_empty_struct_or_tuple(
     closer: &str,
 ) {
     // 3 = " {}" or "();"
-    let used_width = last_line_used_width(&result, offset.width()) + 3;
+    let used_width = last_line_used_width(result, offset.width()) + 3;
     if used_width > context.config.max_width() {
         result.push_str(&offset.to_string_with_newline(context.config))
     }
@@ -1509,17 +1511,84 @@ fn format_tuple_struct(
     Some(result)
 }
 
-pub(crate) fn rewrite_type<R: Rewrite>(
-    context: &RewriteContext<'_>,
+pub(crate) enum ItemVisitorKind<'a> {
+    Item(&'a ast::Item),
+    AssocTraitItem(&'a ast::AssocItem),
+    AssocImplItem(&'a ast::AssocItem),
+    ForeignItem(&'a ast::ForeignItem),
+}
+
+struct TyAliasRewriteInfo<'c, 'g>(
+    &'c RewriteContext<'c>,
+    Indent,
+    &'g ast::Generics,
+    symbol::Ident,
+    Span,
+);
+
+pub(crate) fn rewrite_type_alias<'a, 'b>(
+    ty_alias_kind: &ast::TyAlias,
+    context: &RewriteContext<'a>,
     indent: Indent,
-    ident: symbol::Ident,
-    vis: &ast::Visibility,
-    generics: &ast::Generics,
+    visitor_kind: &ItemVisitorKind<'b>,
+    span: Span,
+) -> Option<String> {
+    use ItemVisitorKind::*;
+
+    let ast::TyAlias {
+        defaultness,
+        ref generics,
+        ref bounds,
+        ref ty,
+    } = *ty_alias_kind;
+    let ty_opt = ty.as_ref().map(|t| &**t);
+    let (ident, vis) = match visitor_kind {
+        Item(i) => (i.ident, &i.vis),
+        AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis),
+        ForeignItem(i) => (i.ident, &i.vis),
+    };
+    let rw_info = &TyAliasRewriteInfo(context, indent, generics, ident, span);
+
+    // Type Aliases are formatted slightly differently depending on the context
+    // in which they appear, whether they are opaque, and whether they are associated.
+    // https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html
+    // https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases
+    match (visitor_kind, ty_opt) {
+        (Item(_), None) => {
+            let op_ty = OpaqueType { bounds };
+            rewrite_ty(rw_info, Some(bounds), Some(&op_ty), vis)
+        }
+        (Item(_), Some(ty)) => rewrite_ty(rw_info, Some(bounds), Some(&*ty), vis),
+        (AssocImplItem(_), _) => {
+            let result = if let Some(ast::Ty {
+                kind: ast::TyKind::ImplTrait(_, ref bounds),
+                ..
+            }) = ty_opt
+            {
+                let op_ty = OpaqueType { bounds };
+                rewrite_ty(rw_info, None, Some(&op_ty), &DEFAULT_VISIBILITY)
+            } else {
+                rewrite_ty(rw_info, None, ty.as_ref(), vis)
+            }?;
+            match defaultness {
+                ast::Defaultness::Default(..) => Some(format!("default {}", result)),
+                _ => Some(result),
+            }
+        }
+        (AssocTraitItem(_), _) | (ForeignItem(_), _) => {
+            rewrite_ty(rw_info, Some(bounds), ty.as_ref(), vis)
+        }
+    }
+}
+
+fn rewrite_ty<R: Rewrite>(
+    rw_info: &TyAliasRewriteInfo<'_, '_>,
     generic_bounds_opt: Option<&ast::GenericBounds>,
     rhs: Option<&R>,
-    span: Span,
+    vis: &ast::Visibility,
 ) -> Option<String> {
     let mut result = String::with_capacity(128);
+    let TyAliasRewriteInfo(context, indent, generics, ident, span) = *rw_info;
     result.push_str(&format!("{}type ", format_visibility(context, vis)));
     let ident_str = rewrite_ident(context, ident);
 
@@ -1607,28 +1676,6 @@ pub(crate) fn rewrite_type<R: Rewrite>(
     }
 }
 
-pub(crate) fn rewrite_opaque_type(
-    context: &RewriteContext<'_>,
-    indent: Indent,
-    ident: symbol::Ident,
-    generic_bounds: &ast::GenericBounds,
-    generics: &ast::Generics,
-    vis: &ast::Visibility,
-    span: Span,
-) -> Option<String> {
-    let opaque_type_bounds = OpaqueTypeBounds { generic_bounds };
-    rewrite_type(
-        context,
-        indent,
-        ident,
-        vis,
-        generics,
-        Some(generic_bounds),
-        Some(&opaque_type_bounds),
-        span,
-    )
-}
-
 fn type_annotation_spacing(config: &Config) -> (&str, &str) {
     (
         if config.space_before_colon() { " " } else { "" },
@@ -1866,42 +1913,6 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
     }
 }
 
-pub(crate) fn rewrite_impl_type(
-    ident: symbol::Ident,
-    vis: &ast::Visibility,
-    defaultness: ast::Defaultness,
-    ty_opt: Option<&ptr::P<ast::Ty>>,
-    generics: &ast::Generics,
-    context: &RewriteContext<'_>,
-    indent: Indent,
-    span: Span,
-) -> Option<String> {
-    // Opaque type
-    let result = if let Some(rustc_ast::ast::Ty {
-        kind: ast::TyKind::ImplTrait(_, ref bounds),
-        ..
-    }) = ty_opt.map(|t| &**t)
-    {
-        rewrite_type(
-            context,
-            indent,
-            ident,
-            &DEFAULT_VISIBILITY,
-            generics,
-            None,
-            Some(&OpaqueType { bounds }),
-            span,
-        )
-    } else {
-        rewrite_type(context, indent, ident, vis, generics, None, ty_opt, span)
-    }?;
-
-    match defaultness {
-        ast::Defaultness::Default(..) => Some(format!("default {}", result)),
-        _ => Some(result),
-    }
-}
-
 impl Rewrite for ast::FnRetTy {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         match *self {
@@ -2066,7 +2077,7 @@ fn rewrite_explicit_self(
                     )?;
                     Some(combine_strs_with_missing_comments(
                         context,
-                        &param_attrs,
+                        param_attrs,
                         &format!("&{} {}self", lifetime_str, mut_str),
                         span,
                         shape,
@@ -2075,7 +2086,7 @@ fn rewrite_explicit_self(
                 }
                 None => Some(combine_strs_with_missing_comments(
                     context,
-                    &param_attrs,
+                    param_attrs,
                     &format!("&{}self", mut_str),
                     span,
                     shape,
@@ -2091,7 +2102,7 @@ fn rewrite_explicit_self(
 
             Some(combine_strs_with_missing_comments(
                 context,
-                &param_attrs,
+                param_attrs,
                 &format!("{}self: {}", format_mutability(mutability), type_str),
                 span,
                 shape,
@@ -2100,7 +2111,7 @@ fn rewrite_explicit_self(
         }
         ast::SelfKind::Value(mutability) => Some(combine_strs_with_missing_comments(
             context,
-            &param_attrs,
+            param_attrs,
             &format!("{}self", format_mutability(mutability)),
             span,
             shape,
@@ -2226,7 +2237,7 @@ fn rewrite_fn_base(
     }
 
     // Skip `pub(crate)`.
-    let lo_after_visibility = get_bytepos_after_visibility(&fn_sig.visibility, span);
+    let lo_after_visibility = get_bytepos_after_visibility(fn_sig.visibility, span);
     // A conservative estimation, the goal is to be over all parens in generics
     let params_start = fn_sig
         .generics
@@ -2984,7 +2995,7 @@ fn format_header(
     let mut result = String::with_capacity(128);
     let shape = Shape::indented(offset, context.config);
 
-    result.push_str(&format_visibility(context, vis).trim());
+    result.push_str(format_visibility(context, vis).trim());
 
     // Check for a missing comment between the visibility and the item name.
     let after_vis = vis.span.hi();
@@ -3005,7 +3016,7 @@ fn format_header(
         }
     }
 
-    result.push_str(&rewrite_ident(context, ident));
+    result.push_str(rewrite_ident(context, ident));
 
     result
 }
@@ -3125,17 +3136,22 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
 
         let item_str = match self.kind {
             ast::ForeignItemKind::Fn(ref fn_kind) => {
-                let ast::FnKind(defaultness, ref fn_sig, ref generics, ref block) = **fn_kind;
-                if let Some(ref body) = block {
+                let ast::Fn {
+                    defaultness,
+                    ref sig,
+                    ref generics,
+                    ref body,
+                } = **fn_kind;
+                if let Some(ref body) = body {
                     let mut visitor = FmtVisitor::from_context(context);
                     visitor.block_indent = shape.indent;
                     visitor.last_pos = self.span.lo();
                     let inner_attrs = inner_attributes(&self.attrs);
                     let fn_ctxt = visit::FnCtxt::Foreign;
                     visitor.visit_fn(
-                        visit::FnKind::Fn(fn_ctxt, self.ident, &fn_sig, &self.vis, Some(body)),
+                        visit::FnKind::Fn(fn_ctxt, self.ident, &sig, &self.vis, Some(body)),
                         generics,
-                        &fn_sig.decl,
+                        &sig.decl,
                         self.span,
                         defaultness,
                         Some(&inner_attrs),
@@ -3146,7 +3162,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
                         context,
                         shape.indent,
                         self.ident,
-                        &FnSig::from_method_sig(&fn_sig, generics, &self.vis),
+                        &FnSig::from_method_sig(&sig, generics, &self.vis),
                         span,
                         FnBraceStyle::None,
                     )
@@ -3167,19 +3183,9 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
                 // 1 = ;
                 rewrite_assign_rhs(context, prefix, &**ty, shape.sub_width(1)?).map(|s| s + ";")
             }
-            ast::ForeignItemKind::TyAlias(ref ty_alias_kind) => {
-                let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) =
-                    **ty_alias_kind;
-                rewrite_type(
-                    &context,
-                    shape.indent,
-                    self.ident,
-                    &self.vis,
-                    generics,
-                    Some(generic_bounds),
-                    type_default.as_ref(),
-                    self.span,
-                )
+            ast::ForeignItemKind::TyAlias(ref ty_alias) => {
+                let (kind, span) = (&ItemVisitorKind::ForeignItem(&self), self.span);
+                rewrite_type_alias(ty_alias, context, shape.indent, kind, span)
             }
             ast::ForeignItemKind::MacCall(ref mac) => {
                 rewrite_macro(mac, None, context, shape, MacroPosition::Item)
@@ -3229,7 +3235,7 @@ fn rewrite_attrs(
     combine_strs_with_missing_comments(
         context,
         &attrs_str,
-        &item_str,
+        item_str,
         missed_span,
         shape,
         allow_extend,
index 47a7b9d4dbe3cb80baa2d08d979e9e94e2b56241..792a1080f0e92189e276168cc0344ef8ba423eba 100644 (file)
@@ -283,7 +283,7 @@ pub fn fancy_print(
         writeln!(
             t,
             "{}",
-            FormatReportFormatterBuilder::new(&self)
+            FormatReportFormatterBuilder::new(self)
                 .enable_colors(true)
                 .build()
         )?;
@@ -297,7 +297,7 @@ pub fn fancy_print(
 impl fmt::Display for FormatReport {
     // Prints all the formatting errors.
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
-        write!(fmt, "{}", FormatReportFormatterBuilder::new(&self).build())?;
+        write!(fmt, "{}", FormatReportFormatterBuilder::new(self).build())?;
         Ok(())
     }
 }
index c04b4787616933e84528d1695a386eefce5769ab..d341ec8e6b0e7d15f428cc3e91527635129f9687 100644 (file)
@@ -386,7 +386,7 @@ pub(crate) fn write_list<I, T>(items: I, formatting: &ListFormatting<'_>) -> Opt
                         result.push('\n');
                         result.push_str(indent_str);
                         // This is the width of the item (without comments).
-                        line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s));
+                        line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(s));
                     }
                 } else {
                     result.push(' ')
@@ -820,7 +820,7 @@ fn calculate_width<I, T>(items: I) -> (usize, usize)
 pub(crate) fn total_item_width(item: &ListItem) -> usize {
     comment_len(item.pre_comment.as_ref().map(|x| &(*x)[..]))
         + comment_len(item.post_comment.as_ref().map(|x| &(*x)[..]))
-        + item.item.as_ref().map_or(0, |s| unicode_str_width(&s))
+        + item.item.as_ref().map_or(0, |s| unicode_str_width(s))
 }
 
 fn comment_len(comment: Option<&str>) -> usize {
index 927187dfd8a2336b20220dd9e794bc04171f0eff..ef747638e33ec83459e4b9f9fe02d052e41c4812 100644 (file)
@@ -186,7 +186,7 @@ fn return_macro_parse_failure_fallback(
         })
         .unwrap_or(false);
     if is_like_block_indent_style {
-        return trim_left_preserve_layout(context.snippet(span), indent, &context.config);
+        return trim_left_preserve_layout(context.snippet(span), indent, context.config);
     }
 
     context.skipped_range.borrow_mut().push((
@@ -437,7 +437,7 @@ fn rewrite_macro_inner(
             // the `macro_name!` and `{ /* macro_body */ }` but skip modifying
             // anything in between the braces (for now).
             let snippet = context.snippet(mac.span()).trim_start_matches(|c| c != '{');
-            match trim_left_preserve_layout(snippet, shape.indent, &context.config) {
+            match trim_left_preserve_layout(snippet, shape.indent, context.config) {
                 Some(macro_body) => Some(format!("{} {}", macro_name, macro_body)),
                 None => Some(format!("{} {}", macro_name, snippet)),
             }
@@ -901,7 +901,7 @@ fn add_repeat(
                     break;
                 }
                 TokenTree::Token(ref t) => {
-                    buffer.push_str(&pprust::token_to_string(&t));
+                    buffer.push_str(&pprust::token_to_string(t));
                 }
                 _ => return None,
             }
@@ -1045,7 +1045,7 @@ fn wrap_macro_args_inner(
     let mut iter = args.iter().peekable();
     let indent_str = shape.indent.to_string_with_newline(context.config);
 
-    while let Some(ref arg) = iter.next() {
+    while let Some(arg) = iter.next() {
         result.push_str(&arg.rewrite(context, shape, use_multiple_lines)?);
 
         if use_multiple_lines
@@ -1055,7 +1055,7 @@ fn wrap_macro_args_inner(
                 result.pop();
             }
             result.push_str(&indent_str);
-        } else if let Some(ref next_arg) = iter.peek() {
+        } else if let Some(next_arg) = iter.peek() {
             let space_before_dollar =
                 !arg.kind.ends_with_space() && next_arg.kind.starts_with_dollar();
             let space_before_brace = next_arg.kind.starts_with_brace();
@@ -1370,7 +1370,7 @@ fn rewrite(
                     {
                         s += &indent_str;
                     }
-                    (s + l + "\n", indent_next_line(kind, &l, &config))
+                    (s + l + "\n", indent_next_line(kind, l, &config))
                 },
             )
             .0;
@@ -1514,11 +1514,11 @@ fn rewrite_macro_with_items(
             MacroArg::Item(item) => item,
             _ => return None,
         };
-        visitor.visit_item(&item);
+        visitor.visit_item(item);
     }
 
     let mut result = String::with_capacity(256);
-    result.push_str(&macro_name);
+    result.push_str(macro_name);
     result.push_str(opener);
     result.push_str(&visitor.block_indent.to_string_with_newline(context.config));
     result.push_str(visitor.buffer.trim());
index 5a6ed0ec06e55a37ca203bafdbd9625a2ad3ce4c..22d23fc1cdba49bc3f1f68fc4247f5f521ceeabd 100644 (file)
@@ -168,7 +168,7 @@ fn collect_beginning_verts(
         .map(|a| {
             context
                 .snippet(a.pat.span)
-                .starts_with("|")
+                .starts_with('|')
                 .then(|| a.pat.span().lo())
         })
         .collect()
@@ -319,7 +319,7 @@ fn flatten_arm_body<'a>(
     let can_extend =
         |expr| !context.config.force_multiline_blocks() && can_flatten_block_around_this(expr);
 
-    if let Some(ref block) = block_can_be_flattened(context, body) {
+    if let Some(block) = block_can_be_flattened(context, body) {
         if let ast::StmtKind::Expr(ref expr) = block.stmts[0].kind {
             if let ast::ExprKind::Block(..) = expr.kind {
                 flatten_arm_body(context, expr, None)
@@ -393,7 +393,7 @@ fn rewrite_match_body(
         if comment_str.is_empty() {
             String::new()
         } else {
-            rewrite_comment(comment_str, false, shape, &context.config)?
+            rewrite_comment(comment_str, false, shape, context.config)?
         }
     };
 
@@ -408,8 +408,8 @@ fn rewrite_match_body(
                 result.push_str(&arrow_comment);
             }
             result.push_str(&nested_indent_str);
-            result.push_str(&body_str);
-            result.push_str(&comma);
+            result.push_str(body_str);
+            result.push_str(comma);
             return Some(result);
         }
 
@@ -451,7 +451,7 @@ fn rewrite_match_body(
             result.push_str(&arrow_comment);
         }
         result.push_str(&block_sep);
-        result.push_str(&body_str);
+        result.push_str(body_str);
         result.push_str(&body_suffix);
         Some(result)
     };
index ded34d9032f91f188c11c9437b41691cdcce75b5..b1f229d9daaf5f411082f260aa68e358de077dc9 100644 (file)
@@ -16,7 +16,7 @@
     Directory, DirectoryOwnership, ModError, ModulePathSuccess, Parser, ParserError,
 };
 use crate::syntux::session::ParseSess;
-use crate::utils::contains_skip;
+use crate::utils::{contains_skip, mk_sp};
 
 mod visitor;
 
@@ -135,10 +135,12 @@ pub(crate) fn visit_crate(
             self.visit_mod_from_ast(&krate.items)?;
         }
 
+        let snippet_provider = self.parse_sess.snippet_provider(krate.span);
+
         self.file_map.insert(
             root_filename,
             Module::new(
-                krate.span,
+                mk_sp(snippet_provider.start_pos(), snippet_provider.end_pos()),
                 None,
                 Cow::Borrowed(&krate.items),
                 Cow::Borrowed(&krate.attrs),
@@ -197,7 +199,7 @@ fn visit_mod_outside_ast(
     /// Visit modules from AST.
     fn visit_mod_from_ast(
         &mut self,
-        items: &'ast Vec<rustc_ast::ptr::P<ast::Item>>,
+        items: &'ast [rustc_ast::ptr::P<ast::Item>],
     ) -> Result<(), ModuleResolutionError> {
         for item in items {
             if is_cfg_if(item) {
@@ -290,7 +292,7 @@ fn visit_sub_mod_inner(
                 };
                 self.visit_sub_mod_after_directory_update(sub_mod, Some(directory))
             }
-            SubModKind::Internal(ref item) => {
+            SubModKind::Internal(item) => {
                 self.push_inline_mod_directory(item.ident, &item.attrs);
                 self.visit_sub_mod_after_directory_update(sub_mod, None)
             }
@@ -317,9 +319,11 @@ fn visit_sub_mod_after_directory_update(
         }
         match (sub_mod.ast_mod_kind, sub_mod.items) {
             (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => {
-                self.visit_mod_from_ast(&items)
+                self.visit_mod_from_ast(items)
+            }
+            (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _))), _) | (_, Cow::Owned(items)) => {
+                self.visit_mod_outside_ast(items)
             }
-            (Some(Cow::Owned(..)), Cow::Owned(items)) => self.visit_mod_outside_ast(items),
             (_, _) => Ok(()),
         }
     }
index ac24181c7805258b89c053d6c444a65709f79af6..3475f5c378cd2fbde554e4a79d0c191bf99d0a97 100644 (file)
@@ -394,7 +394,7 @@ fn rewrite_last_item_with_overflow(
     ) -> Option<String> {
         let last_item = self.last_item()?;
         let rewrite = match last_item {
-            OverflowableItem::Expr(ref expr) => {
+            OverflowableItem::Expr(expr) => {
                 match expr.kind {
                     // When overflowing the closure which consists of a single control flow
                     // expression, force to use block if its condition uses multi line.
index 0f3d5e8f878ba7d7f08883e95c40262bf2d8adfa..d1c75126ea4a7fce24a8eede42ecd677df916d3e 100644 (file)
@@ -55,11 +55,11 @@ fn rewrite_pairs_one_line<T: Rewrite>(
 
     for ((_, rewrite), s) in list.list.iter().zip(list.separators.iter()) {
         if let Some(rewrite) = rewrite {
-            if !is_single_line(&rewrite) || result.len() > shape.width {
+            if !is_single_line(rewrite) || result.len() > shape.width {
                 return None;
             }
 
-            result.push_str(&rewrite);
+            result.push_str(rewrite);
             result.push(' ');
             result.push_str(s);
             result.push(' ');
@@ -94,18 +94,18 @@ fn rewrite_pairs_multiline<T: Rewrite>(
     shape: Shape,
     context: &RewriteContext<'_>,
 ) -> Option<String> {
-    let rhs_offset = shape.rhs_overhead(&context.config);
+    let rhs_offset = shape.rhs_overhead(context.config);
     let nested_shape = (match context.config.indent_style() {
         IndentStyle::Visual => shape.visual_indent(0),
         IndentStyle::Block => shape.block_indent(context.config.tab_spaces()),
     })
-    .with_max_width(&context.config)
+    .with_max_width(context.config)
     .sub_width(rhs_offset)?;
 
     let indent_str = nested_shape.indent.to_string_with_newline(context.config);
     let mut result = String::new();
 
-    result.push_str(&list.list[0].1.as_ref()?);
+    result.push_str(list.list[0].1.as_ref()?);
 
     for ((e, default_rw), s) in list.list[1..].iter().zip(list.separators.iter()) {
         // The following test checks if we should keep two subexprs on the same
@@ -144,7 +144,7 @@ fn rewrite_pairs_multiline<T: Rewrite>(
             }
         }
 
-        result.push_str(&default_rw.as_ref()?);
+        result.push_str(default_rw.as_ref()?);
     }
     Some(result)
 }
@@ -264,12 +264,12 @@ fn flatten(
                 return node.rewrite(context, shape);
             }
             let nested_overhead = sep + 1;
-            let rhs_offset = shape.rhs_overhead(&context.config);
+            let rhs_offset = shape.rhs_overhead(context.config);
             let nested_shape = (match context.config.indent_style() {
                 IndentStyle::Visual => shape.visual_indent(0),
                 IndentStyle::Block => shape.block_indent(context.config.tab_spaces()),
             })
-            .with_max_width(&context.config)
+            .with_max_width(context.config)
             .sub_width(rhs_offset)?;
             let default_shape = match context.config.binop_separator() {
                 SeparatorPlace::Back => nested_shape.sub_width(nested_overhead)?,
index ba8d8024a9707c34ef31c4eae24665eb99f5f39d..a80d63201f982902a385d4a192273810fef1edce 100644 (file)
@@ -456,11 +456,11 @@ fn rewrite_tuple_pat(
     context: &RewriteContext<'_>,
     shape: Shape,
 ) -> Option<String> {
-    let mut pat_vec: Vec<_> = pats.iter().map(|x| TuplePatField::Pat(x)).collect();
-
-    if pat_vec.is_empty() {
+    if pats.is_empty() {
         return Some(format!("{}()", path_str.unwrap_or_default()));
     }
+    let mut pat_vec: Vec<_> = pats.iter().map(TuplePatField::Pat).collect();
+
     let wildcard_suffix_len = count_wildcard_suffix_len(context, &pat_vec, span, shape);
     let (pat_vec, span) = if context.config.condense_wildcard_suffixes() && wildcard_suffix_len >= 2
     {
@@ -482,7 +482,7 @@ fn rewrite_tuple_pat(
     let path_str = path_str.unwrap_or_default();
 
     overflow::rewrite_with_parens(
-        &context,
+        context,
         &path_str,
         pat_vec.iter(),
         shape,
index 2c58350d4feb6d8e0bf9a3cbfc15d084a0af73a7..0732c8ee70059ca372ff28c0d2445a2394c586e8 100644 (file)
@@ -118,7 +118,9 @@ fn rewrite_reorderable_or_regroupable_items(
             };
 
             let mut regrouped_items = match context.config.group_imports() {
-                GroupImportsTactic::Preserve => vec![normalized_items],
+                GroupImportsTactic::Preserve | GroupImportsTactic::One => {
+                    vec![normalized_items]
+                }
                 GroupImportsTactic::StdExternalCrate => group_imports(normalized_items),
             };
 
index b5fe4335dd33dff97c682f1820ab14acd748dffc..d1bb2f80004aa08461ddf0306bf2285130f80e35 100644 (file)
@@ -112,7 +112,7 @@ pub(crate) fn parse_file_as_module(
         span: Span,
     ) -> Result<(Vec<ast::Attribute>, Vec<ptr::P<ast::Item>>, Span), ParserError> {
         let result = catch_unwind(AssertUnwindSafe(|| {
-            let mut parser = new_parser_from_file(sess.inner(), &path, Some(span));
+            let mut parser = new_parser_from_file(sess.inner(), path, Some(span));
             match parser.parse_mod(&TokenKind::Eof) {
                 Ok(result) => Some(result),
                 Err(mut e) => {
@@ -125,18 +125,12 @@ pub(crate) fn parse_file_as_module(
             }
         }));
         match result {
-            Ok(Some(m)) => {
-                if !sess.has_errors() {
-                    return Ok(m);
-                }
-
-                if sess.can_reset_errors() {
-                    sess.reset_errors();
-                    return Ok(m);
-                }
-                Err(ParserError::ParseError)
+            Ok(Some(m)) if !sess.has_errors() => Ok(m),
+            Ok(Some(m)) if sess.can_reset_errors() => {
+                sess.reset_errors();
+                Ok(m)
             }
-            Ok(None) => Err(ParserError::ParseError),
+            Ok(_) => Err(ParserError::ParseError),
             Err(..) if path.exists() => Err(ParserError::ParseError),
             Err(_) => Err(ParserError::ParsePanicError),
         }
index 946c076d9f2d1fdf388b19156c5c2a7b5ca254e0..cdb4893d443b9b381cde8e4c1d284aee5154ddd4 100644 (file)
@@ -164,7 +164,7 @@ pub(crate) fn is_file_parsed(&self, path: &Path) -> bool {
     }
 
     pub(crate) fn ignore_file(&self, path: &FileName) -> bool {
-        self.ignore_path_set.as_ref().is_match(&path)
+        self.ignore_path_set.as_ref().is_match(path)
     }
 
     pub(crate) fn set_silent_emitter(&mut self) {
index 48d61289a9b8f34a25d89237f5842a1d4245ed29..e2620508c340bad91699e8ebd90b36f2a80f6049 100644 (file)
@@ -535,9 +535,9 @@ fn check_files(files: Vec<PathBuf>, opt_config: &Option<PathBuf>) -> (Vec<Format
 
         debug!("Testing '{}'...", file_name.display());
 
-        match idempotent_check(&file_name, &opt_config) {
+        match idempotent_check(&file_name, opt_config) {
             Ok(ref report) if report.has_warnings() => {
-                print!("{}", FormatReportFormatterBuilder::new(&report).build());
+                print!("{}", FormatReportFormatterBuilder::new(report).build());
                 fails += 1;
             }
             Ok(report) => reports.push(report),
index e0b55e3efb2c4f5714f09abad473ff7b498aaa96..ae4a0d0fccb191003dd5bdc04d2378c1b6707228 100644 (file)
@@ -5,21 +5,39 @@
 
 use crate::{FileName, Input, Session};
 
-#[test]
-fn nested_out_of_line_mods_loaded() {
-    // See also https://github.com/rust-lang/rustfmt/issues/4874
-    let filename = "tests/mod-resolver/issue-4874/main.rs";
-    let input_file = PathBuf::from(filename);
+fn verify_mod_resolution(input_file_name: &str, exp_misformatted_files: &[&str]) {
+    let input_file = PathBuf::from(input_file_name);
     let config = read_config(&input_file);
     let mut session = Session::<io::Stdout>::new(config, None);
     let report = session
-        .format(Input::File(filename.into()))
+        .format(Input::File(input_file_name.into()))
         .expect("Should not have had any execution errors");
     let errors_by_file = &report.internal.borrow().0;
-    assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from(
-        "tests/mod-resolver/issue-4874/bar/baz.rs",
-    ))));
-    assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from(
-        "tests/mod-resolver/issue-4874/foo/qux.rs",
-    ))));
+    for exp_file in exp_misformatted_files {
+        assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from(exp_file))));
+    }
+}
+
+#[test]
+fn nested_out_of_line_mods_loaded() {
+    // See also https://github.com/rust-lang/rustfmt/issues/4874
+    verify_mod_resolution(
+        "tests/mod-resolver/issue-4874/main.rs",
+        &[
+            "tests/mod-resolver/issue-4874/bar/baz.rs",
+            "tests/mod-resolver/issue-4874/foo/qux.rs",
+        ],
+    );
+}
+
+#[test]
+fn out_of_line_nested_inline_within_out_of_line() {
+    // See also https://github.com/rust-lang/rustfmt/issues/5063
+    verify_mod_resolution(
+        "tests/mod-resolver/issue-5063/main.rs",
+        &[
+            "tests/mod-resolver/issue-5063/foo/bar/baz.rs",
+            "tests/mod-resolver/issue-5063/foo.rs",
+        ],
+    );
 }
index 62c05ba078c56facce55f848d2b4cee53e0a1c78..9ea90c5e46dd87104522dd220558e7127ade7cdb 100644 (file)
@@ -728,7 +728,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
                     result = combine_strs_with_missing_comments(
                         context,
                         result.trim_end(),
-                        &mt.ty.rewrite(&context, shape)?,
+                        &mt.ty.rewrite(context, shape)?,
                         before_ty_span,
                         shape,
                         true,
@@ -738,7 +738,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
                     let budget = shape.width.checked_sub(used_width)?;
                     let ty_str = mt
                         .ty
-                        .rewrite(&context, Shape::legacy(budget, shape.indent + used_width))?;
+                        .rewrite(context, Shape::legacy(budget, shape.indent + used_width))?;
                     result.push_str(&ty_str);
                 }
 
index 29e1e070d41114079921683fea87f7cd62ec941f..3a8713c5bdb01d678f41892a2a149ee8946e8575 100644 (file)
@@ -42,7 +42,7 @@ pub(crate) fn is_same_visibility(a: &Visibility, b: &Visibility) -> bool {
         (
             VisibilityKind::Restricted { path: p, .. },
             VisibilityKind::Restricted { path: q, .. },
-        ) => pprust::path_to_string(&p) == pprust::path_to_string(&q),
+        ) => pprust::path_to_string(p) == pprust::path_to_string(q),
         (VisibilityKind::Public, VisibilityKind::Public)
         | (VisibilityKind::Inherited, VisibilityKind::Inherited)
         | (
@@ -689,7 +689,7 @@ mod test {
     #[test]
     fn test_remove_trailing_white_spaces() {
         let s = "    r#\"\n        test\n    \"#";
-        assert_eq!(remove_trailing_white_spaces(&s), s);
+        assert_eq!(remove_trailing_white_spaces(s), s);
     }
 
     #[test]
@@ -698,7 +698,7 @@ fn test_trim_left_preserve_layout() {
         let config = Config::default();
         let indent = Indent::new(4, 0);
         assert_eq!(
-            trim_left_preserve_layout(&s, indent, &config),
+            trim_left_preserve_layout(s, indent, &config),
             Some("aaa\n    bbb\n    ccc".to_string())
         );
     }
index d854d90b40b6d9d33e7f7ff4917d8c872c97f6a5..527042d098a1c61f7d6252438ea4b97ba741c5d7 100644 (file)
@@ -12,8 +12,7 @@
 use crate::coverage::transform_missing_snippet;
 use crate::items::{
     format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate,
-    rewrite_impl_type, rewrite_opaque_type, rewrite_type, FnBraceStyle, FnSig, StaticParts,
-    StructParts,
+    rewrite_type_alias, FnBraceStyle, FnSig, ItemVisitorKind, StaticParts, StructParts,
 };
 use crate::macros::{macro_style, rewrite_macro, rewrite_macro_def, MacroPosition};
 use crate::modules::Module;
@@ -164,7 +163,7 @@ fn visit_stmt(&mut self, stmt: &Stmt<'_>, include_empty_semi: bool) {
                     );
                 } else {
                     let shape = self.shape();
-                    let rewrite = self.with_context(|ctx| stmt.rewrite(&ctx, shape));
+                    let rewrite = self.with_context(|ctx| stmt.rewrite(ctx, shape));
                     self.push_rewrite(stmt.span(), rewrite)
                 }
             }
@@ -273,9 +272,9 @@ fn close_block(&mut self, span: Span, unindent_comment: bool) {
 
         let comment_snippet = self.snippet(span);
 
-        let align_to_right = if unindent_comment && contains_comment(&comment_snippet) {
+        let align_to_right = if unindent_comment && contains_comment(comment_snippet) {
             let first_lines = comment_snippet.splitn(2, '/').next().unwrap_or("");
-            last_line_width(first_lines) > last_line_width(&comment_snippet)
+            last_line_width(first_lines) > last_line_width(comment_snippet)
         } else {
             false
         };
@@ -439,7 +438,7 @@ pub(crate) fn visit_item(&mut self, item: &ast::Item) {
         let filtered_attrs;
         let mut attrs = &item.attrs;
         let skip_context_saved = self.skip_context.clone();
-        self.skip_context.update_with_attrs(&attrs);
+        self.skip_context.update_with_attrs(attrs);
 
         let should_visit_node_again = match item.kind {
             // For use/extern crate items, skip rewriting attributes but check for a skip attribute.
@@ -488,12 +487,12 @@ pub(crate) fn visit_item(&mut self, item: &ast::Item) {
                 ast::ItemKind::Use(ref tree) => self.format_import(item, tree),
                 ast::ItemKind::Impl { .. } => {
                     let block_indent = self.block_indent;
-                    let rw = self.with_context(|ctx| format_impl(&ctx, item, block_indent));
+                    let rw = self.with_context(|ctx| format_impl(ctx, item, block_indent));
                     self.push_rewrite(item.span, rw);
                 }
                 ast::ItemKind::Trait(..) => {
                     let block_indent = self.block_indent;
-                    let rw = self.with_context(|ctx| format_trait(&ctx, item, block_indent));
+                    let rw = self.with_context(|ctx| format_trait(ctx, item, block_indent));
                     self.push_rewrite(item.span, rw);
                 }
                 ast::ItemKind::TraitAlias(ref generics, ref generic_bounds) => {
@@ -540,24 +539,22 @@ pub(crate) fn visit_item(&mut self, item: &ast::Item) {
                     self.visit_static(&StaticParts::from_item(item));
                 }
                 ast::ItemKind::Fn(ref fn_kind) => {
-                    let ast::FnKind(defaultness, ref fn_signature, ref generics, ref block) =
-                        **fn_kind;
-                    if let Some(ref body) = block {
+                    let ast::Fn {
+                        defaultness,
+                        ref sig,
+                        ref generics,
+                        ref body,
+                    } = **fn_kind;
+                    if let Some(ref body) = body {
                         let inner_attrs = inner_attributes(&item.attrs);
-                        let fn_ctxt = match fn_signature.header.ext {
+                        let fn_ctxt = match sig.header.ext {
                             ast::Extern::None => visit::FnCtxt::Free,
                             _ => visit::FnCtxt::Foreign,
                         };
                         self.visit_fn(
-                            visit::FnKind::Fn(
-                                fn_ctxt,
-                                item.ident,
-                                &fn_signature,
-                                &item.vis,
-                                Some(body),
-                            ),
+                            visit::FnKind::Fn(fn_ctxt, item.ident, &sig, &item.vis, Some(body)),
                             generics,
-                            &fn_signature.decl,
+                            &sig.decl,
                             item.span,
                             defaultness,
                             Some(&inner_attrs),
@@ -565,46 +562,14 @@ pub(crate) fn visit_item(&mut self, item: &ast::Item) {
                     } else {
                         let indent = self.block_indent;
                         let rewrite = self.rewrite_required_fn(
-                            indent,
-                            item.ident,
-                            &fn_signature,
-                            &item.vis,
-                            generics,
-                            item.span,
+                            indent, item.ident, &sig, &item.vis, generics, item.span,
                         );
                         self.push_rewrite(item.span, rewrite);
                     }
                 }
-                ast::ItemKind::TyAlias(ref alias_kind) => {
-                    let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref ty) =
-                        **alias_kind;
-                    match ty {
-                        Some(ty) => {
-                            let rewrite = rewrite_type(
-                                &self.get_context(),
-                                self.block_indent,
-                                item.ident,
-                                &item.vis,
-                                generics,
-                                Some(generic_bounds),
-                                Some(&*ty),
-                                item.span,
-                            );
-                            self.push_rewrite(item.span, rewrite);
-                        }
-                        None => {
-                            let rewrite = rewrite_opaque_type(
-                                &self.get_context(),
-                                self.block_indent,
-                                item.ident,
-                                generic_bounds,
-                                generics,
-                                &item.vis,
-                                item.span,
-                            );
-                            self.push_rewrite(item.span, rewrite);
-                        }
-                    }
+                ast::ItemKind::TyAlias(ref ty_alias) => {
+                    use ItemVisitorKind::Item;
+                    self.visit_ty_alias_kind(ty_alias, &Item(&item), item.span);
                 }
                 ast::ItemKind::GlobalAsm(..) => {
                     let snippet = Some(self.snippet(item.span).to_owned());
@@ -627,108 +592,86 @@ pub(crate) fn visit_item(&mut self, item: &ast::Item) {
         self.skip_context = skip_context_saved;
     }
 
-    pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) {
-        skip_out_of_file_lines_range_visitor!(self, ti.span);
+    fn visit_ty_alias_kind(
+        &mut self,
+        ty_kind: &ast::TyAlias,
+        visitor_kind: &ItemVisitorKind<'_>,
+        span: Span,
+    ) {
+        let rewrite = rewrite_type_alias(
+            ty_kind,
+            &self.get_context(),
+            self.block_indent,
+            visitor_kind,
+            span,
+        );
+        self.push_rewrite(span, rewrite);
+    }
+
+    fn visit_assoc_item(&mut self, visitor_kind: &ItemVisitorKind<'_>) {
+        use ItemVisitorKind::*;
+        // TODO(calebcartwright): Not sure the skip spans are correct
+        let (ai, skip_span, assoc_ctxt) = match visitor_kind {
+            AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait),
+            AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl),
+            _ => unreachable!(),
+        };
+        skip_out_of_file_lines_range_visitor!(self, ai.span);
 
-        if self.visit_attrs(&ti.attrs, ast::AttrStyle::Outer) {
-            self.push_skipped_with_span(ti.attrs.as_slice(), ti.span(), ti.span());
+        if self.visit_attrs(&ai.attrs, ast::AttrStyle::Outer) {
+            self.push_skipped_with_span(&ai.attrs.as_slice(), skip_span, skip_span);
             return;
         }
 
         // TODO(calebcartwright): consider enabling box_patterns feature gate
-        match ti.kind {
-            ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_trait_item(ti)),
-            ast::AssocItemKind::Fn(ref fn_kind) => {
-                let ast::FnKind(defaultness, ref sig, ref generics, ref block) = **fn_kind;
-                if let Some(ref body) = block {
-                    let inner_attrs = inner_attributes(&ti.attrs);
-                    let fn_ctxt = visit::FnCtxt::Assoc(visit::AssocCtxt::Trait);
+        match (&ai.kind, visitor_kind) {
+            (ast::AssocItemKind::Const(..), AssocTraitItem(_)) => {
+                self.visit_static(&StaticParts::from_trait_item(&ai))
+            }
+            (ast::AssocItemKind::Const(..), AssocImplItem(_)) => {
+                self.visit_static(&StaticParts::from_impl_item(&ai))
+            }
+            (ast::AssocItemKind::Fn(ref fn_kind), _) => {
+                let ast::Fn {
+                    defaultness,
+                    ref sig,
+                    ref generics,
+                    ref body,
+                } = **fn_kind;
+                if let Some(ref body) = body {
+                    let inner_attrs = inner_attributes(&ai.attrs);
+                    let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt);
                     self.visit_fn(
-                        visit::FnKind::Fn(fn_ctxt, ti.ident, sig, &ti.vis, Some(body)),
+                        visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, Some(body)),
                         generics,
                         &sig.decl,
-                        ti.span,
+                        ai.span,
                         defaultness,
                         Some(&inner_attrs),
                     );
                 } else {
                     let indent = self.block_indent;
                     let rewrite =
-                        self.rewrite_required_fn(indent, ti.ident, sig, &ti.vis, generics, ti.span);
-                    self.push_rewrite(ti.span, rewrite);
+                        self.rewrite_required_fn(indent, ai.ident, sig, &ai.vis, generics, ai.span);
+                    self.push_rewrite(ai.span, rewrite);
                 }
             }
-            ast::AssocItemKind::TyAlias(ref ty_alias_kind) => {
-                let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) =
-                    **ty_alias_kind;
-                let rewrite = rewrite_type(
-                    &self.get_context(),
-                    self.block_indent,
-                    ti.ident,
-                    &ti.vis,
-                    generics,
-                    Some(generic_bounds),
-                    type_default.as_ref(),
-                    ti.span,
-                );
-                self.push_rewrite(ti.span, rewrite);
+            (ast::AssocItemKind::TyAlias(ref ty_alias), _) => {
+                self.visit_ty_alias_kind(ty_alias, visitor_kind, ai.span);
             }
-            ast::AssocItemKind::MacCall(ref mac) => {
-                self.visit_mac(mac, Some(ti.ident), MacroPosition::Item);
+            (ast::AssocItemKind::MacCall(ref mac), _) => {
+                self.visit_mac(mac, Some(ai.ident), MacroPosition::Item);
             }
+            _ => unreachable!(),
         }
     }
 
-    pub(crate) fn visit_impl_item(&mut self, ii: &ast::AssocItem) {
-        skip_out_of_file_lines_range_visitor!(self, ii.span);
-
-        if self.visit_attrs(&ii.attrs, ast::AttrStyle::Outer) {
-            self.push_skipped_with_span(ii.attrs.as_slice(), ii.span, ii.span);
-            return;
-        }
+    pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) {
+        self.visit_assoc_item(&ItemVisitorKind::AssocTraitItem(ti));
+    }
 
-        match ii.kind {
-            ast::AssocItemKind::Fn(ref fn_kind) => {
-                let ast::FnKind(defaultness, ref sig, ref generics, ref block) = **fn_kind;
-                if let Some(ref body) = block {
-                    let inner_attrs = inner_attributes(&ii.attrs);
-                    let fn_ctxt = visit::FnCtxt::Assoc(visit::AssocCtxt::Impl);
-                    self.visit_fn(
-                        visit::FnKind::Fn(fn_ctxt, ii.ident, sig, &ii.vis, Some(body)),
-                        generics,
-                        &sig.decl,
-                        ii.span,
-                        defaultness,
-                        Some(&inner_attrs),
-                    );
-                } else {
-                    let indent = self.block_indent;
-                    let rewrite =
-                        self.rewrite_required_fn(indent, ii.ident, sig, &ii.vis, generics, ii.span);
-                    self.push_rewrite(ii.span, rewrite);
-                }
-            }
-            ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)),
-            ast::AssocItemKind::TyAlias(ref ty_alias_kind) => {
-                let ast::TyAliasKind(defaultness, ref generics, _, ref ty) = **ty_alias_kind;
-                self.push_rewrite(
-                    ii.span,
-                    rewrite_impl_type(
-                        ii.ident,
-                        &ii.vis,
-                        defaultness,
-                        ty.as_ref(),
-                        &generics,
-                        &self.get_context(),
-                        self.block_indent,
-                        ii.span,
-                    ),
-                );
-            }
-            ast::AssocItemKind::MacCall(ref mac) => {
-                self.visit_mac(mac, Some(ii.ident), MacroPosition::Item);
-            }
-        }
+    pub(crate) fn visit_impl_item(&mut self, ii: &ast::AssocItem) {
+        self.visit_assoc_item(&ItemVisitorKind::AssocImplItem(ii));
     }
 
     fn visit_mac(&mut self, mac: &ast::MacCall, ident: Option<symbol::Ident>, pos: MacroPosition) {
@@ -905,7 +848,7 @@ fn is_unknown_rustfmt_attr(&self, segments: &[ast::PathSegment]) -> bool {
     }
 
     fn walk_mod_items(&mut self, items: &[rustc_ast::ptr::P<ast::Item>]) {
-        self.visit_items_with_reordering(&ptr_vec_to_ref_vec(&items));
+        self.visit_items_with_reordering(&ptr_vec_to_ref_vec(items));
     }
 
     fn walk_stmts(&mut self, stmts: &[Stmt<'_>], include_current_empty_semi: bool) {
diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo.rs
new file mode 100644 (file)
index 0000000..d569747
--- /dev/null
@@ -0,0 +1,2 @@
+mod bar {
+        mod baz;}
\ No newline at end of file
diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo/bar/baz.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5063/foo/bar/baz.rs
new file mode 100644 (file)
index 0000000..3519b0e
--- /dev/null
@@ -0,0 +1 @@
+fn    baz()    {       }
\ No newline at end of file
diff --git a/src/tools/rustfmt/tests/mod-resolver/issue-5063/main.rs b/src/tools/rustfmt/tests/mod-resolver/issue-5063/main.rs
new file mode 100644 (file)
index 0000000..41c81c7
--- /dev/null
@@ -0,0 +1,5 @@
+fn main() {
+    println!("Hello, world!");
+}
+
+mod foo;
\ No newline at end of file
diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/One-merge_imports.rs b/src/tools/rustfmt/tests/source/configs/group_imports/One-merge_imports.rs
new file mode 100644 (file)
index 0000000..157d385
--- /dev/null
@@ -0,0 +1,17 @@
+// rustfmt-group_imports: One
+// rustfmt-imports_granularity: Crate
+use chrono::Utc;
+use super::update::convert_publish_payload;
+
+use juniper::{FieldError, FieldResult};
+use uuid::Uuid;
+use alloc::alloc::Layout;
+
+use std::sync::Arc;
+use alloc::vec::Vec;
+
+use broker::database::PooledConnection;
+
+use super::schema::{Context, Payload};
+use core::f32;
+use crate::models::Event;
diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/One-nested.rs b/src/tools/rustfmt/tests/source/configs/group_imports/One-nested.rs
new file mode 100644 (file)
index 0000000..109bd07
--- /dev/null
@@ -0,0 +1,7 @@
+// rustfmt-group_imports: One
+mod test {
+    use crate::foo::bar;
+
+    use std::path;
+    use crate::foo::bar2;
+}
diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/One-no_reorder.rs b/src/tools/rustfmt/tests/source/configs/group_imports/One-no_reorder.rs
new file mode 100644 (file)
index 0000000..f82f62c
--- /dev/null
@@ -0,0 +1,16 @@
+// rustfmt-group_imports: One
+// rustfmt-reorder_imports: false
+use chrono::Utc;
+use super::update::convert_publish_payload;
+
+use juniper::{FieldError, FieldResult};
+use uuid::Uuid;
+use alloc::alloc::Layout;
+
+use std::sync::Arc;
+
+use broker::database::PooledConnection;
+
+use super::schema::{Context, Payload};
+use core::f32;
+use crate::models::Event;
diff --git a/src/tools/rustfmt/tests/source/configs/group_imports/One.rs b/src/tools/rustfmt/tests/source/configs/group_imports/One.rs
new file mode 100644 (file)
index 0000000..5ab7a95
--- /dev/null
@@ -0,0 +1,15 @@
+// rustfmt-group_imports: One
+use chrono::Utc;
+use super::update::convert_publish_payload;
+
+use juniper::{FieldError, FieldResult};
+use uuid::Uuid;
+use alloc::alloc::Layout;
+
+use std::sync::Arc;
+
+use broker::database::PooledConnection;
+
+use super::schema::{Context, Payload};
+use core::f32;
+use crate::models::Event;
diff --git a/src/tools/rustfmt/tests/source/empty-item-single-line-false.rs b/src/tools/rustfmt/tests/source/empty-item-single-line-false.rs
new file mode 100644 (file)
index 0000000..20c5bc8
--- /dev/null
@@ -0,0 +1,46 @@
+// rustfmt-brace_style: AlwaysNextLine
+// rustfmt-empty_item_single_line: false
+
+fn function()
+{
+
+}
+
+struct Struct
+{
+
+}
+
+enum Enum
+{
+
+}
+
+trait Trait
+{
+
+}
+
+impl<T> Trait for T
+{
+
+}
+
+trait Trait2<T>
+where
+    T: Copy + Display + Write + Read + FromStr, {}
+
+trait Trait3<T>
+where
+    T: Something
+        + SomethingElse
+        + Sync
+        + Send
+        + Display
+        + Debug
+        + Copy
+        + Hash
+        + Debug
+        + Display
+        + Write
+        + Read, {}
index 38094d67a77374b289a06cae9e0fbdf5e49c29a8..0fb6405120aa7c5d7205c3bd6b126383ac36d1c2 100644 (file)
@@ -27,3 +27,38 @@ enum C<T> where T: Copy {}
 
     struct D<T> where T: Copy {}
 }
+
+
+fn function()
+{
+
+}
+
+trait Trait
+{
+
+}
+
+impl<T> Trait for T
+{
+
+}
+
+trait Trait2<T>
+where
+    T: Copy + Display + Write + Read + FromStr, {}
+
+trait Trait3<T>
+where
+    T: Something
+        + SomethingElse
+        + Sync
+        + Send
+        + Display
+        + Debug
+        + Copy
+        + Hash
+        + Debug
+        + Display
+        + Write
+        + Read, {}
diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/One-merge_imports.rs b/src/tools/rustfmt/tests/target/configs/group_imports/One-merge_imports.rs
new file mode 100644 (file)
index 0000000..52e0e1c
--- /dev/null
@@ -0,0 +1,14 @@
+// rustfmt-group_imports: One
+// rustfmt-imports_granularity: Crate
+use super::{
+    schema::{Context, Payload},
+    update::convert_publish_payload,
+};
+use crate::models::Event;
+use alloc::{alloc::Layout, vec::Vec};
+use broker::database::PooledConnection;
+use chrono::Utc;
+use core::f32;
+use juniper::{FieldError, FieldResult};
+use std::sync::Arc;
+use uuid::Uuid;
diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/One-nested.rs b/src/tools/rustfmt/tests/target/configs/group_imports/One-nested.rs
new file mode 100644 (file)
index 0000000..5b64854
--- /dev/null
@@ -0,0 +1,6 @@
+// rustfmt-group_imports: One
+mod test {
+    use crate::foo::bar;
+    use crate::foo::bar2;
+    use std::path;
+}
diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/One-no_reorder.rs b/src/tools/rustfmt/tests/target/configs/group_imports/One-no_reorder.rs
new file mode 100644 (file)
index 0000000..015e841
--- /dev/null
@@ -0,0 +1,12 @@
+// rustfmt-group_imports: One
+// rustfmt-reorder_imports: false
+use chrono::Utc;
+use super::update::convert_publish_payload;
+use juniper::{FieldError, FieldResult};
+use uuid::Uuid;
+use alloc::alloc::Layout;
+use std::sync::Arc;
+use broker::database::PooledConnection;
+use super::schema::{Context, Payload};
+use core::f32;
+use crate::models::Event;
diff --git a/src/tools/rustfmt/tests/target/configs/group_imports/One.rs b/src/tools/rustfmt/tests/target/configs/group_imports/One.rs
new file mode 100644 (file)
index 0000000..3094c7a
--- /dev/null
@@ -0,0 +1,11 @@
+// rustfmt-group_imports: One
+use super::schema::{Context, Payload};
+use super::update::convert_publish_payload;
+use crate::models::Event;
+use alloc::alloc::Layout;
+use broker::database::PooledConnection;
+use chrono::Utc;
+use core::f32;
+use juniper::{FieldError, FieldResult};
+use std::sync::Arc;
+use uuid::Uuid;
diff --git a/src/tools/rustfmt/tests/target/empty-item-single-line-false.rs b/src/tools/rustfmt/tests/target/empty-item-single-line-false.rs
new file mode 100644 (file)
index 0000000..bf7f70e
--- /dev/null
@@ -0,0 +1,41 @@
+// rustfmt-brace_style: AlwaysNextLine
+// rustfmt-empty_item_single_line: false
+
+fn function()
+{
+}
+
+struct Struct {}
+
+enum Enum {}
+
+trait Trait
+{
+}
+
+impl<T> Trait for T
+{
+}
+
+trait Trait2<T>
+where
+    T: Copy + Display + Write + Read + FromStr,
+{
+}
+
+trait Trait3<T>
+where
+    T: Something
+        + SomethingElse
+        + Sync
+        + Send
+        + Display
+        + Debug
+        + Copy
+        + Hash
+        + Debug
+        + Display
+        + Write
+        + Read,
+{
+}
diff --git a/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_always.rs b/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_always.rs
new file mode 100644 (file)
index 0000000..ff9c40f
--- /dev/null
@@ -0,0 +1,8 @@
+// rustfmt-trailing_comma: Always
+
+pub struct Matrix<T, const R: usize, const C: usize,>
+where
+    [T; R * C]:,
+{
+    contents: [T; R * C],
+}
diff --git a/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_never.rs b/src/tools/rustfmt/tests/target/issue-5012/trailing_comma_never.rs
new file mode 100644 (file)
index 0000000..2fac8ea
--- /dev/null
@@ -0,0 +1,8 @@
+// rustfmt-trailing_comma: Never
+
+pub struct Matrix<T, const R: usize, const C: usize>
+where
+    [T; R * C]:
+{
+    contents: [T; R * C]
+}
diff --git a/src/tools/rustfmt/tests/target/issue-5033/minimum_example.rs b/src/tools/rustfmt/tests/target/issue-5033/minimum_example.rs
new file mode 100644 (file)
index 0000000..0e7df41
--- /dev/null
@@ -0,0 +1,8 @@
+// leading comment
+
+#![rustfmt::skip]
+fn main() {
+    println!("main"); // commented
+}
+
+// post comment
diff --git a/src/tools/rustfmt/tests/target/issue-5033/nested_modules.rs b/src/tools/rustfmt/tests/target/issue-5033/nested_modules.rs
new file mode 100644 (file)
index 0000000..7a11133
--- /dev/null
@@ -0,0 +1,11 @@
+#![rustfmt::skip]
+
+mod a {
+    mod b {
+
+    }
+
+    // trailing comment b
+}
+
+// trailing comment a
diff --git a/src/tools/rustfmt/tests/target/issue_4850.rs b/src/tools/rustfmt/tests/target/issue_4850.rs
new file mode 100644 (file)
index 0000000..7d4da90
--- /dev/null
@@ -0,0 +1,4 @@
+impl ThisIsALongStructNameToPushTheWhereToWrapLolololol where
+    [(); this_is_a_long_const_function_name()]:
+{
+}
index 531ac59868314054c6ef5d36707f7f08f64613b7..4935fac04f1111cec322b7443c9f7b58c2677eef 100644 (file)
@@ -40,3 +40,32 @@ struct D<T>
     where
         T: Copy, {}
 }
+
+fn function() {}
+
+trait Trait {}
+
+impl<T> Trait for T {}
+
+trait Trait2<T>
+where
+    T: Copy + Display + Write + Read + FromStr,
+{
+}
+
+trait Trait3<T>
+where
+    T: Something
+        + SomethingElse
+        + Sync
+        + Send
+        + Display
+        + Debug
+        + Copy
+        + Hash
+        + Debug
+        + Display
+        + Write
+        + Read,
+{
+}
index 338dfd11310aaa0e17d14ac63ef5b115dc00ceff..129237775fe3f803c561c47886048987a92a4170 100644 (file)
@@ -97,6 +97,7 @@ pub fn check(
             &src_path.join("test/ui"),
             &src_path.join("test/ui-fulldeps"),
             &src_path.join("test/rustdoc-ui"),
+            &src_path.join("test/rustdoc"),
         ],
         &mut |path| super::filter_dirs(path),
         &mut |entry, contents| {
index 4afa36502aca1c063e2caec6a225df919a7e0c5d..88ede45655c94411b89b3bc110c3879279d00ede 100644 (file)
@@ -7,8 +7,8 @@
 
 const ENTRY_LIMIT: usize = 1000;
 // FIXME: The following limits should be reduced eventually.
-const ROOT_ENTRY_LIMIT: usize = 1331;
-const ISSUES_ENTRY_LIMIT: usize = 2488;
+const ROOT_ENTRY_LIMIT: usize = 1275;
+const ISSUES_ENTRY_LIMIT: usize = 2310;
 
 fn check_entries(path: &Path, bad: &mut bool) {
     let dirs = walkdir::WalkDir::new(&path.join("test/ui"))
index 48c7a00de7830c83e4659f49f35358049949fea1..7a9908fe8c0758fcc3047c04b21aa786741d0468 100644 (file)
@@ -2,6 +2,8 @@
 allow-unauthenticated = [
     "C-*", "A-*", "E-*", "NLL-*", "O-*", "S-*", "T-*", "WG-*", "F-*",
     "D-*",
+    "needs-fcp",
+    "relnotes",
     "requires-nightly",
     "regression-*",
     "perf-*",