]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #100559 - nnethercote:parser-simplifications, r=compiler-errors
authorMatthias Krüger <matthias.krueger@famsik.de>
Mon, 15 Aug 2022 18:11:38 +0000 (20:11 +0200)
committerGitHub <noreply@github.com>
Mon, 15 Aug 2022 18:11:38 +0000 (20:11 +0200)
Parser simplifications

Best reviewed one commit at a time.

r? ``@compiler-errors``

485 files changed:
Cargo.lock
RELEASES.md
compiler/rustc_ast/src/lib.rs
compiler/rustc_ast_lowering/src/expr.rs
compiler/rustc_ast_lowering/src/index.rs
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_ast_lowering/src/pat.rs
compiler/rustc_ast_passes/src/lib.rs
compiler/rustc_attr/src/lib.rs
compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
compiler/rustc_borrowck/src/lib.rs
compiler/rustc_builtin_macros/src/format.rs
compiler/rustc_builtin_macros/src/lib.rs
compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
compiler/rustc_codegen_llvm/src/lib.rs
compiler/rustc_codegen_llvm/src/llvm/ffi.rs
compiler/rustc_codegen_ssa/src/back/link.rs
compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
compiler/rustc_codegen_ssa/src/target_features.rs
compiler/rustc_const_eval/src/const_eval/machine.rs
compiler/rustc_const_eval/src/interpret/machine.rs
compiler/rustc_const_eval/src/interpret/validity.rs
compiler/rustc_const_eval/src/lib.rs
compiler/rustc_const_eval/src/transform/promote_consts.rs
compiler/rustc_error_messages/locales/en-US/borrowck.ftl
compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
compiler/rustc_error_messages/locales/en-US/const_eval.ftl
compiler/rustc_error_messages/locales/en-US/expand.ftl
compiler/rustc_error_messages/locales/en-US/lint.ftl
compiler/rustc_error_messages/locales/en-US/parser.ftl
compiler/rustc_error_messages/locales/en-US/passes.ftl
compiler/rustc_error_messages/locales/en-US/privacy.ftl
compiler/rustc_error_messages/locales/en-US/typeck.ftl
compiler/rustc_error_messages/src/lib.rs
compiler/rustc_errors/src/emitter.rs
compiler/rustc_errors/src/lib.rs
compiler/rustc_expand/src/lib.rs
compiler/rustc_hir/src/hir.rs
compiler/rustc_hir/src/intravisit.rs
compiler/rustc_hir/src/target.rs
compiler/rustc_hir_pretty/src/lib.rs
compiler/rustc_index/src/vec.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/error_reporting/note.rs
compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_infer/src/lib.rs
compiler/rustc_interface/src/interface.rs
compiler/rustc_interface/src/tests.rs
compiler/rustc_interface/src/util.rs
compiler/rustc_lint/src/early.rs
compiler/rustc_lint/src/levels.rs
compiler/rustc_lint/src/lib.rs
compiler/rustc_lint/src/nonstandard_style.rs
compiler/rustc_lint/src/types.rs
compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
compiler/rustc_macros/src/diagnostics/fluent.rs
compiler/rustc_macros/src/diagnostics/mod.rs
compiler/rustc_macros/src/lib.rs
compiler/rustc_metadata/src/lib.rs
compiler/rustc_middle/src/hir/map/mod.rs
compiler/rustc_middle/src/lib.rs
compiler/rustc_middle/src/ty/error.rs
compiler/rustc_mir_build/src/lib.rs
compiler/rustc_mir_transform/src/const_prop.rs
compiler/rustc_mir_transform/src/lib.rs
compiler/rustc_monomorphize/src/collector.rs
compiler/rustc_parse/src/lib.rs
compiler/rustc_parse/src/parser/diagnostics.rs
compiler/rustc_parse/src/parser/expr.rs
compiler/rustc_parse/src/parser/item.rs
compiler/rustc_parse/src/parser/stmt.rs
compiler/rustc_passes/src/check_attr.rs
compiler/rustc_passes/src/lib.rs
compiler/rustc_passes/src/liveness.rs
compiler/rustc_passes/src/stability.rs
compiler/rustc_privacy/src/lib.rs
compiler/rustc_resolve/src/late/diagnostics.rs
compiler/rustc_resolve/src/lib.rs
compiler/rustc_session/src/config.rs
compiler/rustc_session/src/lib.rs
compiler/rustc_session/src/options.rs
compiler/rustc_session/src/session.rs
compiler/rustc_span/src/source_map.rs
compiler/rustc_target/src/spec/crt_objects.rs
compiler/rustc_target/src/spec/linux_musl_base.rs
compiler/rustc_target/src/spec/mod.rs
compiler/rustc_target/src/spec/tests/tests_impl.rs
compiler/rustc_target/src/spec/wasm32_wasi.rs
compiler/rustc_target/src/spec/wasm_base.rs
compiler/rustc_target/src/spec/windows_gnu_base.rs
compiler/rustc_trait_selection/src/lib.rs
compiler/rustc_trait_selection/src/traits/coherence.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/wf.rs
compiler/rustc_typeck/src/astconv/mod.rs
compiler/rustc_typeck/src/check/compare_method.rs
compiler/rustc_typeck/src/check/demand.rs
compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
compiler/rustc_typeck/src/check/intrinsic.rs
compiler/rustc_typeck/src/check/intrinsicck.rs
compiler/rustc_typeck/src/check/pat.rs
compiler/rustc_typeck/src/check/writeback.rs
compiler/rustc_typeck/src/lib.rs
library/alloc/src/alloc.rs
library/core/src/alloc/global.rs
library/core/src/fmt/mod.rs
library/core/src/hash/mod.rs
library/core/src/intrinsics.rs
library/core/src/iter/adapters/array_chunks.rs [new file with mode: 0644]
library/core/src/iter/adapters/mod.rs
library/core/src/iter/adapters/skip.rs
library/core/src/iter/mod.rs
library/core/src/iter/traits/iterator.rs
library/core/src/mem/transmutability.rs
library/core/src/primitive_docs.rs
library/core/src/ptr/const_ptr.rs
library/core/src/ptr/metadata.rs
library/core/src/ptr/mod.rs
library/core/src/ptr/mut_ptr.rs
library/core/src/slice/iter.rs
library/core/src/slice/mod.rs
library/core/src/sync/atomic.rs
library/core/src/tuple.rs
library/core/tests/const_ptr.rs
library/core/tests/iter/adapters/array_chunks.rs [new file with mode: 0644]
library/core/tests/iter/adapters/mod.rs
library/core/tests/iter/adapters/skip.rs
library/core/tests/lib.rs
library/std/src/lib.rs
library/std/src/os/fd/raw.rs
library/std/src/primitive_docs.rs
library/std/src/sys/sgx/abi/usercalls/alloc.rs
library/std/src/sys/unix/fs.rs
library/std/src/sys/unix/locks/pthread_condvar.rs
library/std/src/sys/unsupported/alloc.rs
library/std/src/sys_common/thread_local_key/tests.rs
library/std/src/thread/mod.rs
src/bootstrap/compile.rs
src/bootstrap/config.rs
src/bootstrap/flags.rs
src/bootstrap/mk/Makefile.in
src/bootstrap/setup.rs
src/ci/docker/host-x86_64/x86_64-gnu-llvm-12/Dockerfile
src/doc/rustc/src/platform-support/fuchsia.md
src/etc/check_missing_items.py
src/etc/htmldocck.py
src/etc/natvis/intrinsic.natvis
src/etc/natvis/liballoc.natvis
src/librustdoc/clean/mod.rs
src/librustdoc/clean/types.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/highlight/fixtures/decorations.html
src/librustdoc/html/highlight/fixtures/dos_line.html
src/librustdoc/html/highlight/fixtures/highlight.html
src/librustdoc/html/highlight/fixtures/sample.html
src/librustdoc/html/highlight/fixtures/union.html
src/librustdoc/html/render/context.rs
src/librustdoc/html/render/mod.rs
src/librustdoc/html/sources.rs
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/json/conversions.rs
src/librustdoc/lib.rs
src/librustdoc/passes/calculate_doc_coverage.rs
src/librustdoc/passes/stripper.rs
src/rustdoc-json-types/lib.rs
src/stage0.json
src/test/codegen/async-fn-debug-awaitee-field.rs
src/test/codegen/async-fn-debug-msvc.rs
src/test/codegen/debug-vtable.rs
src/test/codegen/generator-debug-msvc.rs
src/test/debuginfo/generator-objects.rs
src/test/debuginfo/msvc-pretty-enums.rs
src/test/debuginfo/msvc-scalarpair-params.rs
src/test/debuginfo/mutex.rs
src/test/debuginfo/pretty-std.rs
src/test/debuginfo/result-types.rs
src/test/debuginfo/type-names.rs
src/test/run-make/issue-85401-static-mir/Makefile [new file with mode: 0644]
src/test/run-make/issue-85401-static-mir/bar.rs [new file with mode: 0644]
src/test/run-make/issue-85401-static-mir/baz.rs [new file with mode: 0644]
src/test/run-make/issue-85401-static-mir/foo.rs [new file with mode: 0644]
src/test/run-make/translation/Makefile
src/test/run-make/translation/basic-translation.ftl [deleted file]
src/test/run-make/translation/basic-translation.rs [deleted file]
src/test/run-make/translation/broken.ftl [new file with mode: 0644]
src/test/run-make/translation/missing.ftl [new file with mode: 0644]
src/test/run-make/translation/test.rs [new file with mode: 0644]
src/test/run-make/translation/working.ftl [new file with mode: 0644]
src/test/rustdoc-json/fns/generic_args.rs
src/test/rustdoc-json/fns/generic_returns.rs
src/test/rustdoc-json/fns/generics.rs
src/test/rustdoc-json/impls/auto.rs [new file with mode: 0644]
src/test/rustdoc-json/impls/import_from_private.rs [new file with mode: 0644]
src/test/rustdoc-json/traits/supertrait.rs
src/test/rustdoc-json/type/dyn.rs
src/test/rustdoc-json/type/hrtb.rs
src/test/rustdoc-ui/z-help.stdout
src/test/rustdoc/all.rs
src/test/rustdoc/assoc-consts.rs
src/test/rustdoc/const-display.rs
src/test/rustdoc/deprecated-impls.rs
src/test/rustdoc/elided-lifetime.rs
src/test/rustdoc/empty-mod-private.rs
src/test/rustdoc/empty-mod-public.rs
src/test/rustdoc/empty-section.rs
src/test/rustdoc/generic-associated-types/issue-94683.rs
src/test/rustdoc/hidden-impls.rs
src/test/rustdoc/hidden-line.rs
src/test/rustdoc/hidden-methods.rs
src/test/rustdoc/hide-unstable-trait.rs
src/test/rustdoc/impl-parts-crosscrate.rs
src/test/rustdoc/impl-trait-alias.rs
src/test/rustdoc/inline_cross/add-docs.rs
src/test/rustdoc/inline_cross/assoc-items.rs
src/test/rustdoc/inline_cross/hidden-use.rs
src/test/rustdoc/inline_cross/proc_macro.rs
src/test/rustdoc/inline_local/glob-extern-document-private-items.rs
src/test/rustdoc/inline_local/glob-extern.rs
src/test/rustdoc/inline_local/glob-private-document-private-items.rs
src/test/rustdoc/inline_local/glob-private.rs
src/test/rustdoc/inline_local/hidden-use.rs
src/test/rustdoc/inline_local/macro_by_example.rs
src/test/rustdoc/inline_local/please_inline.rs
src/test/rustdoc/internal.rs
src/test/rustdoc/intra-doc/extern-type.rs
src/test/rustdoc/issue-16265-1.rs
src/test/rustdoc/issue-16265-2.rs
src/test/rustdoc/issue-23511.rs
src/test/rustdoc/issue-23812.rs
src/test/rustdoc/issue-27104.rs
src/test/rustdoc/issue-27759.rs
src/test/rustdoc/issue-29584.rs
src/test/rustdoc/issue-31899.rs
src/test/rustdoc/issue-32374.rs
src/test/rustdoc/issue-32395.rs
src/test/rustdoc/issue-34473.rs
src/test/rustdoc/issue-41783.codeblock.html [new file with mode: 0644]
src/test/rustdoc/issue-41783.rs
src/test/rustdoc/issue-53689.rs
src/test/rustdoc/issue-61592.rs
src/test/rustdoc/issue-89852.rs
src/test/rustdoc/link-title-escape.rs
src/test/rustdoc/macro-document-private-duplicate.rs
src/test/rustdoc/macro-private-not-documented.rs
src/test/rustdoc/macro_rules-matchers.rs
src/test/rustdoc/markdown-summaries.rs
src/test/rustdoc/masked.rs
src/test/rustdoc/module-impls.rs
src/test/rustdoc/nested-modules.rs
src/test/rustdoc/no-crate-filter.rs
src/test/rustdoc/recursive-deref.rs
src/test/rustdoc/remove-url-from-headings.rs
src/test/rustdoc/search-index-summaries.rs
src/test/rustdoc/search-index.rs
src/test/rustdoc/show-const-contents.rs
src/test/rustdoc/sized_trait.rs
src/test/rustdoc/sort-modules-by-appearance.rs
src/test/rustdoc/source-file.rs
src/test/rustdoc/static-root-path.rs
src/test/rustdoc/table-in-docblock.rs
src/test/rustdoc/toggle-item-contents.rs
src/test/rustdoc/trait-impl-items-links-and-anchors.rs
src/test/rustdoc/trait-impl.rs
src/test/rustdoc/tuple-struct-fields-doc.rs
src/test/rustdoc/type-layout-flag-required.rs
src/test/rustdoc/type-layout.rs
src/test/rustdoc/typedef.rs
src/test/rustdoc/universal-impl-trait.rs
src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl [new file with mode: 0644]
src/test/ui-fulldeps/fluent-messages/missing-message.ftl
src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl [new file with mode: 0644]
src/test/ui-fulldeps/fluent-messages/test.rs
src/test/ui-fulldeps/fluent-messages/test.stderr
src/test/ui/argument-suggestions/complex.stderr
src/test/ui/argument-suggestions/invalid_arguments.stderr
src/test/ui/argument-suggestions/issue-96638.stderr
src/test/ui/argument-suggestions/issue-97484.stderr
src/test/ui/argument-suggestions/too-long.rs [new file with mode: 0644]
src/test/ui/argument-suggestions/too-long.stderr [new file with mode: 0644]
src/test/ui/argument-suggestions/two-mismatch-notes.rs [new file with mode: 0644]
src/test/ui/argument-suggestions/two-mismatch-notes.stderr [new file with mode: 0644]
src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr
src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
src/test/ui/associated-types/associated-types-eq-3.stderr
src/test/ui/associated-types/associated-types-eq-hr.stderr
src/test/ui/associated-types/associated-types-issue-20346.stderr
src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
src/test/ui/associated-types/associated-types-path-2.stderr
src/test/ui/associated-types/issue-22560.stderr
src/test/ui/associated-types/issue-87261.stderr
src/test/ui/async-await/generator-desc.stderr
src/test/ui/c-variadic/issue-86053-1.stderr
src/test/ui/closures/binder/disallow-const.rs [new file with mode: 0644]
src/test/ui/closures/binder/disallow-const.stderr [new file with mode: 0644]
src/test/ui/closures/binder/disallow-ty.rs [new file with mode: 0644]
src/test/ui/closures/binder/disallow-ty.stderr [new file with mode: 0644]
src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
src/test/ui/coercion/coerce-to-bang.stderr
src/test/ui/coherence/auxiliary/trait-with-const-param.rs [new file with mode: 0644]
src/test/ui/coherence/const-generics-orphan-check-ok.rs [new file with mode: 0644]
src/test/ui/coherence/issue-100191-2.rs [new file with mode: 0644]
src/test/ui/coherence/issue-100191-2.stderr [new file with mode: 0644]
src/test/ui/coherence/issue-100191.rs [new file with mode: 0644]
src/test/ui/coherence/issue-100191.stderr [new file with mode: 0644]
src/test/ui/const-generics/generic_const_exprs/issue-100360.rs [new file with mode: 0644]
src/test/ui/const-generics/generic_const_exprs/issue-89851.rs [new file with mode: 0644]
src/test/ui/consts/assert-type-intrinsics.rs
src/test/ui/consts/assert-type-intrinsics.stderr
src/test/ui/consts/extra-const-ub/detect-extra-ub.rs [new file with mode: 0644]
src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr [new file with mode: 0644]
src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs
src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr
src/test/ui/drop/drop_order.rs [new file with mode: 0644]
src/test/ui/error-codes/E0271.stderr
src/test/ui/fn/fn-item-type.stderr
src/test/ui/generic-associated-types/issue-74684-2.stderr
src/test/ui/higher-rank-trait-bounds/complex.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/due-to-where-clause.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/due-to-where-clause.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-30786.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-30786.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-46989.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-46989.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-57639.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-58451.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-58451.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-88446.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-90177.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-95034.rs [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-95034.stderr [new file with mode: 0644]
src/test/ui/higher-rank-trait-bounds/issue-95230.rs [new file with mode: 0644]
src/test/ui/hrtb/complex.rs [deleted file]
src/test/ui/hrtb/due-to-where-clause.rs [deleted file]
src/test/ui/hrtb/due-to-where-clause.stderr [deleted file]
src/test/ui/hrtb/hrtb-cache-issue-54302.rs [deleted file]
src/test/ui/hrtb/hrtb-cache-issue-54302.stderr [deleted file]
src/test/ui/hrtb/hrtb-conflate-regions.rs [deleted file]
src/test/ui/hrtb/hrtb-conflate-regions.stderr [deleted file]
src/test/ui/hrtb/hrtb-debruijn-in-receiver.rs [deleted file]
src/test/ui/hrtb/hrtb-debruijn-in-receiver.stderr [deleted file]
src/test/ui/hrtb/hrtb-exists-forall-fn.rs [deleted file]
src/test/ui/hrtb/hrtb-exists-forall-fn.stderr [deleted file]
src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs [deleted file]
src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr [deleted file]
src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs [deleted file]
src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs [deleted file]
src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr [deleted file]
src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs [deleted file]
src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr [deleted file]
src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs [deleted file]
src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr [deleted file]
src/test/ui/hrtb/hrtb-identity-fn-borrows.rs [deleted file]
src/test/ui/hrtb/hrtb-identity-fn-borrows.stderr [deleted file]
src/test/ui/hrtb/hrtb-just-for-static.rs [deleted file]
src/test/ui/hrtb/hrtb-just-for-static.stderr [deleted file]
src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr [deleted file]
src/test/ui/hrtb/hrtb-perfect-forwarding.rs [deleted file]
src/test/ui/hrtb/hrtb-perfect-forwarding.stderr [deleted file]
src/test/ui/hrtb/issue-30786.rs [deleted file]
src/test/ui/hrtb/issue-30786.stderr [deleted file]
src/test/ui/hrtb/issue-46989.rs [deleted file]
src/test/ui/hrtb/issue-46989.stderr [deleted file]
src/test/ui/hrtb/issue-57639.rs [deleted file]
src/test/ui/hrtb/issue-58451.rs [deleted file]
src/test/ui/hrtb/issue-58451.stderr [deleted file]
src/test/ui/hrtb/issue-62203-hrtb-ice.rs [deleted file]
src/test/ui/hrtb/issue-62203-hrtb-ice.stderr [deleted file]
src/test/ui/hrtb/issue-88446.rs [deleted file]
src/test/ui/hrtb/issue-90177.rs [deleted file]
src/test/ui/hrtb/issue-95034.rs [deleted file]
src/test/ui/hrtb/issue-95034.stderr [deleted file]
src/test/ui/hrtb/issue-95230.rs [deleted file]
src/test/ui/intrinsics/const-eval-select-bad.stderr
src/test/ui/issues/issue-11374.stderr
src/test/ui/issues/issue-18819.stderr
src/test/ui/issues/issue-21950.stderr
src/test/ui/let-else/issue-94176.rs [new file with mode: 0644]
src/test/ui/let-else/issue-94176.stderr [new file with mode: 0644]
src/test/ui/let-else/let-else-then-diverge.rs [new file with mode: 0644]
src/test/ui/let-else/let-else-then-diverge.stderr [new file with mode: 0644]
src/test/ui/lint/lint-attr-everywhere-early.rs [new file with mode: 0644]
src/test/ui/lint/lint-attr-everywhere-early.stderr [new file with mode: 0644]
src/test/ui/lint/lint-attr-everywhere-late.rs [new file with mode: 0644]
src/test/ui/lint/lint-attr-everywhere-late.stderr [new file with mode: 0644]
src/test/ui/lint/unused/unused_attributes-must_use.rs
src/test/ui/lint/unused/unused_attributes-must_use.stderr
src/test/ui/methods/method-call-err-msg.stderr
src/test/ui/parser/issue-100197-mut-let.fixed [new file with mode: 0644]
src/test/ui/parser/issue-100197-mut-let.rs [new file with mode: 0644]
src/test/ui/parser/issue-100197-mut-let.stderr [new file with mode: 0644]
src/test/ui/parser/issue-99910-const-let-mutually-exclusive.fixed [new file with mode: 0644]
src/test/ui/parser/issue-99910-const-let-mutually-exclusive.rs [new file with mode: 0644]
src/test/ui/parser/issue-99910-const-let-mutually-exclusive.stderr [new file with mode: 0644]
src/test/ui/parser/struct-filed-with-attr.fixed [new file with mode: 0644]
src/test/ui/parser/struct-filed-with-attr.rs [new file with mode: 0644]
src/test/ui/parser/struct-filed-with-attr.stderr [new file with mode: 0644]
src/test/ui/parser/suggest-const-for-global-var.rs [new file with mode: 0644]
src/test/ui/parser/suggest-const-for-global-var.stderr [new file with mode: 0644]
src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed [new file with mode: 0644]
src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs [new file with mode: 0644]
src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-100365.rs [new file with mode: 0644]
src/test/ui/resolve/issue-100365.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-22692.rs
src/test/ui/resolve/issue-22692.stderr
src/test/ui/resolve/suggest-path-for-tuple-struct.stderr
src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs
src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
src/test/ui/sanitize/memory.rs
src/test/ui/span/issue-34264.stderr
src/test/ui/span/missing-unit-argument.stderr
src/test/ui/stability-attribute/auxiliary/ctor-stability.rs [new file with mode: 0644]
src/test/ui/stability-attribute/ctor-stability.rs [new file with mode: 0644]
src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
src/test/ui/suggestions/assoc-const-as-field.stderr
src/test/ui/suggestions/dont-try-removing-the-field.rs [new file with mode: 0644]
src/test/ui/suggestions/dont-try-removing-the-field.stderr [new file with mode: 0644]
src/test/ui/suggestions/suggest-ref-macro.stderr
src/test/ui/suggestions/try-removing-the-field.rs [new file with mode: 0644]
src/test/ui/suggestions/try-removing-the-field.stderr [new file with mode: 0644]
src/test/ui/traits/alias/generic-default-in-dyn.rs [new file with mode: 0644]
src/test/ui/traits/alias/generic-default-in-dyn.stderr [new file with mode: 0644]
src/test/ui/traits/alias/self-in-generics.rs [new file with mode: 0644]
src/test/ui/traits/alias/self-in-generics.stderr [new file with mode: 0644]
src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr
src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr
src/test/ui/traits/multidispatch-bad.stderr
src/test/ui/traits/object/enforce-supertrait-projection.stderr
src/test/ui/traits/pointee-tail-is-generic-errors.stderr
src/test/ui/traits/unspecified-self-in-trait-ref.rs [new file with mode: 0644]
src/test/ui/traits/unspecified-self-in-trait-ref.stderr [new file with mode: 0644]
src/test/ui/tuple/add-tuple-within-arguments.stderr
src/test/ui/tuple/wrong_argument_ice-3.stderr
src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr
src/test/ui/unpretty/pretty-let-else.rs [new file with mode: 0644]
src/test/ui/unpretty/pretty-let-else.stdout [new file with mode: 0644]
src/test/ui/unspecified-self-in-trait-ref.rs [deleted file]
src/test/ui/unspecified-self-in-trait-ref.stderr [deleted file]
src/tools/cargo
src/tools/clippy/clippy_dev/src/lib.rs
src/tools/clippy/clippy_lints/src/dereference.rs
src/tools/clippy/clippy_lints/src/lib.rs
src/tools/clippy/clippy_utils/src/lib.rs
src/tools/clippy/src/driver.rs
src/tools/compiletest/src/main.rs
src/tools/miri
src/tools/tidy/src/bins.rs
x [new file with mode: 0755]
x.ps1
x.py
x.sh [deleted file]

index 3dca4aa3c6d26f9c74386bd87e8e644ed68f44fb..b480c42fa82859a9c43526fd859b3c3aa58fdc32 100644 (file)
@@ -333,7 +333,6 @@ dependencies = [
  "cargo-util",
  "clap",
  "crates-io",
- "crossbeam-utils",
  "curl",
  "curl-sys",
  "env_logger 0.9.0",
@@ -357,7 +356,6 @@ dependencies = [
  "libgit2-sys",
  "log",
  "memchr",
- "num_cpus",
  "opener",
  "openssl",
  "os_info",
@@ -801,9 +799,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.78"
+version = "0.1.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "413b6b13f725a46cdec40364e0c1d564a22cf0aaac5f1e267a129d956478a6b4"
+checksum = "4f873ce2bd3550b0b565f878b3d04ea8253f4259dc3d20223af2e1ba86f5ecca"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
index e66bf60b7f781d665679169f17a76692f9933482..147ff3561a30bbac29174727bfb3b5a189e05b6b 100644 (file)
@@ -27,6 +27,7 @@ Libraries
 - [Extend `ptr::null` and `null_mut` to all thin (including extern) types.][94954]
 - [`impl Read and Write for VecDeque<u8>`.][95632]
 - [STD support for the Nintendo 3DS.][95897]
+- [Use rounding in float to Duration conversion methods.][96051]
 - [Make write/print macros eagerly drop temporaries.][96455]
 - [Implement internal traits that enable `[OsStr]::join`.][96881]
 - [Implement `Hash` for `core::alloc::Layout`.][97034]
@@ -99,6 +100,8 @@ Compatibility Notes
 
 - [`#[link]` attributes are now checked more strictly,][96885] which may introduce
   errors for invalid attribute arguments that were previously ignored.
+- [Rounding is now used when converting a float to a `Duration`.][96051] The converted
+  duration can differ slightly from what it was.
 
 Internal Changes
 ----------------
@@ -118,6 +121,7 @@ and related tools.
 [95818]: https://github.com/rust-lang/rust/pull/95818/
 [95897]: https://github.com/rust-lang/rust/pull/95897/
 [95953]: https://github.com/rust-lang/rust/pull/95953/
+[96051]: https://github.com/rust-lang/rust/pull/96051/
 [96296]: https://github.com/rust-lang/rust/pull/96296/
 [96455]: https://github.com/rust-lang/rust/pull/96455/
 [96737]: https://github.com/rust-lang/rust/pull/96737/
index 838f77512c5afd42067bee3afc667287e6cac15d..528fc4816e928897a12d67861ac0f3581d1ef932 100644 (file)
@@ -14,7 +14,6 @@
 #![feature(const_trait_impl)]
 #![feature(if_let_guard)]
 #![feature(label_break_value)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(slice_internals)]
index 92e6bc6013dc2ab4ada6cbba7e0469d3b8b04308..32dbd2ff47d6b98349cd4a51a65e13734a3b3107 100644 (file)
@@ -1406,8 +1406,10 @@ fn with_loop_condition_scope<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T
     }
 
     fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
+        let hir_id = self.lower_node_id(f.id);
+        self.lower_attrs(hir_id, &f.attrs);
         hir::ExprField {
-            hir_id: self.next_id(),
+            hir_id,
             ident: self.lower_ident(f.ident),
             expr: self.lower_expr(&f.expr),
             span: self.lower_span(f.span),
index e08c1d063c10544aca6fd83785b103c4597c9d30..2b7431f0990570a004902099db789a36f65cd989 100644 (file)
@@ -199,6 +199,13 @@ fn visit_pat(&mut self, pat: &'hir Pat<'hir>) {
         });
     }
 
+    fn visit_pat_field(&mut self, field: &'hir PatField<'hir>) {
+        self.insert(field.span, field.hir_id, Node::PatField(field));
+        self.with_parent(field.hir_id, |this| {
+            intravisit::walk_pat_field(this, field);
+        });
+    }
+
     fn visit_arm(&mut self, arm: &'hir Arm<'hir>) {
         let node = Node::Arm(arm);
 
@@ -225,6 +232,13 @@ fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
         });
     }
 
+    fn visit_expr_field(&mut self, field: &'hir ExprField<'hir>) {
+        self.insert(field.span, field.hir_id, Node::ExprField(field));
+        self.with_parent(field.hir_id, |this| {
+            intravisit::walk_expr_field(this, field);
+        });
+    }
+
     fn visit_stmt(&mut self, stmt: &'hir Stmt<'hir>) {
         self.insert(stmt.span, stmt.hir_id, Node::Stmt(stmt));
 
index 38d30d0ffdedbfa8c286be6a95e5c7420b20a7a3..056f9ca08f8f286e7d3c5de8216e28abd2d2d861 100644 (file)
@@ -31,7 +31,6 @@
 //! in the HIR, especially for multiple identifiers.
 
 #![feature(box_patterns)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(never_type)]
 #![recursion_limit = "256"]
index bd2e76e5528dab08b8a07e00353bc7bdbfb1e906..51f67e505f4eeae82458a7b138a95b7a112ce8be 100644 (file)
@@ -64,12 +64,17 @@ pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
                             ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         );
 
-                        let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::PatField {
-                            hir_id: self.next_id(),
-                            ident: self.lower_ident(f.ident),
-                            pat: self.lower_pat(&f.pat),
-                            is_shorthand: f.is_shorthand,
-                            span: self.lower_span(f.span),
+                        let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
+                            let hir_id = self.lower_node_id(f.id);
+                            self.lower_attrs(hir_id, &f.attrs);
+
+                            hir::PatField {
+                                hir_id,
+                                ident: self.lower_ident(f.ident),
+                                pat: self.lower_pat(&f.pat),
+                                is_shorthand: f.is_shorthand,
+                                span: self.lower_span(f.span),
+                            }
                         }));
                         break hir::PatKind::Struct(qpath, fs, etc);
                     }
index 2e3ac0c60186dadfd2f27d4cb7b17a7391ec735b..2bc3b6f361643df5fe3e733ca2cc968b7935d06d 100644 (file)
@@ -8,7 +8,6 @@
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(iter_is_partitioned)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![recursion_limit = "256"]
 
index afe1d191d10e16d69d8a27647fbdf328f17c7d21..c95c1c40a34c20fc211cfbbf31b5241cb7cddbca 100644 (file)
@@ -4,7 +4,6 @@
 //! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax`
 //! to this crate.
 
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 
 #[macro_use]
index 1ef2b0ae98843b3edd575b71783fd86a7f0e8b14..b1def189230f76c90eeb0c7a253c185047331354 100644 (file)
@@ -484,9 +484,7 @@ fn try_extract_error_from_region_constraints<'tcx>(
     };
     nice_error.try_report_from_nll().or_else(|| {
         if let SubregionOrigin::Subtype(trace) = cause {
-            Some(
-                infcx.report_and_explain_type_error(*trace, &TypeError::RegionsPlaceholderMismatch),
-            )
+            Some(infcx.report_and_explain_type_error(*trace, TypeError::RegionsPlaceholderMismatch))
         } else {
             None
         }
index 4f2a7bccefb683948d516e8d88b4c2305767cfe8..4ad9a970bc1be32eacdc72faafbe5647fec084cc 100644 (file)
@@ -2,7 +2,6 @@
 
 #![allow(rustc::potential_query_instability)]
 #![feature(box_patterns)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
index 9eb96ec76800c8634355aae052d55bc7eca4450f..53c13873b1016f65dd6ab38ea06a0d28d419c2d9 100644 (file)
@@ -130,64 +130,46 @@ impl PositionalNamedArgsLint {
     /// CountIsParam, which contains an index into the arguments.
     fn maybe_add_positional_named_arg(
         &mut self,
-        current_positional_arg: usize,
-        total_args_length: usize,
-        format_argument_index: usize,
+        arg: Option<&FormatArg>,
         ty: PositionalNamedArgType,
         cur_piece: usize,
         inner_span_to_replace: Option<rustc_parse_format::InnerSpan>,
-        names: &FxHashMap<Symbol, (usize, Span)>,
         has_formatting: bool,
     ) {
-        let start_of_named_args = total_args_length - names.len();
-        if current_positional_arg >= start_of_named_args {
-            self.maybe_push(
-                format_argument_index,
-                ty,
-                cur_piece,
-                inner_span_to_replace,
-                names,
-                has_formatting,
-            )
+        if let Some(arg) = arg {
+            if let Some(name) = arg.name {
+                self.push(name, ty, cur_piece, inner_span_to_replace, has_formatting)
+            }
         }
     }
 
-    /// Try constructing a PositionalNamedArg struct and pushing it into the vec of positional
-    /// named arguments. If a named arg associated with `format_argument_index` cannot be found,
-    /// a new item will not be added as the lint cannot be emitted in this case.
-    fn maybe_push(
+    /// Construct a PositionalNamedArg struct and push it into the vec of positional
+    /// named arguments.
+    fn push(
         &mut self,
-        format_argument_index: usize,
+        arg_name: Ident,
         ty: PositionalNamedArgType,
         cur_piece: usize,
         inner_span_to_replace: Option<rustc_parse_format::InnerSpan>,
-        names: &FxHashMap<Symbol, (usize, Span)>,
         has_formatting: bool,
     ) {
-        let named_arg = names
-            .iter()
-            .find(|&(_, &(index, _))| index == format_argument_index)
-            .map(|found| found.clone());
-
-        if let Some((&replacement, &(_, positional_named_arg_span))) = named_arg {
-            // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in
-            // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is
-            // `Precision`.
-            let inner_span_to_replace = if ty == PositionalNamedArgType::Precision {
-                inner_span_to_replace
-                    .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end })
-            } else {
-                inner_span_to_replace
-            };
-            self.positional_named_args.push(PositionalNamedArg {
-                ty,
-                cur_piece,
-                inner_span_to_replace,
-                replacement,
-                positional_named_arg_span,
-                has_formatting,
-            });
-        }
+        // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in
+        // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is
+        // `Precision`.
+        let inner_span_to_replace = if ty == PositionalNamedArgType::Precision {
+            inner_span_to_replace
+                .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end })
+        } else {
+            inner_span_to_replace
+        };
+        self.positional_named_args.push(PositionalNamedArg {
+            ty,
+            cur_piece,
+            inner_span_to_replace,
+            replacement: arg_name.name,
+            positional_named_arg_span: arg_name.span,
+            has_formatting,
+        });
     }
 }
 
@@ -211,7 +193,7 @@ struct Context<'a, 'b> {
     /// * `arg_types` (in JSON): `[[0, 1, 0], [0, 1, 1], [0, 1]]`
     /// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]`
     /// * `names` (in JSON): `{"foo": 2}`
-    args: Vec<P<ast::Expr>>,
+    args: Vec<FormatArg>,
     /// The number of arguments that were added by implicit capturing.
     num_captured_args: usize,
     /// Placeholder slot numbers indexed by argument.
@@ -219,7 +201,7 @@ struct Context<'a, 'b> {
     /// Unique format specs seen for each argument.
     arg_unique_types: Vec<Vec<ArgumentType>>,
     /// Map from named arguments to their resolved indices.
-    names: FxHashMap<Symbol, (usize, Span)>,
+    names: FxHashMap<Symbol, usize>,
 
     /// The latest consecutive literal strings, or empty if there weren't any.
     literal: String,
@@ -282,7 +264,7 @@ struct Context<'a, 'b> {
 
 pub struct FormatArg {
     expr: P<ast::Expr>,
-    named: bool,
+    name: Option<Ident>,
 }
 
 /// Parses the arguments from the given list of tokens, returning the diagnostic
@@ -298,9 +280,9 @@ fn parse_args<'a>(
     ecx: &mut ExtCtxt<'a>,
     sp: Span,
     tts: TokenStream,
-) -> PResult<'a, (P<ast::Expr>, Vec<FormatArg>, FxHashMap<Symbol, (usize, Span)>)> {
+) -> PResult<'a, (P<ast::Expr>, Vec<FormatArg>, FxHashMap<Symbol, usize>)> {
     let mut args = Vec::<FormatArg>::new();
-    let mut names = FxHashMap::<Symbol, (usize, Span)>::default();
+    let mut names = FxHashMap::<Symbol, usize>::default();
 
     let mut p = ecx.new_parser_from_tts(tts);
 
@@ -365,9 +347,9 @@ fn parse_args<'a>(
                 p.bump();
                 p.expect(&token::Eq)?;
                 let e = p.parse_expr()?;
-                if let Some((prev, _)) = names.get(&ident.name) {
+                if let Some(&prev) = names.get(&ident.name) {
                     ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", ident))
-                        .span_label(args[*prev].expr.span, "previously here")
+                        .span_label(args[prev].expr.span, "previously here")
                         .span_label(e.span, "duplicate argument")
                         .emit();
                     continue;
@@ -378,8 +360,8 @@ fn parse_args<'a>(
                 // if the input is valid, we can simply append to the positional
                 // args. And remember the names.
                 let slot = args.len();
-                names.insert(ident.name, (slot, ident.span));
-                args.push(FormatArg { expr: e, named: true });
+                names.insert(ident.name, slot);
+                args.push(FormatArg { expr: e, name: Some(ident) });
             }
             _ => {
                 let e = p.parse_expr()?;
@@ -389,12 +371,12 @@ fn parse_args<'a>(
                         "positional arguments cannot follow named arguments",
                     );
                     err.span_label(e.span, "positional arguments must be before named arguments");
-                    for pos in names.values() {
-                        err.span_label(args[pos.0].expr.span, "named argument");
+                    for &pos in names.values() {
+                        err.span_label(args[pos].expr.span, "named argument");
                     }
                     err.emit();
                 }
-                args.push(FormatArg { expr: e, named: false });
+                args.push(FormatArg { expr: e, name: None });
             }
         }
     }
@@ -410,8 +392,7 @@ fn num_args(&self) -> usize {
     fn resolve_name_inplace(&mut self, p: &mut parse::Piece<'_>) {
         // NOTE: the `unwrap_or` branch is needed in case of invalid format
         // arguments, e.g., `format_args!("{foo}")`.
-        let lookup =
-            |s: &str| self.names.get(&Symbol::intern(s)).unwrap_or(&(0, Span::default())).0;
+        let lookup = |s: &str| self.names.get(&Symbol::intern(s)).copied().unwrap_or(0);
 
         match *p {
             parse::String(_) => {}
@@ -457,13 +438,10 @@ fn verify_piece(&mut self, p: &parse::Piece<'_>) {
                 let pos = match arg.position {
                     parse::ArgumentIs(i) => {
                         self.unused_names_lint.maybe_add_positional_named_arg(
-                            i,
-                            self.args.len(),
-                            i,
+                            self.args.get(i),
                             PositionalNamedArgType::Arg,
                             self.curpiece,
                             Some(arg.position_span),
-                            &self.names,
                             has_precision || has_width,
                         );
 
@@ -471,13 +449,10 @@ fn verify_piece(&mut self, p: &parse::Piece<'_>) {
                     }
                     parse::ArgumentImplicitlyIs(i) => {
                         self.unused_names_lint.maybe_add_positional_named_arg(
-                            i,
-                            self.args.len(),
-                            i,
+                            self.args.get(i),
                             PositionalNamedArgType::Arg,
                             self.curpiece,
                             None,
-                            &self.names,
                             has_precision || has_width,
                         );
                         Exact(i)
@@ -563,13 +538,10 @@ fn verify_count(
             parse::CountImplied | parse::CountIs(..) => {}
             parse::CountIsParam(i) => {
                 self.unused_names_lint.maybe_add_positional_named_arg(
-                    i,
-                    self.args.len(),
-                    i,
+                    self.args.get(i),
                     named_arg_type,
                     self.curpiece,
                     *inner_span,
-                    &self.names,
                     true,
                 );
                 self.verify_arg_type(Exact(i), Count);
@@ -622,7 +594,7 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
             );
             for arg in &self.args {
                 // Point at the arguments that will be formatted.
-                e.span_label(arg.span, "");
+                e.span_label(arg.expr.span, "");
             }
         } else {
             let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip();
@@ -692,7 +664,7 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
                         );
                         if let Some(arg) = self.args.get(pos) {
                             e.span_label(
-                                arg.span,
+                                arg.expr.span,
                                 "this parameter corresponds to the precision flag",
                             );
                         }
@@ -771,7 +743,7 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
                 match self.names.get(&name) {
                     Some(&idx) => {
                         // Treat as positional arg.
-                        self.verify_arg_type(Capture(idx.0), ty)
+                        self.verify_arg_type(Capture(idx), ty)
                     }
                     None => {
                         // For the moment capturing variables from format strings expanded from macros is
@@ -787,8 +759,11 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
                                 self.fmtsp
                             };
                             self.num_captured_args += 1;
-                            self.args.push(self.ecx.expr_ident(span, Ident::new(name, span)));
-                            self.names.insert(name, (idx, span));
+                            self.args.push(FormatArg {
+                                expr: self.ecx.expr_ident(span, Ident::new(name, span)),
+                                name: Some(Ident::new(name, span)),
+                            });
+                            self.names.insert(name, idx);
                             self.verify_arg_type(Capture(idx), ty)
                         } else {
                             let msg = format!("there is no argument named `{}`", name);
@@ -1054,11 +1029,11 @@ fn into_expr(self) -> P<ast::Expr> {
         // evaluated a single time each, in the order written by the programmer,
         // and that the surrounding future/generator (if any) is Send whenever
         // possible.
-        let no_need_for_match =
-            nicely_ordered && !original_args.iter().skip(1).any(|e| may_contain_yield_point(e));
+        let no_need_for_match = nicely_ordered
+            && !original_args.iter().skip(1).any(|arg| may_contain_yield_point(&arg.expr));
 
         for (arg_index, arg_ty) in fmt_arg_index_and_ty {
-            let e = &mut original_args[arg_index];
+            let e = &mut original_args[arg_index].expr;
             let span = e.span;
             let arg = if no_need_for_match {
                 let expansion_span = e.span.with_ctxt(self.macsp.ctxt());
@@ -1087,7 +1062,9 @@ fn into_expr(self) -> P<ast::Expr> {
                 // span is otherwise unavailable in the MIR used by borrowck).
                 let heads = original_args
                     .into_iter()
-                    .map(|e| self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e))
+                    .map(|arg| {
+                        self.ecx.expr_addr_of(arg.expr.span.with_ctxt(self.macsp.ctxt()), arg.expr)
+                    })
                     .collect();
 
                 let pat = self.ecx.pat_ident(self.macsp, Ident::new(sym::args, self.macsp));
@@ -1220,7 +1197,7 @@ pub fn expand_preparsed_format_args(
     sp: Span,
     efmt: P<ast::Expr>,
     args: Vec<FormatArg>,
-    names: FxHashMap<Symbol, (usize, Span)>,
+    names: FxHashMap<Symbol, usize>,
     append_newline: bool,
 ) -> P<ast::Expr> {
     // NOTE: this verbose way of initializing `Vec<Vec<ArgumentType>>` is because
@@ -1312,16 +1289,17 @@ pub fn expand_preparsed_format_args(
         if err.should_be_replaced_with_positional_argument {
             let captured_arg_span =
                 fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end));
-            let positional_args = args.iter().filter(|arg| !arg.named).collect::<Vec<_>>();
+            let n_positional_args =
+                args.iter().rposition(|arg| arg.name.is_none()).map_or(0, |i| i + 1);
             if let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) {
-                let span = match positional_args.last() {
+                let span = match args[..n_positional_args].last() {
                     Some(arg) => arg.expr.span,
                     None => fmt_sp,
                 };
                 e.multipart_suggestion_verbose(
                     "consider using a positional formatting argument instead",
                     vec![
-                        (captured_arg_span, positional_args.len().to_string()),
+                        (captured_arg_span, n_positional_args.to_string()),
                         (span.shrink_to_hi(), format!(", {}", arg)),
                     ],
                     Applicability::MachineApplicable,
@@ -1338,11 +1316,9 @@ pub fn expand_preparsed_format_args(
         .map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end)))
         .collect();
 
-    let named_pos: FxHashSet<usize> = names.values().cloned().map(|(i, _)| i).collect();
-
     let mut cx = Context {
         ecx,
-        args: args.into_iter().map(|arg| arg.expr).collect(),
+        args,
         num_captured_args: 0,
         arg_types,
         arg_unique_types,
@@ -1410,14 +1386,12 @@ pub fn expand_preparsed_format_args(
         .enumerate()
         .filter(|(i, ty)| ty.is_empty() && !cx.count_positions.contains_key(&i))
         .map(|(i, _)| {
-            let msg = if named_pos.contains(&i) {
-                // named argument
+            let msg = if cx.args[i].name.is_some() {
                 "named argument never used"
             } else {
-                // positional argument
                 "argument never used"
             };
-            (cx.args[i].span, msg)
+            (cx.args[i].expr.span, msg)
         })
         .collect::<Vec<_>>();
 
index 0192f3c8ca4f253f77d936911e1b8d397c1fdbbf..48e81eb13c0c6a6bf675b62428eff8f05864d573 100644 (file)
@@ -8,7 +8,6 @@
 #![feature(decl_macro)]
 #![feature(if_let_guard)]
 #![feature(is_sorted)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
index bd84100e0e883797d0ccaf4594c1d17a66260401..25a989bdf05253b6ec91aed5ee615b24a71bbca9 100644 (file)
@@ -114,6 +114,7 @@ macro_rules! return_if_di_node_created_in_meantime {
 }
 
 /// Extract size and alignment from a TyAndLayout.
+#[inline]
 fn size_and_align_of<'tcx>(ty_and_layout: TyAndLayout<'tcx>) -> (Size, Align) {
     (ty_and_layout.size, ty_and_layout.align.abi)
 }
index d6e2c8ccdf44a2344cbf74004c0dec9f0f0b85db..daec9303b2c67edbf6f009ec9492bc81a8c02f68 100644 (file)
@@ -1,19 +1,21 @@
 use std::borrow::Cow;
 
 use libc::c_uint;
-use rustc_codegen_ssa::debuginfo::{
-    type_names::compute_debuginfo_type_name, wants_c_like_enum_debuginfo,
+use rustc_codegen_ssa::{
+    debuginfo::{type_names::compute_debuginfo_type_name, wants_c_like_enum_debuginfo},
+    traits::ConstMethods,
 };
+
+use rustc_index::vec::IndexVec;
 use rustc_middle::{
     bug,
     ty::{
         self,
         layout::{LayoutOf, TyAndLayout},
-        util::Discr,
-        AdtDef, GeneratorSubsts,
+        AdtDef, GeneratorSubsts, Ty,
     },
 };
-use rustc_target::abi::{Size, TagEncoding, VariantIdx, Variants};
+use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
 use smallvec::smallvec;
 
 use crate::{
@@ -21,9 +23,9 @@
     debuginfo::{
         metadata::{
             build_field_di_node, closure_saved_names_of_captured_variables,
-            enums::tag_base_type,
-            file_metadata, generator_layout_and_saved_local_names, size_and_align_of,
-            type_map::{self, UniqueTypeId},
+            enums::{tag_base_type, DiscrResult},
+            file_metadata, generator_layout_and_saved_local_names, size_and_align_of, type_di_node,
+            type_map::{self, Stub, UniqueTypeId},
             unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA,
             UNKNOWN_LINE_NUMBER,
         },
     },
 };
 
-/// In CPP-like mode, we generate a union of structs for each variant and an
-/// explicit discriminant field roughly equivalent to the following C/C++ code:
+// The names of the associated constants in each variant wrapper struct.
+// These have to match up with the names being used in `intrinsic.natvis`.
+const ASSOC_CONST_DISCR_NAME: &str = "NAME";
+const ASSOC_CONST_DISCR_EXACT: &str = "DISCR_EXACT";
+const ASSOC_CONST_DISCR_BEGIN: &str = "DISCR_BEGIN";
+const ASSOC_CONST_DISCR_END: &str = "DISCR_END";
+
+const ASSOC_CONST_DISCR128_EXACT_LO: &str = "DISCR128_EXACT_LO";
+const ASSOC_CONST_DISCR128_EXACT_HI: &str = "DISCR128_EXACT_HI";
+const ASSOC_CONST_DISCR128_BEGIN_LO: &str = "DISCR128_BEGIN_LO";
+const ASSOC_CONST_DISCR128_BEGIN_HI: &str = "DISCR128_BEGIN_HI";
+const ASSOC_CONST_DISCR128_END_LO: &str = "DISCR128_END_LO";
+const ASSOC_CONST_DISCR128_END_HI: &str = "DISCR128_END_HI";
+
+// The name of the tag field in the top-level union
+const TAG_FIELD_NAME: &str = "tag";
+const TAG_FIELD_NAME_128_LO: &str = "tag128_lo";
+const TAG_FIELD_NAME_128_HI: &str = "tag128_hi";
+
+// We assign a "virtual" discriminant value to the sole variant of
+// a single-variant enum.
+const SINGLE_VARIANT_VIRTUAL_DISR: u64 = 0;
+
+/// In CPP-like mode, we generate a union with a field for each variant and an
+/// explicit tag field. The field of each variant has a struct type
+/// that encodes the discrimiant of the variant and it's data layout.
+/// The union also has a nested enumeration type that is only used for encoding
+/// variant names in an efficient way. Its enumerator values do _not_ correspond
+/// to the enum's discriminant values.
+/// It's roughly equivalent to the following C/C++ code:
 ///
 /// ```c
-/// union enum$<{fully-qualified-name}> {
-///   struct {variant 0 name} {
-///     <variant 0 fields>
+/// union enum2$<{fully-qualified-name}> {
+///   struct Variant0 {
+///     struct {name-of-variant-0} {
+///        <variant 0 fields>
+///     } value;
+///
+///     static VariantNames NAME = {name-of-variant-0};
+///     static int_type DISCR_EXACT = {discriminant-of-variant-0};
 ///   } variant0;
+///
 ///   <other variant structs>
-///   {name} discriminant;
+///
+///   int_type tag;
+///
+///   enum VariantNames {
+///      <name-of-variant-0> = 0, // The numeric values are variant index,
+///      <name-of-variant-1> = 1, // not discriminant values.
+///      <name-of-variant-2> = 2,
+///      ...
+///   }
 /// }
 /// ```
 ///
-/// As you can see, the type name is wrapped `enum$`. This way we can have a
-/// single NatVis rule for handling all enums.
+/// As you can see, the type name is wrapped in `enum2$<_>`. This way we can
+/// have a single NatVis rule for handling all enums. The `2` in `enum2$<_>`
+/// is an encoding version tag, so that debuggers can decide to decode this
+/// differently than the previous `enum$<_>` encoding emitted by earlier
+/// compiler versions.
 ///
-/// At the LLVM IR level this looks like
+/// Niche-tag enums have one special variant, usually called the
+/// "dataful variant". This variant has a field that
+/// doubles as the tag of the enum. The variant is active when the value of
+/// that field is within a pre-defined range. Therefore the variant struct
+/// has a `DISCR_BEGIN` and `DISCR_END` field instead of `DISCR_EXACT` in
+/// that case. Both `DISCR_BEGIN` and `DISCR_END` are inclusive bounds.
+/// Note that these ranges can wrap around, so that `DISCR_END < DISCR_BEGIN`.
 ///
-/// ```txt
-///       DW_TAG_union_type              (top-level type for enum)
-///         DW_TAG_member                    (member for variant 1)
-///         DW_TAG_member                    (member for variant 2)
-///         DW_TAG_member                    (member for variant 3)
-///         DW_TAG_structure_type            (type of variant 1)
-///         DW_TAG_structure_type            (type of variant 2)
-///         DW_TAG_structure_type            (type of variant 3)
-///         DW_TAG_enumeration_type          (type of tag)
-/// ```
+/// Single-variant enums don't actually have a tag field. In this case we
+/// emit a static tag field (that always has the value 0) so we can use the
+/// same representation (and NatVis).
 ///
-/// The above encoding applies for enums with a direct tag. For niche-tag we have to do things
-/// differently in order to allow a NatVis visualizer to extract all the information needed:
-/// We generate a union of two fields, one for the dataful variant
-/// and one that just points to the discriminant (which is some field within the dataful variant).
-/// We also create a DW_TAG_enumeration_type DIE that contains tag values for the non-dataful
-/// variants and make the discriminant field that type. We then use NatVis to render the enum type
-/// correctly in Windbg/VS. This will generate debuginfo roughly equivalent to the following C:
+/// For niche-layout enums it's possible to have a 128-bit tag. NatVis, VS, and
+/// WinDbg (the main targets for CPP-like debuginfo at the moment) don't support
+/// 128-bit integers, so all values involved get split into two 64-bit fields.
+/// Instead of the `tag` field, we generate two fields `tag128_lo` and `tag128_hi`,
+/// Instead of `DISCR_EXACT`, we generate `DISCR128_EXACT_LO` and `DISCR128_EXACT_HI`,
+/// and so on.
 ///
-/// ```c
-/// union enum$<{name}, {min niche}, {max niche}, {dataful variant name}> {
-///   struct <dataful variant name> {
-///     <fields in dataful variant>
-///   } dataful_variant;
-///   enum Discriminant$ {
-///     <non-dataful variants>
-///   } discriminant;
+///
+/// The following pseudocode shows how to decode an enum value in a debugger:
+///
+/// ```text
+///
+/// fn find_active_variant(enum_value) -> (VariantName, VariantValue) {
+///     let is_128_bit = enum_value.has_field("tag128_lo");
+///
+///     if !is_128_bit {
+///         // Note: `tag` can be a static field for enums with only one
+///         //       inhabited variant.
+///         let tag = enum_value.field("tag").value;
+///
+///         // For each variant, check if it is a match. Only one of them will match,
+///         // so if we find it we can return it immediately.
+///         for variant_field in enum_value.fields().filter(|f| f.name.starts_with("variant")) {
+///             if variant_field.has_field("DISCR_EXACT") {
+///                 // This variant corresponds to a single tag value
+///                 if variant_field.field("DISCR_EXACT").value == tag {
+///                     return (variant_field.field("NAME"), variant_field.value);
+///                 }
+///             } else {
+///                 // This is a range variant
+///                 let begin = variant_field.field("DISCR_BEGIN");
+///                 let end = variant_field.field("DISCR_END");
+///
+///                 if is_in_range(tag, begin, end) {
+///                     return (variant_field.field("NAME"), variant_field.value);
+///                 }
+///             }
+///         }
+///     } else {
+///         // Basically the same as with smaller tags, we just have to
+///         // stitch the values together.
+///         let tag: u128 = (enum_value.field("tag128_lo").value as u128) |
+///                         (enum_value.field("tag128_hi").value as u128 << 64);
+///
+///         for variant_field in enum_value.fields().filter(|f| f.name.starts_with("variant")) {
+///             if variant_field.has_field("DISCR128_EXACT_LO") {
+///                 let discr_exact = (variant_field.field("DISCR128_EXACT_LO" as u128) |
+///                                   (variant_field.field("DISCR128_EXACT_HI") as u128 << 64);
+///
+///                 // This variant corresponds to a single tag value
+///                 if discr_exact.value == tag {
+///                     return (variant_field.field("NAME"), variant_field.value);
+///                 }
+///             } else {
+///                 // This is a range variant
+///                 let begin = (variant_field.field("DISCR128_BEGIN_LO").value as u128) |
+///                             (variant_field.field("DISCR128_BEGIN_HI").value as u128 << 64);
+///                 let end = (variant_field.field("DISCR128_END_LO").value as u128) |
+///                           (variant_field.field("DISCR128_END_HI").value as u128 << 64);
+///
+///                 if is_in_range(tag, begin, end) {
+///                     return (variant_field.field("NAME"), variant_field.value);
+///                 }
+///             }
+///         }
+///     }
+///
+///     // We should have found an active variant at this point.
+///     unreachable!();
 /// }
-/// ```
 ///
-/// The NatVis in `intrinsic.natvis` matches on the type name `enum$<*, *, *, *>`
-/// and evaluates `this.discriminant`. If the value is between the min niche and max
-/// niche, then the enum is in the dataful variant and `this.dataful_variant` is
-/// rendered. Otherwise, the enum is in one of the non-dataful variants. In that
-/// case, we just need to render the name of the `this.discriminant` enum.
+/// // Check if a value is within the given range
+/// // (where the range might wrap around the value space)
+/// fn is_in_range(value, start, end) -> bool {
+///     if start < end {
+///         value >= start && value <= end
+///     } else {
+///         value >= start || value <= end
+///     }
+/// }
+///
+/// ```
 pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     unique_type_id: UniqueTypeId<'tcx>,
@@ -135,27 +239,28 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
                     ref variants,
                     tag_field,
                     ..
-                } => build_union_fields_for_direct_tag_enum(
+                } => build_union_fields_for_enum(
                     cx,
                     enum_adt_def,
                     enum_type_and_layout,
                     enum_type_di_node,
-                    &mut variants.indices(),
+                    variants.indices(),
                     tag_field,
+                    None,
                 ),
                 Variants::Multiple {
                     tag_encoding: TagEncoding::Niche { dataful_variant, .. },
                     ref variants,
                     tag_field,
                     ..
-                } => build_union_fields_for_niche_tag_enum(
+                } => build_union_fields_for_enum(
                     cx,
                     enum_adt_def,
                     enum_type_and_layout,
                     enum_type_di_node,
-                    dataful_variant,
-                    &mut variants.indices(),
+                    variants.indices(),
                     tag_field,
+                    Some(dataful_variant),
                 ),
             }
         },
@@ -217,137 +322,344 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
     let variant_layout = enum_type_and_layout.for_variant(cx, variant_index);
     let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
         cx,
-        enum_type_and_layout.ty,
+        enum_type_and_layout,
         enum_type_di_node,
         variant_index,
         enum_adt_def.variant(variant_index),
         variant_layout,
     );
 
-    // NOTE: The field name of the union is the same as the variant name, not "variant0".
-    let variant_name = enum_adt_def.variant(variant_index).name.as_str();
+    let tag_base_type = cx.tcx.types.u32;
+    let tag_base_type_di_node = type_di_node(cx, tag_base_type);
+    let tag_base_type_align = cx.align_of(tag_base_type);
 
-    smallvec![build_field_di_node(
+    let variant_names_type_di_node = build_variant_names_type_di_node(
         cx,
         enum_type_di_node,
-        variant_name,
-        // NOTE: We use the size and align of the entire type, not from variant_layout
-        //       since the later is sometimes smaller (if it has fewer fields).
-        size_and_align_of(enum_type_and_layout),
-        Size::ZERO,
-        DIFlags::FlagZero,
+        std::iter::once((
+            variant_index,
+            Cow::from(enum_adt_def.variant(variant_index).name.as_str()),
+        )),
+    );
+
+    let variant_struct_type_wrapper_di_node = build_variant_struct_wrapper_type_di_node(
+        cx,
+        enum_type_and_layout,
+        enum_type_di_node,
+        variant_index,
+        None,
         variant_struct_type_di_node,
-    )]
+        variant_names_type_di_node,
+        tag_base_type_di_node,
+        tag_base_type,
+        DiscrResult::NoDiscriminant,
+    );
+
+    smallvec![
+        build_field_di_node(
+            cx,
+            enum_type_di_node,
+            &variant_union_field_name(variant_index),
+            // NOTE: We use the size and align of the entire type, not from variant_layout
+            //       since the later is sometimes smaller (if it has fewer fields).
+            size_and_align_of(enum_type_and_layout),
+            Size::ZERO,
+            DIFlags::FlagZero,
+            variant_struct_type_wrapper_di_node,
+        ),
+        unsafe {
+            llvm::LLVMRustDIBuilderCreateStaticMemberType(
+                DIB(cx),
+                enum_type_di_node,
+                TAG_FIELD_NAME.as_ptr().cast(),
+                TAG_FIELD_NAME.len(),
+                unknown_file_metadata(cx),
+                UNKNOWN_LINE_NUMBER,
+                variant_names_type_di_node,
+                DIFlags::FlagZero,
+                Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)),
+                tag_base_type_align.bits() as u32,
+            )
+        }
+    ]
 }
 
-fn build_union_fields_for_direct_tag_enum<'ll, 'tcx>(
+fn build_union_fields_for_enum<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     enum_adt_def: AdtDef<'tcx>,
     enum_type_and_layout: TyAndLayout<'tcx>,
     enum_type_di_node: &'ll DIType,
-    variant_indices: &mut dyn Iterator<Item = VariantIdx>,
+    variant_indices: impl Iterator<Item = VariantIdx> + Clone,
     tag_field: usize,
+    dataful_variant_index: Option<VariantIdx>,
 ) -> SmallVec<&'ll DIType> {
+    let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
+
+    let variant_names_type_di_node = build_variant_names_type_di_node(
+        cx,
+        enum_type_di_node,
+        variant_indices.clone().map(|variant_index| {
+            let variant_name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
+            (variant_index, variant_name)
+        }),
+    );
+
     let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_indices
         .map(|variant_index| {
             let variant_layout = enum_type_and_layout.for_variant(cx, variant_index);
 
+            let variant_def = enum_adt_def.variant(variant_index);
+
+            let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
+                cx,
+                enum_type_and_layout,
+                enum_type_di_node,
+                variant_index,
+                variant_def,
+                variant_layout,
+            );
+
             VariantFieldInfo {
                 variant_index,
-                variant_struct_type_di_node: super::build_enum_variant_struct_type_di_node(
-                    cx,
-                    enum_type_and_layout.ty,
-                    enum_type_di_node,
-                    variant_index,
-                    enum_adt_def.variant(variant_index),
-                    variant_layout,
-                ),
+                variant_struct_type_di_node,
                 source_info: None,
+                discr: super::compute_discriminant_value(cx, enum_type_and_layout, variant_index),
             }
         })
         .collect();
 
-    let discr_type_name = cx.tcx.item_name(enum_adt_def.did());
-    let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
-    let discr_type_di_node = super::build_enumeration_type_di_node(
-        cx,
-        discr_type_name.as_str(),
-        tag_base_type,
-        &mut enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
-            (discr, Cow::from(enum_adt_def.variant(variant_index).name.as_str()))
-        }),
-        enum_type_di_node,
-    );
-
     build_union_fields_for_direct_tag_enum_or_generator(
         cx,
         enum_type_and_layout,
         enum_type_di_node,
         &variant_field_infos,
-        discr_type_di_node,
+        variant_names_type_di_node,
+        tag_base_type,
         tag_field,
+        dataful_variant_index,
     )
 }
 
-fn build_union_fields_for_niche_tag_enum<'ll, 'tcx>(
+// The base type of the VariantNames DW_AT_enumeration_type is always the same.
+// It has nothing to do with the tag of the enum and just has to be big enough
+// to hold all variant names.
+fn variant_names_enum_base_type<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> Ty<'tcx> {
+    cx.tcx.types.u32
+}
+
+/// This function builds a DW_AT_enumeration_type that contains an entry for
+/// each variant. Note that this has nothing to do with the discriminant. The
+/// numeric value of each enumerator corresponds to the variant index. The
+/// type is only used for efficiently encoding the name of each variant in
+/// debuginfo.
+fn build_variant_names_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
-    enum_adt_def: AdtDef<'tcx>,
-    enum_type_and_layout: TyAndLayout<'tcx>,
-    enum_type_di_node: &'ll DIType,
-    dataful_variant_index: VariantIdx,
-    variant_indices: &mut dyn Iterator<Item = VariantIdx>,
-    tag_field: usize,
-) -> SmallVec<&'ll DIType> {
-    let dataful_variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
+    containing_scope: &'ll DIType,
+    variants: impl Iterator<Item = (VariantIdx, Cow<'tcx, str>)>,
+) -> &'ll DIType {
+    // Create an enumerator for each variant.
+    super::build_enumeration_type_di_node(
         cx,
-        enum_type_and_layout.ty,
-        enum_type_di_node,
-        dataful_variant_index,
-        &enum_adt_def.variant(dataful_variant_index),
-        enum_type_and_layout.for_variant(cx, dataful_variant_index),
-    );
+        "VariantNames",
+        variant_names_enum_base_type(cx),
+        variants.map(|(variant_index, variant_name)| (variant_name, variant_index.as_u32() as u64)),
+        containing_scope,
+    )
+}
 
-    let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
-    // Create an DW_TAG_enumerator for each variant except the dataful one.
-    let discr_type_di_node = super::build_enumeration_type_di_node(
+fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
+    cx: &CodegenCx<'ll, 'tcx>,
+    enum_or_generator_type_and_layout: TyAndLayout<'tcx>,
+    enum_or_generator_type_di_node: &'ll DIType,
+    variant_index: VariantIdx,
+    dataful_variant_index: Option<VariantIdx>,
+    variant_struct_type_di_node: &'ll DIType,
+    variant_names_type_di_node: &'ll DIType,
+    tag_base_type_di_node: &'ll DIType,
+    tag_base_type: Ty<'tcx>,
+    discr: DiscrResult,
+) -> &'ll DIType {
+    type_map::build_type_with_children(
         cx,
-        "Discriminant$",
-        tag_base_type,
-        &mut variant_indices.filter_map(|variant_index| {
-            if let Some(discr_val) =
-                super::compute_discriminant_value(cx, enum_type_and_layout, variant_index)
-            {
-                let discr = Discr { val: discr_val as u128, ty: tag_base_type };
-                let variant_name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
-                Some((discr, variant_name))
-            } else {
-                debug_assert_eq!(variant_index, dataful_variant_index);
-                None
-            }
-        }),
-        enum_type_di_node,
-    );
-
-    smallvec![
-        build_field_di_node(
-            cx,
-            enum_type_di_node,
-            "dataful_variant",
-            size_and_align_of(enum_type_and_layout),
-            Size::ZERO,
-            DIFlags::FlagZero,
-            dataful_variant_struct_type_di_node,
-        ),
-        build_field_di_node(
+        type_map::stub(
             cx,
-            enum_type_di_node,
-            "discriminant",
-            cx.size_and_align_of(tag_base_type),
-            enum_type_and_layout.fields.offset(tag_field),
+            Stub::Struct,
+            UniqueTypeId::for_enum_variant_struct_type_wrapper(
+                cx.tcx,
+                enum_or_generator_type_and_layout.ty,
+                variant_index,
+            ),
+            &variant_struct_wrapper_type_name(variant_index),
+            // NOTE: We use size and align of enum_type, not from variant_layout:
+            size_and_align_of(enum_or_generator_type_and_layout),
+            Some(enum_or_generator_type_di_node),
             DIFlags::FlagZero,
-            discr_type_di_node,
         ),
-    ]
+        |cx, wrapper_struct_type_di_node| {
+            enum DiscrKind {
+                Exact(u64),
+                Exact128(u128),
+                Range(u64, u64),
+                Range128(u128, u128),
+            }
+
+            let (tag_base_type_size, tag_base_type_align) = cx.size_and_align_of(tag_base_type);
+            let is_128_bits = tag_base_type_size.bits() > 64;
+
+            let discr = match discr {
+                DiscrResult::NoDiscriminant => DiscrKind::Exact(SINGLE_VARIANT_VIRTUAL_DISR),
+                DiscrResult::Value(discr_val) => {
+                    if is_128_bits {
+                        DiscrKind::Exact128(discr_val)
+                    } else {
+                        debug_assert_eq!(discr_val, discr_val as u64 as u128);
+                        DiscrKind::Exact(discr_val as u64)
+                    }
+                }
+                DiscrResult::Range(min, max) => {
+                    assert_eq!(Some(variant_index), dataful_variant_index);
+                    if is_128_bits {
+                        DiscrKind::Range128(min, max)
+                    } else {
+                        debug_assert_eq!(min, min as u64 as u128);
+                        debug_assert_eq!(max, max as u64 as u128);
+                        DiscrKind::Range(min as u64, max as u64)
+                    }
+                }
+            };
+
+            let mut fields = SmallVec::new();
+
+            // We always have a field for the value
+            fields.push(build_field_di_node(
+                cx,
+                wrapper_struct_type_di_node,
+                "value",
+                size_and_align_of(enum_or_generator_type_and_layout),
+                Size::ZERO,
+                DIFlags::FlagZero,
+                variant_struct_type_di_node,
+            ));
+
+            let build_assoc_const =
+                |name: &str, type_di_node: &'ll DIType, value: u64, align: Align| unsafe {
+                    llvm::LLVMRustDIBuilderCreateStaticMemberType(
+                        DIB(cx),
+                        wrapper_struct_type_di_node,
+                        name.as_ptr().cast(),
+                        name.len(),
+                        unknown_file_metadata(cx),
+                        UNKNOWN_LINE_NUMBER,
+                        type_di_node,
+                        DIFlags::FlagZero,
+                        Some(cx.const_u64(value)),
+                        align.bits() as u32,
+                    )
+                };
+
+            // We also always have an associated constant for the discriminant value
+            // of the variant.
+            fields.push(build_assoc_const(
+                ASSOC_CONST_DISCR_NAME,
+                variant_names_type_di_node,
+                variant_index.as_u32() as u64,
+                cx.align_of(variant_names_enum_base_type(cx)),
+            ));
+
+            // Emit the discriminant value (or range) corresponding to the variant.
+            match discr {
+                DiscrKind::Exact(discr_val) => {
+                    fields.push(build_assoc_const(
+                        ASSOC_CONST_DISCR_EXACT,
+                        tag_base_type_di_node,
+                        discr_val,
+                        tag_base_type_align,
+                    ));
+                }
+                DiscrKind::Exact128(discr_val) => {
+                    let align = cx.align_of(cx.tcx.types.u64);
+                    let type_di_node = type_di_node(cx, cx.tcx.types.u64);
+                    let Split128 { hi, lo } = split_128(discr_val);
+
+                    fields.push(build_assoc_const(
+                        ASSOC_CONST_DISCR128_EXACT_LO,
+                        type_di_node,
+                        lo,
+                        align,
+                    ));
+
+                    fields.push(build_assoc_const(
+                        ASSOC_CONST_DISCR128_EXACT_HI,
+                        type_di_node,
+                        hi,
+                        align,
+                    ));
+                }
+                DiscrKind::Range(begin, end) => {
+                    fields.push(build_assoc_const(
+                        ASSOC_CONST_DISCR_BEGIN,
+                        tag_base_type_di_node,
+                        begin,
+                        tag_base_type_align,
+                    ));
+
+                    fields.push(build_assoc_const(
+                        ASSOC_CONST_DISCR_END,
+                        tag_base_type_di_node,
+                        end,
+                        tag_base_type_align,
+                    ));
+                }
+                DiscrKind::Range128(begin, end) => {
+                    let align = cx.align_of(cx.tcx.types.u64);
+                    let type_di_node = type_di_node(cx, cx.tcx.types.u64);
+                    let Split128 { hi: begin_hi, lo: begin_lo } = split_128(begin);
+                    let Split128 { hi: end_hi, lo: end_lo } = split_128(end);
+
+                    fields.push(build_assoc_const(
+                        ASSOC_CONST_DISCR128_BEGIN_HI,
+                        type_di_node,
+                        begin_hi,
+                        align,
+                    ));
+
+                    fields.push(build_assoc_const(
+                        ASSOC_CONST_DISCR128_BEGIN_LO,
+                        type_di_node,
+                        begin_lo,
+                        align,
+                    ));
+
+                    fields.push(build_assoc_const(
+                        ASSOC_CONST_DISCR128_END_HI,
+                        type_di_node,
+                        end_hi,
+                        align,
+                    ));
+
+                    fields.push(build_assoc_const(
+                        ASSOC_CONST_DISCR128_END_LO,
+                        type_di_node,
+                        end_lo,
+                        align,
+                    ));
+                }
+            }
+
+            fields
+        },
+        NO_GENERICS,
+    )
+    .di_node
+}
+
+struct Split128 {
+    hi: u64,
+    lo: u64,
+}
+
+fn split_128(value: u128) -> Split128 {
+    Split128 { hi: (value >> 64) as u64, lo: value as u64 }
 }
 
 fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
@@ -369,6 +681,29 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
 
     let common_upvar_names = closure_saved_names_of_captured_variables(cx.tcx, generator_def_id);
     let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx);
+    let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
+
+    let tag_base_type = tag_base_type(cx, generator_type_and_layout);
+
+    let variant_names_type_di_node = build_variant_names_type_di_node(
+        cx,
+        generator_type_di_node,
+        variant_range
+            .clone()
+            .map(|variant_index| (variant_index, GeneratorSubsts::variant_name(variant_index))),
+    );
+
+    let discriminants: IndexVec<VariantIdx, DiscrResult> = {
+        let discriminants_iter = generator_substs.discriminants(generator_def_id, cx.tcx);
+        let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
+            IndexVec::with_capacity(variant_count);
+        for (variant_index, discr) in discriminants_iter {
+            // Assert that the index in the IndexMap matches up with the given VariantIdx.
+            assert_eq!(variant_index, discriminants.next_index());
+            discriminants.push(DiscrResult::Value(discr.val));
+        }
+        discriminants
+    };
 
     // Build the type node for each field.
     let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_range
@@ -391,29 +726,24 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
                 None
             };
 
-            VariantFieldInfo { variant_index, variant_struct_type_di_node, source_info }
+            VariantFieldInfo {
+                variant_index,
+                variant_struct_type_di_node,
+                source_info,
+                discr: discriminants[variant_index],
+            }
         })
         .collect();
 
-    let tag_base_type = tag_base_type(cx, generator_type_and_layout);
-    let discr_type_name = "Discriminant$";
-    let discr_type_di_node = super::build_enumeration_type_di_node(
-        cx,
-        discr_type_name,
-        tag_base_type,
-        &mut generator_substs
-            .discriminants(generator_def_id, cx.tcx)
-            .map(|(variant_index, discr)| (discr, GeneratorSubsts::variant_name(variant_index))),
-        generator_type_di_node,
-    );
-
     build_union_fields_for_direct_tag_enum_or_generator(
         cx,
         generator_type_and_layout,
         generator_type_di_node,
         &variant_field_infos[..],
-        discr_type_di_node,
+        variant_names_type_di_node,
+        tag_base_type,
         tag_field,
+        None,
     )
 }
 
@@ -425,8 +755,11 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
     enum_type_di_node: &'ll DIType,
     variant_field_infos: &[VariantFieldInfo<'ll>],
     discr_type_di_node: &'ll DIType,
+    tag_base_type: Ty<'tcx>,
     tag_field: usize,
+    dataful_variant_index: Option<VariantIdx>,
 ) -> SmallVec<&'ll DIType> {
+    let tag_base_type_di_node = type_di_node(cx, tag_base_type);
     let mut unions_fields = SmallVec::with_capacity(variant_field_infos.len() + 1);
 
     // We create a field in the union for each variant ...
@@ -438,6 +771,19 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
         let field_name = variant_union_field_name(variant_member_info.variant_index);
         let (size, align) = size_and_align_of(enum_type_and_layout);
 
+        let variant_struct_type_wrapper = build_variant_struct_wrapper_type_di_node(
+            cx,
+            enum_type_and_layout,
+            enum_type_di_node,
+            variant_member_info.variant_index,
+            dataful_variant_index,
+            variant_member_info.variant_struct_type_di_node,
+            discr_type_di_node,
+            tag_base_type_di_node,
+            tag_base_type,
+            variant_member_info.discr,
+        );
+
         // We use LLVMRustDIBuilderCreateMemberType() member type directly because
         // the build_field_di_node() function does not support specifying a source location,
         // which is something that we don't do anywhere else.
@@ -456,7 +802,7 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
                 // Union fields are always at offset zero
                 Size::ZERO.bits(),
                 DIFlags::FlagZero,
-                variant_member_info.variant_struct_type_di_node,
+                variant_struct_type_wrapper,
             )
         }
     }));
@@ -466,16 +812,53 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
         cx.size_and_align_of(super::tag_base_type(cx, enum_type_and_layout))
     );
 
-    // ... and a field for the discriminant.
-    unions_fields.push(build_field_di_node(
-        cx,
-        enum_type_di_node,
-        "discriminant",
-        cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
-        enum_type_and_layout.fields.offset(tag_field),
-        DIFlags::FlagZero,
-        discr_type_di_node,
-    ));
+    // ... and a field for the tag. If the tag is 128 bits wide, this will actually
+    // be two 64-bit fields.
+    let is_128_bits = cx.size_of(tag_base_type).bits() > 64;
+
+    if is_128_bits {
+        let type_di_node = type_di_node(cx, cx.tcx.types.u64);
+        let size_and_align = cx.size_and_align_of(cx.tcx.types.u64);
+
+        let (lo_offset, hi_offset) = match cx.tcx.data_layout.endian {
+            Endian::Little => (0, 8),
+            Endian::Big => (8, 0),
+        };
+
+        let tag_field_offset = enum_type_and_layout.fields.offset(tag_field).bytes();
+        let lo_offset = Size::from_bytes(tag_field_offset + lo_offset);
+        let hi_offset = Size::from_bytes(tag_field_offset + hi_offset);
+
+        unions_fields.push(build_field_di_node(
+            cx,
+            enum_type_di_node,
+            TAG_FIELD_NAME_128_LO,
+            size_and_align,
+            lo_offset,
+            DIFlags::FlagZero,
+            type_di_node,
+        ));
+
+        unions_fields.push(build_field_di_node(
+            cx,
+            enum_type_di_node,
+            TAG_FIELD_NAME_128_HI,
+            size_and_align,
+            hi_offset,
+            DIFlags::FlagZero,
+            type_di_node,
+        ));
+    } else {
+        unions_fields.push(build_field_di_node(
+            cx,
+            enum_type_di_node,
+            TAG_FIELD_NAME,
+            cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
+            enum_type_and_layout.fields.offset(tag_field),
+            DIFlags::FlagZero,
+            tag_base_type_di_node,
+        ));
+    }
 
     unions_fields
 }
@@ -485,6 +868,7 @@ struct VariantFieldInfo<'ll> {
     variant_index: VariantIdx,
     variant_struct_type_di_node: &'ll DIType,
     source_info: Option<(&'ll DIFile, c_uint)>,
+    discr: DiscrResult,
 }
 
 fn variant_union_field_name(variant_index: VariantIdx) -> Cow<'static, str> {
@@ -512,3 +896,29 @@ fn variant_union_field_name(variant_index: VariantIdx) -> Cow<'static, str> {
         .map(|&s| Cow::from(s))
         .unwrap_or_else(|| format!("variant{}", variant_index.as_usize()).into())
 }
+
+fn variant_struct_wrapper_type_name(variant_index: VariantIdx) -> Cow<'static, str> {
+    const PRE_ALLOCATED: [&str; 16] = [
+        "Variant0",
+        "Variant1",
+        "Variant2",
+        "Variant3",
+        "Variant4",
+        "Variant5",
+        "Variant6",
+        "Variant7",
+        "Variant8",
+        "Variant9",
+        "Variant10",
+        "Variant11",
+        "Variant12",
+        "Variant13",
+        "Variant14",
+        "Variant15",
+    ];
+
+    PRE_ALLOCATED
+        .get(variant_index.as_usize())
+        .map(|&s| Cow::from(s))
+        .unwrap_or_else(|| format!("Variant{}", variant_index.as_usize()).into())
+}
index 73e01d0453b257077c8d0605417699f538c01d3d..9b3d080bfd6aa3f8dbb7b1f76de5c70ba62e9fe9 100644 (file)
@@ -10,7 +10,6 @@
     ty::{
         self,
         layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
-        util::Discr,
         AdtDef, GeneratorSubsts, Ty, VariantDef,
     },
 };
@@ -90,8 +89,11 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
             cx,
             &compute_debuginfo_type_name(cx.tcx, enum_type_and_layout.ty, false),
             tag_base_type(cx, enum_type_and_layout),
-            &mut enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
-                (discr, Cow::from(enum_adt_def.variant(variant_index).name.as_str()))
+            enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
+                let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
+                // Is there anything we can do to support 128-bit C-Style enums?
+                let value = discr.val as u64;
+                (name, value)
             }),
             containing_scope,
         ),
@@ -152,7 +154,7 @@ fn build_enumeration_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     type_name: &str,
     base_type: Ty<'tcx>,
-    variants: &mut dyn Iterator<Item = (Discr<'tcx>, Cow<'tcx, str>)>,
+    enumerators: impl Iterator<Item = (Cow<'tcx, str>, u64)>,
     containing_scope: &'ll DIType,
 ) -> &'ll DIType {
     let is_unsigned = match base_type.kind() {
@@ -161,18 +163,15 @@ fn build_enumeration_type_di_node<'ll, 'tcx>(
         _ => bug!("build_enumeration_type_di_node() called with non-integer tag type."),
     };
 
-    let enumerator_di_nodes: SmallVec<Option<&'ll DIType>> = variants
-        .map(|(discr, variant_name)| {
-            unsafe {
-                Some(llvm::LLVMRustDIBuilderCreateEnumerator(
-                    DIB(cx),
-                    variant_name.as_ptr().cast(),
-                    variant_name.len(),
-                    // FIXME: what if enumeration has i128 discriminant?
-                    discr.val as i64,
-                    is_unsigned,
-                ))
-            }
+    let enumerator_di_nodes: SmallVec<Option<&'ll DIType>> = enumerators
+        .map(|(name, value)| unsafe {
+            Some(llvm::LLVMRustDIBuilderCreateEnumerator(
+                DIB(cx),
+                name.as_ptr().cast(),
+                name.len(),
+                value as i64,
+                is_unsigned,
+            ))
         })
         .collect();
 
@@ -247,23 +246,27 @@ fn build_enumeration_type_di_node<'ll, 'tcx>(
 /// and a DW_TAG_member for each field (but not the discriminant).
 fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
-    enum_type: Ty<'tcx>,
+    enum_type_and_layout: TyAndLayout<'tcx>,
     enum_type_di_node: &'ll DIType,
     variant_index: VariantIdx,
     variant_def: &VariantDef,
     variant_layout: TyAndLayout<'tcx>,
 ) -> &'ll DIType {
-    debug_assert_eq!(variant_layout.ty, enum_type);
+    debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
 
     type_map::build_type_with_children(
         cx,
         type_map::stub(
             cx,
             Stub::Struct,
-            UniqueTypeId::for_enum_variant_struct_type(cx.tcx, enum_type, variant_index),
+            UniqueTypeId::for_enum_variant_struct_type(
+                cx.tcx,
+                enum_type_and_layout.ty,
+                variant_index,
+            ),
             variant_def.name.as_str(),
             // NOTE: We use size and align of enum_type, not from variant_layout:
-            cx.size_and_align_of(enum_type),
+            size_and_align_of(enum_type_and_layout),
             Some(enum_type_di_node),
             DIFlags::FlagZero,
         ),
@@ -290,9 +293,9 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
                         type_di_node(cx, field_layout.ty),
                     )
                 })
-                .collect()
+                .collect::<SmallVec<_>>()
         },
-        |cx| build_generic_type_param_di_nodes(cx, enum_type),
+        |cx| build_generic_type_param_di_nodes(cx, enum_type_and_layout.ty),
     )
     .di_node
 }
@@ -398,6 +401,19 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
     .di_node
 }
 
+#[derive(Copy, Clone)]
+enum DiscrResult {
+    NoDiscriminant,
+    Value(u128),
+    Range(u128, u128),
+}
+
+impl DiscrResult {
+    fn opt_single_val(&self) -> Option<u128> {
+        if let Self::Value(d) = *self { Some(d) } else { None }
+    }
+}
+
 /// Returns the discriminant value corresponding to the variant index.
 ///
 /// Will return `None` if there is less than two variants (because then the enum won't have)
@@ -407,12 +423,11 @@ fn compute_discriminant_value<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     enum_type_and_layout: TyAndLayout<'tcx>,
     variant_index: VariantIdx,
-) -> Option<u64> {
+) -> DiscrResult {
     match enum_type_and_layout.layout.variants() {
-        &Variants::Single { .. } => None,
-        &Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => Some(
-            enum_type_and_layout.ty.discriminant_for_variant(cx.tcx, variant_index).unwrap().val
-                as u64,
+        &Variants::Single { .. } => DiscrResult::NoDiscriminant,
+        &Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => DiscrResult::Value(
+            enum_type_and_layout.ty.discriminant_for_variant(cx.tcx, variant_index).unwrap().val,
         ),
         &Variants::Multiple {
             tag_encoding: TagEncoding::Niche { ref niche_variants, niche_start, dataful_variant },
@@ -420,17 +435,26 @@ fn compute_discriminant_value<'ll, 'tcx>(
             ..
         } => {
             if variant_index == dataful_variant {
-                None
+                let valid_range = enum_type_and_layout
+                    .for_variant(cx, variant_index)
+                    .largest_niche
+                    .as_ref()
+                    .unwrap()
+                    .valid_range;
+
+                let min = valid_range.start.min(valid_range.end);
+                let min = tag.size(cx).truncate(min);
+
+                let max = valid_range.start.max(valid_range.end);
+                let max = tag.size(cx).truncate(max);
+
+                DiscrResult::Range(min, max)
             } else {
                 let value = (variant_index.as_u32() as u128)
                     .wrapping_sub(niche_variants.start().as_u32() as u128)
                     .wrapping_add(niche_start);
                 let value = tag.size(cx).truncate(value);
-                // NOTE(eddyb) do *NOT* remove this assert, until
-                // we pass the full 128-bit value to LLVM, otherwise
-                // truncation will be silent and remain undetected.
-                assert_eq!(value as u64 as u128, value);
-                Some(value as u64)
+                DiscrResult::Value(value)
             }
         }
     }
index f1935e0ec31afbbf4bd20bf9cb3113c0d948387b..dae90a43f2659c32ab5277b6a09d4071dc074bff 100644 (file)
@@ -88,7 +88,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
                     variant_name: Cow::from(enum_adt_def.variant(variant_index).name.as_str()),
                     variant_struct_type_di_node: super::build_enum_variant_struct_type_di_node(
                         cx,
-                        enum_type,
+                        enum_type_and_layout,
                         enum_type_di_node,
                         variant_index,
                         enum_adt_def.variant(variant_index),
@@ -413,7 +413,13 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>(
             enum_type_and_layout.size.bits(),
             enum_type_and_layout.align.abi.bits() as u32,
             Size::ZERO.bits(),
-            discr_value.map(|v| cx.const_u64(v)),
+            discr_value.opt_single_val().map(|value| {
+                // NOTE(eddyb) do *NOT* remove this assert, until
+                // we pass the full 128-bit value to LLVM, otherwise
+                // truncation will be silent and remain undetected.
+                assert_eq!(value as u64 as u128, value);
+                cx.const_u64(value as u64)
+            }),
             DIFlags::FlagZero,
             variant_member_info.variant_struct_type_di_node,
         )
index ce2f419c4acdc64bf963a8a3796d4cf9929a1c07..e30622cbdced69260cb2107ba6459898fbcd8235 100644 (file)
@@ -47,6 +47,8 @@ pub(super) enum UniqueTypeId<'tcx> {
     VariantPart(Ty<'tcx>, private::HiddenZst),
     /// The ID for the artificial struct type describing a single enum variant.
     VariantStructType(Ty<'tcx>, VariantIdx, private::HiddenZst),
+    /// The ID for the additional wrapper struct type describing an enum variant in CPP-like mode.
+    VariantStructTypeCppLikeWrapper(Ty<'tcx>, VariantIdx, private::HiddenZst),
     /// The ID of the artificial type we create for VTables.
     VTableTy(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>, private::HiddenZst),
 }
@@ -71,6 +73,15 @@ pub fn for_enum_variant_struct_type(
         UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
     }
 
+    pub fn for_enum_variant_struct_type_wrapper(
+        tcx: TyCtxt<'tcx>,
+        enum_ty: Ty<'tcx>,
+        variant_idx: VariantIdx,
+    ) -> Self {
+        debug_assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
+        UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
+    }
+
     pub fn for_vtable_ty(
         tcx: TyCtxt<'tcx>,
         self_type: Ty<'tcx>,
index eeb1ed61f288f9245a9b497794c25d294da72d9e..c80ad6920006db275fd699bc1756ebd23685fdc7 100644 (file)
@@ -6,7 +6,6 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(hash_raw_entry)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(extern_types)]
 #![feature(once_cell)]
index 3139f93bfefaee9c0daf0c01734d5442983f8b9d..89611fc0dee1b2d9cc8a73d0d125e9b20c1766aa 100644 (file)
@@ -2079,6 +2079,19 @@ pub fn LLVMRustDIBuilderCreateVariantMemberType<'a>(
         Ty: &'a DIType,
     ) -> &'a DIType;
 
+    pub fn LLVMRustDIBuilderCreateStaticMemberType<'a>(
+        Builder: &DIBuilder<'a>,
+        Scope: &'a DIDescriptor,
+        Name: *const c_char,
+        NameLen: size_t,
+        File: &'a DIFile,
+        LineNo: c_uint,
+        Ty: &'a DIType,
+        Flags: DIFlags,
+        val: Option<&'a Value>,
+        AlignInBits: u32,
+    ) -> &'a DIDerivedType;
+
     pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
         Builder: &DIBuilder<'a>,
         Scope: &'a DIScope,
index 953761a782052f952e1e60722253a49489d6e1f1..7f6947e3c79d8c9b33554f82c0de64ceb5df59d1 100644 (file)
@@ -20,7 +20,7 @@
 use rustc_session::{filesearch, Session};
 use rustc_span::symbol::Symbol;
 use rustc_span::DebuggerVisualizerFile;
-use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
+use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
 use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
 use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
 
@@ -764,15 +764,15 @@ fn link_natively<'a>(
                 "Linker does not support -static-pie command line option. Retrying with -static instead."
             );
             // Mirror `add_(pre,post)_link_objects` to replace CRT objects.
-            let self_contained = crt_objects_fallback(sess, crate_type);
+            let self_contained = self_contained(sess, crate_type);
             let opts = &sess.target;
             let pre_objects = if self_contained {
-                &opts.pre_link_objects_fallback
+                &opts.pre_link_objects_self_contained
             } else {
                 &opts.pre_link_objects
             };
             let post_objects = if self_contained {
-                &opts.post_link_objects_fallback
+                &opts.post_link_objects_self_contained
             } else {
                 &opts.post_link_objects
             };
@@ -1556,26 +1556,26 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
     true
 }
 
-/// Whether we link to our own CRT objects instead of relying on gcc to pull them.
+/// Various toolchain components used during linking are used from rustc distribution
+/// instead of being found somewhere on the host system.
 /// We only provide such support for a very limited number of targets.
-fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
+fn self_contained(sess: &Session, crate_type: CrateType) -> bool {
     if let Some(self_contained) = sess.opts.cg.link_self_contained {
         return self_contained;
     }
 
-    match sess.target.crt_objects_fallback {
+    match sess.target.link_self_contained {
+        LinkSelfContainedDefault::False => false,
+        LinkSelfContainedDefault::True => true,
         // FIXME: Find a better heuristic for "native musl toolchain is available",
         // based on host and linker path, for example.
         // (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
-        Some(CrtObjectsFallback::Musl) => sess.crt_static(Some(crate_type)),
-        Some(CrtObjectsFallback::Mingw) => {
+        LinkSelfContainedDefault::Musl => sess.crt_static(Some(crate_type)),
+        LinkSelfContainedDefault::Mingw => {
             sess.host == sess.target
                 && sess.target.vendor != "uwp"
                 && detect_self_contained_mingw(&sess)
         }
-        // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
-        Some(CrtObjectsFallback::Wasm) => true,
-        None => false,
     }
 }
 
@@ -1592,7 +1592,7 @@ fn add_pre_link_objects(
     let opts = &sess.target;
     let empty = Default::default();
     let objects = if self_contained {
-        &opts.pre_link_objects_fallback
+        &opts.pre_link_objects_self_contained
     } else if !(sess.target.os == "fuchsia" && flavor == LinkerFlavor::Gcc) {
         &opts.pre_link_objects
     } else {
@@ -1610,9 +1610,11 @@ fn add_post_link_objects(
     link_output_kind: LinkOutputKind,
     self_contained: bool,
 ) {
-    let opts = &sess.target;
-    let objects =
-        if self_contained { &opts.post_link_objects_fallback } else { &opts.post_link_objects };
+    let objects = if self_contained {
+        &sess.target.post_link_objects_self_contained
+    } else {
+        &sess.target.post_link_objects
+    };
     for obj in objects.get(&link_output_kind).iter().copied().flatten() {
         cmd.add_object(&get_object_file_path(sess, obj, self_contained));
     }
@@ -1891,12 +1893,12 @@ fn linker_with_args<'a>(
     out_filename: &Path,
     codegen_results: &CodegenResults,
 ) -> Result<Command, ErrorGuaranteed> {
-    let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
+    let self_contained = self_contained(sess, crate_type);
     let cmd = &mut *super::linker::get_linker(
         sess,
         path,
         flavor,
-        crt_objects_fallback,
+        self_contained,
         &codegen_results.crate_info.target_cpu,
     );
     let link_output_kind = link_output_kind(sess, crate_type);
@@ -1923,7 +1925,7 @@ fn linker_with_args<'a>(
     // ------------ Object code and libraries, order-dependent ------------
 
     // Pre-link CRT objects.
-    add_pre_link_objects(cmd, sess, flavor, link_output_kind, crt_objects_fallback);
+    add_pre_link_objects(cmd, sess, flavor, link_output_kind, self_contained);
 
     add_linked_symbol_object(
         cmd,
@@ -2033,7 +2035,7 @@ fn linker_with_args<'a>(
         cmd,
         sess,
         link_output_kind,
-        crt_objects_fallback,
+        self_contained,
         flavor,
         crate_type,
         codegen_results,
@@ -2049,7 +2051,7 @@ fn linker_with_args<'a>(
     // ------------ Object code and libraries, order-dependent ------------
 
     // Post-link CRT objects.
-    add_post_link_objects(cmd, sess, link_output_kind, crt_objects_fallback);
+    add_post_link_objects(cmd, sess, link_output_kind, self_contained);
 
     // ------------ Late order-dependent options ------------
 
@@ -2066,7 +2068,7 @@ fn add_order_independent_options(
     cmd: &mut dyn Linker,
     sess: &Session,
     link_output_kind: LinkOutputKind,
-    crt_objects_fallback: bool,
+    self_contained: bool,
     flavor: LinkerFlavor,
     crate_type: CrateType,
     codegen_results: &CodegenResults,
@@ -2098,7 +2100,7 @@ fn add_order_independent_options(
     // Make the binary compatible with data execution prevention schemes.
     cmd.add_no_exec();
 
-    if crt_objects_fallback {
+    if self_contained {
         cmd.no_crt_objects();
     }
 
@@ -2127,7 +2129,7 @@ fn add_order_independent_options(
 
     cmd.linker_plugin_lto();
 
-    add_library_search_dirs(cmd, sess, crt_objects_fallback);
+    add_library_search_dirs(cmd, sess, self_contained);
 
     cmd.output_filename(out_filename);
 
index 8cd5a0fc24759efd8178d138f8a30449539bac29..135ed680da2dc7ad998c2ee25f75be979959662f 100644 (file)
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
 use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, ExistentialProjection, GeneratorSubsts, ParamEnv, Ty, TyCtxt};
-use rustc_target::abi::{Integer, TagEncoding, Variants};
+use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
+use rustc_target::abi::Integer;
 use smallvec::SmallVec;
 
-use std::borrow::Cow;
 use std::fmt::Write;
 
 use crate::debuginfo::wants_c_like_enum_debuginfo;
@@ -98,7 +97,6 @@ fn push_debuginfo_type_name<'tcx>(
 
             if let Some(ty_and_layout) = layout_for_cpp_like_fallback {
                 msvc_enum_fallback(
-                    tcx,
                     ty_and_layout,
                     &|output, visited| {
                         push_item_name(tcx, def.did(), true, output);
@@ -391,11 +389,10 @@ fn push_debuginfo_type_name<'tcx>(
             // Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
             // "{async_fn_env#0}<T1, T2, ...>", etc.
             // In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
-            // an artificial `enum$<>` type, as defined in msvc_enum_fallback().
+            // an artificial `enum2$<>` type, as defined in msvc_enum_fallback().
             if cpp_like_debuginfo && t.is_generator() {
                 let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap();
                 msvc_enum_fallback(
-                    tcx,
                     ty_and_layout,
                     &|output, visited| {
                         push_closure_or_generator_name(tcx, def_id, substs, true, output, visited);
@@ -428,58 +425,17 @@ fn push_debuginfo_type_name<'tcx>(
 
     /// MSVC names enums differently than other platforms so that the debugging visualization
     // format (natvis) is able to understand enums and render the active variant correctly in the
-    // debugger. For more information, look in `src/etc/natvis/intrinsic.natvis` and
-    // `EnumMemberDescriptionFactor::create_member_descriptions`.
+    // debugger. For more information, look in
+    // rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs.
     fn msvc_enum_fallback<'tcx>(
-        tcx: TyCtxt<'tcx>,
         ty_and_layout: TyAndLayout<'tcx>,
         push_inner: &dyn Fn(/*output*/ &mut String, /*visited*/ &mut FxHashSet<Ty<'tcx>>),
         output: &mut String,
         visited: &mut FxHashSet<Ty<'tcx>>,
     ) {
         debug_assert!(!wants_c_like_enum_debuginfo(ty_and_layout));
-        let ty = ty_and_layout.ty;
-
-        output.push_str("enum$<");
+        output.push_str("enum2$<");
         push_inner(output, visited);
-
-        let variant_name = |variant_index| match ty.kind() {
-            ty::Adt(adt_def, _) => {
-                debug_assert!(adt_def.is_enum());
-                Cow::from(adt_def.variant(variant_index).name.as_str())
-            }
-            ty::Generator(..) => GeneratorSubsts::variant_name(variant_index),
-            _ => unreachable!(),
-        };
-
-        if let Variants::Multiple {
-            tag_encoding: TagEncoding::Niche { dataful_variant, .. },
-            tag,
-            variants,
-            ..
-        } = &ty_and_layout.variants
-        {
-            let dataful_variant_layout = &variants[*dataful_variant];
-
-            // calculate the range of values for the dataful variant
-            let dataful_discriminant_range =
-                dataful_variant_layout.largest_niche().unwrap().valid_range;
-
-            let min = dataful_discriminant_range.start;
-            let min = tag.size(&tcx).truncate(min);
-
-            let max = dataful_discriminant_range.end;
-            let max = tag.size(&tcx).truncate(max);
-
-            let dataful_variant_name = variant_name(*dataful_variant);
-            write!(output, ", {}, {}, {}", min, max, dataful_variant_name).unwrap();
-        } else if let Variants::Single { index: variant_idx } = &ty_and_layout.variants {
-            // Uninhabited enums can't be constructed and should never need to be visualized so
-            // skip this step for them.
-            if !ty_and_layout.abi.is_uninhabited() {
-                write!(output, ", {}", variant_name(*variant_idx)).unwrap();
-            }
-        }
         push_close_angle_bracket(true, output);
     }
 
index ecad0518533ec7ef0511b2da25e23d21dc2a7a75..9062a83b8be4468decf0257cbb5105e3c4259dee 100644 (file)
     ("zhinxmin", Some(sym::riscv_target_feature)),
     ("zfh", Some(sym::riscv_target_feature)),
     ("zfhmin", Some(sym::riscv_target_feature)),
+    ("zba", Some(sym::riscv_target_feature)),
+    ("zbb", Some(sym::riscv_target_feature)),
+    ("zbc", Some(sym::riscv_target_feature)),
+    ("zbs", Some(sym::riscv_target_feature)),
     ("zbkb", Some(sym::riscv_target_feature)),
     ("zbkc", Some(sym::riscv_target_feature)),
     ("zbkx", Some(sym::riscv_target_feature)),
index fc2e6652a3d72267811bf589cec5aa9fd18df404..684877cae76776f025de733a7e9afea14017cdd1 100644 (file)
@@ -236,6 +236,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
 
     const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error
 
+    #[inline(always)]
+    fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+        ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
+    }
+
+    #[inline(always)]
+    fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+        ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
+    }
+
     fn load_mir(
         ecx: &InterpCx<'mir, 'tcx, Self>,
         instance: ty::InstanceDef<'tcx>,
index 71ccd1799fa95b19d26a49587ca129575d100dca..9b9919fcc2a3da2f695c836ef1c9b74307898374 100644 (file)
@@ -436,24 +436,12 @@ fn after_stack_pop(
     type AllocExtra = ();
     type FrameExtra = ();
 
-    #[inline(always)]
-    fn enforce_alignment(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
-        // We do not check for alignment to avoid having to carry an `Align`
-        // in `ConstValue::ByRef`.
-        false
-    }
-
     #[inline(always)]
     fn force_int_for_alignment_check(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
         // We do not support `force_int`.
         false
     }
 
-    #[inline(always)]
-    fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
-        false // for now, we don't enforce validity
-    }
-
     #[inline(always)]
     fn enforce_number_init(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
         true
index 6f6717721fb5a0df81c15a0e101c43dd3c95c7e1..f1b1855c3ec743193f4d75d9b2803072936afce2 100644 (file)
@@ -1005,6 +1005,10 @@ pub fn const_validate_operand(
     /// It will error if the bits at the destination do not match the ones described by the layout.
     #[inline(always)]
     pub fn validate_operand(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
+        // Note that we *could* actually be in CTFE here with `-Zextra-const-ub-checks`, but it's
+        // still correct to not use `ctfe_mode`: that mode is for validation of the final constant
+        // value, it rules out things like `UnsafeCell` in awkward places. It also can make checking
+        // recurse through references which, for now, we don't want here, either.
         self.validate_operand_internal(op, vec![], None, None)
     }
 }
index 1063f03d0e2191826e3a3e98d130edceaf7978e1..7272ae5aa0976b4a036eb244699fbaa2160a4313 100644 (file)
@@ -9,7 +9,6 @@
 #![feature(control_flow_enum)]
 #![feature(decl_macro)]
 #![feature(exact_size_is_empty)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
index ed4d8c95d1e6178d882bcaef5a3c9b5bad620a39..161c89e3242b9f660336c64da476154e48a9ca24 100644 (file)
@@ -839,17 +839,12 @@ fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) ->
             let mut promoted_operand = |ty, span| {
                 promoted.span = span;
                 promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
+                let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
                 let _const = tcx.mk_const(ty::ConstS {
                     ty,
                     kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
                         def,
-                        substs: InternalSubsts::for_item(tcx, def.did, |param, _| {
-                            if let ty::GenericParamDefKind::Lifetime = param.kind {
-                                tcx.lifetimes.re_erased.into()
-                            } else {
-                                tcx.mk_param_from_def(param)
-                            }
-                        }),
+                        substs,
                         promoted: Some(promoted_id),
                     }),
                 });
index 645673ef47aeb618faf16c7a4a4abce055170575..4af40d2062d3a79c275cfe22d841105e282bbb5d 100644 (file)
@@ -1,18 +1,18 @@
-borrowck-move-unsized =
+borrowck_move_unsized =
     cannot move a value of type `{$ty}`
     .label = the size of `{$ty}` cannot be statically determined
 
-borrowck-higher-ranked-lifetime-error =
+borrowck_higher_ranked_lifetime_error =
     higher-ranked lifetime error
 
-borrowck-could-not-prove =
+borrowck_could_not_prove =
     could not prove `{$predicate}`
 
-borrowck-could-not-normalize =
+borrowck_could_not_normalize =
     could not normalize `{$value}`
 
-borrowck-higher-ranked-subtype-error =
+borrowck_higher_ranked_subtype_error =
     higher-ranked subtype error
   
-generic-does-not-live-long-enough =
+generic_does_not_live_long_enough =
     `{$kind}` does not live long enough
\ No newline at end of file
index 1d3e33c81851f5cb84b1132f51fdda2a535f81ad..4d088e27b364ae36762db7512961333e7a34849f 100644 (file)
@@ -1,5 +1,5 @@
-builtin-macros-requires-cfg-pattern =
+builtin_macros_requires_cfg_pattern =
     macro requires a cfg-pattern as an argument
     .label = cfg-pattern required
 
-builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern
+builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
index 3f2ff86100160b0f2eead39e5ee5dbb1c696cee0..341f05efefdfb2a44cf9cdf0f040718efebc01fa 100644 (file)
@@ -1,31 +1,31 @@
-const-eval-unstable-in-stable =
+const_eval_unstable_in_stable =
     const-stable function cannot use `#[feature({$gate})]`
-    .unstable-sugg = if it is not part of the public API, make this function unstably const
-    .bypass-sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+    .unstable_sugg = if it is not part of the public API, make this function unstably const
+    .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
 
-const-eval-thread-local-access =
+const_eval_thread_local_access =
     thread-local statics cannot be accessed at compile-time
 
-const-eval-static-access =
+const_eval_static_access =
     {$kind}s cannot refer to statics
     .help = consider extracting the value of the `static` to a `const`, and referring to that
-    .teach-note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
-    .teach-help = To fix this, the value can be extracted to a `const` and then used.
+    .teach_note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
+    .teach_help = To fix this, the value can be extracted to a `const` and then used.
 
-const-eval-raw-ptr-to-int =
+const_eval_raw_ptr_to_int =
     pointers cannot be cast to integers during const eval
     .note = at compile-time, pointers do not have an integer value
     .note2 = avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
 
-const-eval-raw-ptr-comparison =
+const_eval_raw_ptr_comparison =
     pointers cannot be reliably compared during const eval
     .note = see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
 
-const-eval-panic-non-str = argument to `panic!()` in a const context must have type `&str`
+const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str`
 
-const-eval-mut-deref =
+const_eval_mut_deref =
     mutation through a reference is not allowed in {$kind}s
 
-const-eval-transient-mut-borrow = mutable references are not allowed in {$kind}s
+const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s
 
-const-eval-transient-mut-borrow-raw = raw mutable references are not allowed in {$kind}s
+const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s
index 8d506a3ea8bbc64ee4d9c2cc23cd2a423e1eea8c..bdfa22e77eb2fcdc1fa0df21cdd151b91f2566c9 100644 (file)
@@ -1,5 +1,5 @@
-expand-explain-doc-comment-outer =
+expand_explain_doc_comment_outer =
     outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
 
-expand-explain-doc-comment-inner =
+expand_explain_doc_comment_inner =
     inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
index 55e96e58e468866e7b93f1e265ee72d48250586f..973171147166438023f0e61ef11e8b1058cc666e 100644 (file)
@@ -1,22 +1,22 @@
-lint-array-into-iter =
+lint_array_into_iter =
     this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <{$target} as IntoIterator>::into_iter in Rust 2021
-    .use-iter-suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
-    .remove-into-iter-suggestion = or remove `.into_iter()` to iterate by value
-    .use-explicit-into-iter-suggestion =
+    .use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
+    .remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value
+    .use_explicit_into_iter_suggestion =
         or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
 
-lint-enum-intrinsics-mem-discriminant =
+lint_enum_intrinsics_mem_discriminant =
     the return value of `mem::discriminant` is unspecified when called with a non-enum type
     .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum.
 
-lint-enum-intrinsics-mem-variant =
+lint_enum_intrinsics_mem_variant =
     the return value of `mem::variant_count` is unspecified when called with a non-enum type
     .note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum.
 
-lint-expectation = this lint expectation is unfulfilled
+lint_expectation = this lint expectation is unfulfilled
     .note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
 
-lint-hidden-unicode-codepoints = unicode codepoint changing visible direction of text present in {$label}
+lint_hidden_unicode_codepoints = unicode codepoint changing visible direction of text present in {$label}
     .label = this {$label} contains {$count ->
         [one] an invisible
         *[other] invisible
@@ -25,68 +25,68 @@ lint-hidden-unicode-codepoints = unicode codepoint changing visible direction of
         *[other] 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
-    .suggestion-remove = if their presence wasn't intentional, you can remove them
-    .suggestion-escape = if you want to keep them but make them visible in your source code, you can escape them
-    .no-suggestion-note-escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}
+    .suggestion_remove = if their presence wasn't intentional, you can remove them
+    .suggestion_escape = if you want to keep them but make them visible in your source code, you can escape them
+    .no_suggestion_note_escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}
 
-lint-default-hash-types = prefer `{$preferred}` over `{$used}`, it has better performance
+lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance
     .note = a `use rustc_data_structures::fx::{$preferred}` may be necessary
 
-lint-query-instability = using `{$query}` can result in unstable query results
+lint_query_instability = using `{$query}` can result in unstable query results
     .note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
 
-lint-tykind-kind = usage of `ty::TyKind::<kind>`
+lint_tykind_kind = usage of `ty::TyKind::<kind>`
     .suggestion = try using `ty::<kind>` directly
 
-lint-tykind = usage of `ty::TyKind`
+lint_tykind = usage of `ty::TyKind`
     .help = try using `Ty` instead
 
-lint-ty-qualified = usage of qualified `ty::{$ty}`
+lint_ty_qualified = usage of qualified `ty::{$ty}`
     .suggestion = try importing it and using it unqualified
 
-lint-lintpass-by-hand = implementing `LintPass` by hand
+lint_lintpass_by_hand = implementing `LintPass` by hand
     .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
 
-lint-non-existant-doc-keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
+lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
     .help = only existing keywords are allowed in core/std
 
-lint-diag-out-of-impl =
+lint_diag_out_of_impl =
     diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
 
-lint-untranslatable-diag = diagnostics should be created using translatable messages
+lint_untranslatable_diag = diagnostics should be created using translatable messages
 
-lint-cstring-ptr = getting the inner pointer of a temporary `CString`
-    .as-ptr-label = this pointer will be invalid
-    .unwrap-label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
+lint_cstring_ptr = getting the inner pointer of a temporary `CString`
+    .as_ptr_label = this pointer will be invalid
+    .unwrap_label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
     .note = pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
     .help = for more information, see https://doc.rust-lang.org/reference/destructors.html
 
-lint-identifier-non-ascii-char = identifier contains non-ASCII characters
+lint_identifier_non_ascii_char = identifier contains non-ASCII characters
 
-lint-identifier-uncommon-codepoints = identifier contains uncommon Unicode codepoints
+lint_identifier_uncommon_codepoints = identifier contains uncommon Unicode codepoints
 
-lint-confusable-identifier-pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
+lint_confusable_identifier_pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
     .label = this is where the previous identifier occurred
 
-lint-mixed-script-confusables =
+lint_mixed_script_confusables =
     the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables
-    .includes-note = the usage includes {$includes}
+    .includes_note = the usage includes {$includes}
     .note = please recheck to make sure their usages are indeed what you want
 
-lint-non-fmt-panic = panic message is not a string literal
+lint_non_fmt_panic = panic message is not a string literal
     .note = this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021
-    .more-info-note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
-    .supports-fmt-note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
-    .supports-fmt-suggestion = remove the `format!(..)` macro call
-    .display-suggestion = add a "{"{"}{"}"}" format string to `Display` the message
-    .debug-suggestion =
+    .more_info_note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+    .supports_fmt_note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
+    .supports_fmt_suggestion = remove the `format!(..)` macro call
+    .display_suggestion = add a "{"{"}{"}"}" format string to `Display` the message
+    .debug_suggestion =
         add a "{"{"}:?{"}"}" format string to use the `Debug` implementation of `{$ty}`
-    .panic-suggestion = {$already_suggested ->
+    .panic_suggestion = {$already_suggested ->
         [true] or use
         *[false] use
     } std::panic::panic_any instead
 
-lint-non-fmt-panic-unused =
+lint_non_fmt_panic_unused =
     panic message contains {$count ->
         [one] an unused
         *[other] unused
@@ -95,13 +95,13 @@ lint-non-fmt-panic-unused =
         *[other] placeholders
     }
     .note = this message is not used as a format string when given without arguments, but will be in Rust 2021
-    .add-args-suggestion = add the missing {$count ->
+    .add_args_suggestion = add the missing {$count ->
         [one] argument
         *[other] arguments
     }
-    .add-fmt-suggestion = or add a "{"{"}{"}"}" format string to use the message literally
+    .add_fmt_suggestion = or add a "{"{"}{"}"}" format string to use the message literally
 
-lint-non-fmt-panic-braces =
+lint_non_fmt_panic_braces =
     panic message contains {$count ->
         [one] a brace
         *[other] braces
@@ -109,30 +109,30 @@ lint-non-fmt-panic-braces =
     .note = this message is not used as a format string, but will be in Rust 2021
     .suggestion = add a "{"{"}{"}"}" format string to use the message literally
 
-lint-non-camel-case-type = {$sort} `{$name}` should have an upper camel case name
+lint_non_camel_case_type = {$sort} `{$name}` should have an upper camel case name
     .suggestion = convert the identifier to upper camel case
     .label = should have an UpperCamelCase name
 
-lint-non-snake-case = {$sort} `{$name}` should have a snake case name
-    .rename-or-convert-suggestion = rename the identifier or convert it to a snake case raw identifier
-    .cannot-convert-note = `{$sc}` cannot be used as a raw identifier
-    .rename-suggestion = rename the identifier
-    .convert-suggestion = convert the identifier to snake case
+lint_non_snake_case = {$sort} `{$name}` should have a snake case name
+    .rename_or_convert_suggestion = rename the identifier or convert it to a snake case raw identifier
+    .cannot_convert_note = `{$sc}` cannot be used as a raw identifier
+    .rename_suggestion = rename the identifier
+    .convert_suggestion = convert the identifier to snake case
     .help = convert the identifier to snake case: `{$sc}`
     .label = should have a snake_case name
 
-lint-non-upper_case-global = {$sort} `{$name}` should have an upper case name
+lint_non_upper_case_global = {$sort} `{$name}` should have an upper case name
     .suggestion = convert the identifier to upper case
     .label = should have an UPPER_CASE name
 
-lint-noop-method-call = call to `.{$method}()` on a reference in this situation does nothing
+lint_noop_method_call = call to `.{$method}()` on a reference in this situation does nothing
     .label = unnecessary method call
     .note = the type `{$receiver_ty}` which `{$method}` is being called on is the same as the type returned from `{$method}`, so the method call does not do anything and can be removed
 
-lint-pass-by-value = passing `{$ty}` by reference
+lint_pass_by_value = passing `{$ty}` by reference
     .suggestion = try passing by value
 
-lint-redundant-semicolons =
+lint_redundant_semicolons =
     unnecessary trailing {$multiple ->
         [true] semicolons
         *[false] semicolon
@@ -142,254 +142,254 @@ lint-redundant-semicolons =
         *[false] this semicolon
     }
 
-lint-drop-trait-constraints =
+lint_drop_trait_constraints =
     bounds on `{$predicate}` are most likely incorrect, consider instead using `{$needs_drop}` to detect whether a type can be trivially dropped
 
-lint-drop-glue =
+lint_drop_glue =
     types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped
 
-lint-range-endpoint-out-of-range = range endpoint is out of range for `{$ty}`
+lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}`
     .suggestion = use an inclusive range instead
 
-lint-overflowing-bin-hex = literal out of range for `{$ty}`
-    .negative-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
-    .negative-becomes-note = and the value `-{$lit}` will become `{$actually}{$ty}`
-    .positive-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`
+lint_overflowing_bin_hex = literal out of range for `{$ty}`
+    .negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
+    .negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}`
+    .positive_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`
     .suggestion = consider using the type `{$suggestion_ty}` instead
     .help = consider using the type `{$suggestion_ty}` instead
 
-lint-overflowing-int = literal out of range for `{$ty}`
+lint_overflowing_int = literal out of range for `{$ty}`
     .note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
     .help = consider using the type `{$suggestion_ty}` instead
 
-lint-only-cast-u8-to-char = only `u8` can be cast into `char`
+lint_only_cast_u8_to_char = only `u8` can be cast into `char`
     .suggestion = use a `char` literal instead
 
-lint-overflowing-uint = literal out of range for `{$ty}`
+lint_overflowing_uint = literal out of range for `{$ty}`
     .note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
 
-lint-overflowing-literal = literal out of range for `{$ty}`
+lint_overflowing_literal = literal out of range for `{$ty}`
     .note = the literal `{$lit}` does not fit into the type `{$ty}` and will be converted to `{$ty}::INFINITY`
 
-lint-unused-comparisons = comparison is useless due to type limits
+lint_unused_comparisons = comparison is useless due to type limits
 
-lint-improper-ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
+lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
     .label = not FFI-safe
     .note = the type is defined here
 
-lint-improper-ctypes-opaque = opaque types have no C equivalent
+lint_improper_ctypes_opaque = opaque types have no C equivalent
 
-lint-improper-ctypes-fnptr-reason = this function pointer has Rust-specific calling convention
-lint-improper-ctypes-fnptr-help = consider using an `extern fn(...) -> ...` function pointer instead
+lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention
+lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead
 
-lint-improper-ctypes-tuple-reason = tuples have unspecified layout
-lint-improper-ctypes-tuple-help = consider using a struct instead
+lint_improper_ctypes_tuple_reason = tuples have unspecified layout
+lint_improper_ctypes_tuple_help = consider using a struct instead
 
-lint-improper-ctypes-str-reason = string slices have no C equivalent
-lint-improper-ctypes-str-help = consider using `*const u8` and a length instead
+lint_improper_ctypes_str_reason = string slices have no C equivalent
+lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
 
-lint-improper-ctypes-dyn = trait objects have no C equivalent
+lint_improper_ctypes_dyn = trait objects have no C equivalent
 
-lint-improper-ctypes-slice-reason = slices have no C equivalent
-lint-improper-ctypes-slice-help = consider using a raw pointer instead
+lint_improper_ctypes_slice_reason = slices have no C equivalent
+lint_improper_ctypes_slice_help = consider using a raw pointer instead
 
-lint-improper-ctypes-128bit = 128-bit integers don't currently have a known stable ABI
+lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stable ABI
 
-lint-improper-ctypes-char-reason = the `char` type has no C equivalent
-lint-improper-ctypes-char-help = consider using `u32` or `libc::wchar_t` instead
+lint_improper_ctypes_char_reason = the `char` type has no C equivalent
+lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
 
-lint-improper-ctypes-non-exhaustive = this enum is non-exhaustive
-lint-improper-ctypes-non-exhaustive-variant = this enum has non-exhaustive variants
+lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
+lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
 
-lint-improper-ctypes-enum-repr-reason = enum has no representation hint
-lint-improper-ctypes-enum-repr-help =
+lint_improper_ctypes_enum_repr_reason = enum has no representation hint
+lint_improper_ctypes_enum_repr_help =
     consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 
-lint-improper-ctypes-struct-fieldless-reason = this struct has no fields
-lint-improper-ctypes-struct-fieldless-help = consider adding a member to this struct
+lint_improper_ctypes_struct_fieldless_reason = this struct has no fields
+lint_improper_ctypes_struct_fieldless_help = consider adding a member to this struct
 
-lint-improper-ctypes-union-fieldless-reason = this union has no fields
-lint-improper-ctypes-union-fieldless-help = consider adding a member to this union
+lint_improper_ctypes_union_fieldless_reason = this union has no fields
+lint_improper_ctypes_union_fieldless_help = consider adding a member to this union
 
-lint-improper-ctypes-struct-non-exhaustive = this struct is non-exhaustive
-lint-improper-ctypes-union-non-exhaustive = this union is non-exhaustive
+lint_improper_ctypes_struct_non_exhaustive = this struct is non-exhaustive
+lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
 
-lint-improper-ctypes-struct-layout-reason = this struct has unspecified layout
-lint-improper-ctypes-struct-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+lint_improper_ctypes_struct_layout_reason = this struct has unspecified layout
+lint_improper_ctypes_struct_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 
-lint-improper-ctypes-union-layout-reason = this union has unspecified layout
-lint-improper-ctypes-union-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
+lint_improper_ctypes_union_layout_reason = this union has unspecified layout
+lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
 
-lint-improper-ctypes-box = box cannot be represented as a single pointer
+lint_improper_ctypes_box = box cannot be represented as a single pointer
 
-lint-improper-ctypes-enum-phantomdata = this enum contains a PhantomData field
+lint_improper_ctypes_enum_phantomdata = this enum contains a PhantomData field
 
-lint-improper-ctypes-struct-zst = this struct contains only zero-sized fields
+lint_improper_ctypes_struct_zst = this struct contains only zero-sized fields
 
-lint-improper-ctypes-array-reason = passing raw arrays by value is not FFI-safe
-lint-improper-ctypes-array-help = consider passing a pointer to the array
+lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe
+lint_improper_ctypes_array_help = consider passing a pointer to the array
 
-lint-improper-ctypes-only-phantomdata = composed only of `PhantomData`
+lint_improper_ctypes_only_phantomdata = composed only of `PhantomData`
 
-lint-variant-size-differences =
+lint_variant_size_differences =
     enum variant is more than three times larger ({$largest} bytes) than the next largest
 
-lint-atomic-ordering-load = atomic loads cannot have `Release` or `AcqRel` ordering
+lint_atomic_ordering_load = atomic loads cannot have `Release` or `AcqRel` ordering
     .help = consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
 
-lint-atomic-ordering-store = atomic stores cannot have `Acquire` or `AcqRel` ordering
+lint_atomic_ordering_store = atomic stores cannot have `Acquire` or `AcqRel` ordering
     .help = consider using ordering modes `Release`, `SeqCst` or `Relaxed`
 
-lint-atomic-ordering-fence = memory fences cannot have `Relaxed` ordering
+lint_atomic_ordering_fence = memory fences cannot have `Relaxed` ordering
     .help = consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`
 
-lint-atomic-ordering-invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write
+lint_atomic_ordering_invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write
     .label = invalid failure ordering
     .help = consider using `Acquire` or `Relaxed` failure ordering instead
 
-lint-unused-op = unused {$op} that must be used
+lint_unused_op = unused {$op} that must be used
     .label = the {$op} produces a value
     .suggestion = use `let _ = ...` to ignore the resulting value
 
-lint-unused-result = unused result of type `{$ty}`
+lint_unused_result = unused result of type `{$ty}`
 
-lint-unused-closure =
+lint_unused_closure =
     unused {$pre}{$count ->
         [one] closure
         *[other] closures
     }{$post} that must be used
     .note = closures are lazy and do nothing unless called
 
-lint-unused-generator =
+lint_unused_generator =
     unused {$pre}{$count ->
         [one] generator
         *[other] generator
     }{$post} that must be used
     .note = generators are lazy and do nothing unless resumed
 
-lint-unused-def = unused {$pre}`{$def}`{$post} that must be used
+lint_unused_def = unused {$pre}`{$def}`{$post} that must be used
 
-lint-path-statement-drop = path statement drops value
+lint_path_statement_drop = path statement drops value
     .suggestion = use `drop` to clarify the intent
 
-lint-path-statement-no-effect = path statement with no effect
+lint_path_statement_no_effect = path statement with no effect
 
-lint-unused-delim = unnecessary {$delim} around {$item}
+lint_unused_delim = unnecessary {$delim} around {$item}
     .suggestion = remove these {$delim}
 
-lint-unused-import-braces = braces around {$node} is unnecessary
+lint_unused_import_braces = braces around {$node} is unnecessary
 
-lint-unused-allocation = unnecessary allocation, use `&` instead
-lint-unused-allocation-mut = unnecessary allocation, use `&mut` instead
+lint_unused_allocation = unnecessary allocation, use `&` instead
+lint_unused_allocation_mut = unnecessary allocation, use `&mut` instead
 
-lint-builtin-while-true = denote infinite loops with `loop {"{"} ... {"}"}`
+lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}`
     .suggestion = use `loop`
 
-lint-builtin-box-pointers = type uses owned (Box type) pointers: {$ty}
+lint_builtin_box_pointers = type uses owned (Box type) pointers: {$ty}
 
-lint-builtin-non-shorthand-field-patterns = the `{$ident}:` in this pattern is redundant
+lint_builtin_non_shorthand_field_patterns = the `{$ident}:` in this pattern is redundant
     .suggestion = use shorthand field pattern
 
-lint-builtin-overridden-symbol-name =
+lint_builtin_overridden_symbol_name =
     the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
 
-lint-builtin-overridden-symbol-section =
+lint_builtin_overridden_symbol_section =
     the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them
 
-lint-builtin-allow-internal-unsafe =
+lint_builtin_allow_internal_unsafe =
     `allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
 
-lint-builtin-unsafe-block = usage of an `unsafe` block
+lint_builtin_unsafe_block = usage of an `unsafe` block
 
-lint-builtin-unsafe-trait = declaration of an `unsafe` trait
+lint_builtin_unsafe_trait = declaration of an `unsafe` trait
 
-lint-builtin-unsafe-impl = implementation of an `unsafe` trait
+lint_builtin_unsafe_impl = implementation of an `unsafe` trait
 
-lint-builtin-no-mangle-fn = declaration of a `no_mangle` function
-lint-builtin-export-name-fn = declaration of a function with `export_name`
-lint-builtin-link-section-fn = declaration of a function with `link_section`
+lint_builtin_no_mangle_fn = declaration of a `no_mangle` function
+lint_builtin_export_name_fn = declaration of a function with `export_name`
+lint_builtin_link_section_fn = declaration of a function with `link_section`
 
-lint-builtin-no-mangle-static = declaration of a `no_mangle` static
-lint-builtin-export-name-static = declaration of a static with `export_name`
-lint-builtin-link-section-static = declaration of a static with `link_section`
+lint_builtin_no_mangle_static = declaration of a `no_mangle` static
+lint_builtin_export_name_static = declaration of a static with `export_name`
+lint_builtin_link_section_static = declaration of a static with `link_section`
 
-lint-builtin-no-mangle-method = declaration of a `no_mangle` method
-lint-builtin-export-name-method = declaration of a method with `export_name`
+lint_builtin_no_mangle_method = declaration of a `no_mangle` method
+lint_builtin_export_name_method = declaration of a method with `export_name`
 
-lint-builtin-decl-unsafe-fn = declaration of an `unsafe` function
-lint-builtin-decl-unsafe-method = declaration of an `unsafe` method
-lint-builtin-impl-unsafe-method = implementation of an `unsafe` method
+lint_builtin_decl_unsafe_fn = declaration of an `unsafe` function
+lint_builtin_decl_unsafe_method = declaration of an `unsafe` method
+lint_builtin_impl_unsafe_method = implementation of an `unsafe` method
 
-lint-builtin-missing-doc = missing documentation for {$article} {$desc}
+lint_builtin_missing_doc = missing documentation for {$article} {$desc}
 
-lint-builtin-missing-copy-impl = type could implement `Copy`; consider adding `impl Copy`
+lint_builtin_missing_copy_impl = type could implement `Copy`; consider adding `impl Copy`
 
-lint-builtin-missing-debug-impl =
+lint_builtin_missing_debug_impl =
     type does not implement `{$debug}`; consider adding `#[derive(Debug)]` or a manual implementation
 
-lint-builtin-anonymous-params = anonymous parameters are deprecated and will be removed in the next edition
+lint_builtin_anonymous_params = anonymous parameters are deprecated and will be removed in the next edition
     .suggestion = try naming the parameter or explicitly ignoring it
 
-lint-builtin-deprecated-attr-link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
-lint-builtin-deprecated-attr-used = use of deprecated attribute `{$name}`: no longer used.
-lint-builtin-deprecated-attr-default-suggestion = remove this attribute
+lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
+lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used.
+lint_builtin_deprecated_attr_default_suggestion = remove this attribute
 
-lint-builtin-unused-doc-comment = unused doc comment
+lint_builtin_unused_doc_comment = unused doc comment
     .label = rustdoc does not generate documentation for {$kind}
-    .plain-help = use `//` for a plain comment
-    .block-help = use `/* */` for a plain comment
+    .plain_help = use `//` for a plain comment
+    .block_help = use `/* */` for a plain comment
 
-lint-builtin-no-mangle-generic = functions generic over types or consts must be mangled
+lint_builtin_no_mangle_generic = functions generic over types or consts must be mangled
     .suggestion = remove this attribute
 
-lint-builtin-const-no-mangle = const items should never be `#[no_mangle]`
+lint_builtin_const_no_mangle = const items should never be `#[no_mangle]`
     .suggestion = try a static value
 
-lint-builtin-mutable-transmutes =
+lint_builtin_mutable_transmutes =
     transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
 
-lint-builtin-unstable-features = unstable feature
+lint_builtin_unstable_features = unstable feature
 
-lint-builtin-unreachable-pub = unreachable `pub` {$what}
+lint_builtin_unreachable_pub = unreachable `pub` {$what}
     .suggestion = consider restricting its visibility
     .help = or consider exporting it for use by other crates
 
-lint-builtin-type-alias-bounds-help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
+lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
 
-lint-builtin-type-alias-where-clause = where clauses are not enforced in type aliases
+lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases
     .suggestion = the clause will not be checked when the type alias is used, and should be removed
 
-lint-builtin-type-alias-generic-bounds = bounds on generic parameters are not enforced in type aliases
+lint_builtin_type_alias_generic_bounds = bounds on generic parameters are not enforced in type aliases
     .suggestion = the bound will not be checked when the type alias is used, and should be removed
 
-lint-builtin-trivial-bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
+lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
 
-lint-builtin-ellipsis-inclusive-range-patterns = `...` range patterns are deprecated
+lint_builtin_ellipsis_inclusive_range_patterns = `...` range patterns are deprecated
     .suggestion = use `..=` for an inclusive range
 
-lint-builtin-unnameable-test-items = cannot test inner items
+lint_builtin_unnameable_test_items = cannot test inner items
 
-lint-builtin-keyword-idents = `{$kw}` is a keyword in the {$next} edition
+lint_builtin_keyword_idents = `{$kw}` is a keyword in the {$next} edition
     .suggestion = you can use a raw identifier to stay compatible
 
-lint-builtin-explicit-outlives = outlives requirements can be inferred
+lint_builtin_explicit_outlives = outlives requirements can be inferred
     .suggestion = remove {$count ->
         [one] this bound
         *[other] these bounds
     }
 
-lint-builtin-incomplete-features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
+lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
     .note = see issue #{$n} <https://github.com/rust-lang/rust/issues/{$n}> for more information
     .help = consider using `min_{$name}` instead, which is more stable and complete
 
-lint-builtin-clashing-extern-same-name = `{$this_fi}` redeclared with a different signature
-    .previous-decl-label = `{$orig}` previously declared here
-    .mismatch-label = this signature doesn't match the previous declaration
-lint-builtin-clashing-extern-diff-name = `{$this_fi}` redeclares `{$orig}` with a different signature
-    .previous-decl-label = `{$orig}` previously declared here
-    .mismatch-label = this signature doesn't match the previous declaration
+lint_builtin_clashing_extern_same_name = `{$this_fi}` redeclared with a different signature
+    .previous_decl_label = `{$orig}` previously declared here
+    .mismatch_label = this signature doesn't match the previous declaration
+lint_builtin_clashing_extern_diff_name = `{$this_fi}` redeclares `{$orig}` with a different signature
+    .previous_decl_label = `{$orig}` previously declared here
+    .mismatch_label = this signature doesn't match the previous declaration
 
-lint-builtin-deref-nullptr = dereferencing a null pointer
+lint_builtin_deref_nullptr = dereferencing a null pointer
     .label = this code causes undefined behavior when executed
 
-lint-builtin-asm-labels = avoid using named labels in inline assembly
+lint_builtin_asm_labels = avoid using named labels in inline assembly
index 076b1b1caed7278645fbe808cf3510cac370c2a5..7e583753618354415320138517d7883d068fadda 100644 (file)
@@ -1,34 +1,34 @@
-parser-struct-literal-body-without-path =
+parser_struct_literal_body_without_path =
     struct literal body without path
     .suggestion = you might have forgotten to add the struct literal inside the block
 
-parser-maybe-report-ambiguous-plus =
+parser_maybe_report_ambiguous_plus =
     ambiguous `+` in a type
     .suggestion = use parentheses to disambiguate
 
-parser-maybe-recover-from-bad-type-plus =
+parser_maybe_recover_from_bad_type_plus =
     expected a path on the left-hand side of `+`, not `{$ty}`
 
-parser-add-paren = try adding parentheses
+parser_add_paren = try adding parentheses
 
-parser-forgot-paren = perhaps you forgot parentheses?
+parser_forgot_paren = perhaps you forgot parentheses?
 
-parser-expect-path = expected a path
+parser_expect_path = expected a path
 
-parser-maybe-recover-from-bad-qpath-stage-2 =
+parser_maybe_recover_from_bad_qpath_stage_2 =
     missing angle brackets in associated item path
     .suggestion = try: `{$ty}`
 
-parser-incorrect-semicolon =
+parser_incorrect_semicolon =
     expected item, found `;`
     .suggestion = remove this semicolon
     .help = {$name} declarations are not followed by a semicolon
 
-parser-incorrect-use-of-await =
+parser_incorrect_use_of_await =
     incorrect use of `await`
-    .parentheses-suggestion = `await` is not a method call, remove the parentheses
-    .postfix-suggestion = `await` is a postfix operation
+    .parentheses_suggestion = `await` is not a method call, remove the parentheses
+    .postfix_suggestion = `await` is a postfix operation
 
-parser-in-in-typo =
+parser_in_in_typo =
     expected iterable, found keyword `in`
     .suggestion = remove the duplicated `in`
index d8056c77f0f4233cd1f01a689723b65cfc23a902..7374f6d3f27d3282c87816425c0dfa1611d002c1 100644 (file)
--passes-previously-accepted =
+-passes_previously_accepted =
     this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
--passes-see-issue =
+-passes_see_issue =
     see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
 
-passes-outer-crate-level-attr =
+passes_outer_crate_level_attr =
     crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
 
-passes-inner-crate-level-attr =
+passes_inner_crate_level_attr =
     crate-level attribute should be in the root module
 
-passes-ignored-attr-with-macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs
-    .warn = {-passes-previously-accepted}
-    .note = {-passes-see-issue(issue: "80564")}
+passes_ignored_attr_with_macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs
+    .warn = {-passes_previously_accepted}
+    .note = {-passes_see_issue(issue: "80564")}
 
-passes-ignored-attr = `#[{$sym}]` is ignored on struct fields and match arms
-    .warn = {-passes-previously-accepted}
-    .note = {-passes-see-issue(issue: "80564")}
+passes_ignored_attr = `#[{$sym}]` is ignored on struct fields and match arms
+    .warn = {-passes_previously_accepted}
+    .note = {-passes_see_issue(issue: "80564")}
 
-passes-inline-ignored-function-prototype = `#[inline]` is ignored on function prototypes
+passes_inline_ignored_function_prototype = `#[inline]` is ignored on function prototypes
 
-passes-inline-ignored-constants = `#[inline]` is ignored on constants
-    .warn = {-passes-previously-accepted}
-    .note = {-passes-see-issue(issue: "65833")}
+passes_inline_ignored_constants = `#[inline]` is ignored on constants
+    .warn = {-passes_previously_accepted}
+    .note = {-passes_see_issue(issue: "65833")}
 
-passes-inline-not-fn-or-closure = attribute should be applied to function or closure
+passes_inline_not_fn_or_closure = attribute should be applied to function or closure
     .label = not a function or closure
 
-passes-no-coverage-ignored-function-prototype = `#[no_coverage]` is ignored on function prototypes
+passes_no_coverage_ignored_function_prototype = `#[no_coverage]` is ignored on function prototypes
 
-passes-no-coverage-propagate =
+passes_no_coverage_propagate =
     `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
 
-passes-no-coverage-fn-defn = `#[no_coverage]` may only be applied to function definitions
+passes_no_coverage_fn_defn = `#[no_coverage]` may only be applied to function definitions
 
-passes-no-coverage-not-coverable = `#[no_coverage]` must be applied to coverable code
+passes_no_coverage_not_coverable = `#[no_coverage]` must be applied to coverable code
     .label = not coverable code
 
-passes-should-be-applied-to-fn = attribute should be applied to a function definition
+passes_should_be_applied_to_fn = attribute should be applied to a function definition
     .label = not a function definition
 
-passes-naked-tracked-caller = cannot use `#[track_caller]` with `#[naked]`
+passes_naked_tracked_caller = cannot use `#[track_caller]` with `#[naked]`
 
-passes-should-be-applied-to-struct-enum = attribute should be applied to a struct or enum
+passes_should_be_applied_to_struct_enum = attribute should be applied to a struct or enum
     .label = not a struct or enum
 
-passes-should-be-applied-to-trait = attribute should be applied to a trait
+passes_should_be_applied_to_trait = attribute should be applied to a trait
     .label = not a trait
 
-passes-target-feature-on-statement = {passes-should-be-applied-to-fn}
-    .warn = {-passes-previously-accepted}
-    .label = {passes-should-be-applied-to-fn.label}
+passes_target_feature_on_statement = {passes_should_be_applied_to_fn}
+    .warn = {-passes_previously_accepted}
+    .label = {passes_should_be_applied_to_fn.label}
 
-passes-should-be-applied-to-static = attribute should be applied to a static
+passes_should_be_applied_to_static = attribute should be applied to a static
     .label = not a static
 
-passes-doc-expect-str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
+passes_doc_expect_str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
 
-passes-doc-alias-empty = {$attr_str} attribute cannot have empty value
+passes_doc_alias_empty = {$attr_str} attribute cannot have empty value
 
-passes-doc-alias-bad-char = {$char_} character isn't allowed in {$attr_str}
+passes_doc_alias_bad_char = {$char_} character isn't allowed in {$attr_str}
 
-passes-doc-alias-start-end = {$attr_str} cannot start or end with ' '
+passes_doc_alias_start_end = {$attr_str} cannot start or end with ' '
 
-passes-doc-alias-bad-location = {$attr_str} isn't allowed on {$location}
+passes_doc_alias_bad_location = {$attr_str} isn't allowed on {$location}
 
-passes-doc-alias-not-an-alias = {$attr_str} is the same as the item's name
+passes_doc_alias_not_an_alias = {$attr_str} is the same as the item's name
 
-passes-doc-alias-duplicated = doc alias is duplicated
+passes_doc_alias_duplicated = doc alias is duplicated
     .label = first defined here
 
-passes-doc-alias-not-string-literal = `#[doc(alias("a"))]` expects string literals
+passes_doc_alias_not_string_literal = `#[doc(alias("a"))]` expects string literals
 
-passes-doc-alias-malformed =
+passes_doc_alias_malformed =
     doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]`
 
-passes-doc-keyword-empty-mod = `#[doc(keyword = "...")]` should be used on empty modules
+passes_doc_keyword_empty_mod = `#[doc(keyword = "...")]` should be used on empty modules
 
-passes-doc-keyword-not-mod = `#[doc(keyword = "...")]` should be used on modules
+passes_doc_keyword_not_mod = `#[doc(keyword = "...")]` should be used on modules
 
-passes-doc-keyword-invalid-ident = `{$doc_keyword}` is not a valid identifier
+passes_doc_keyword_invalid_ident = `{$doc_keyword}` is not a valid identifier
 
-passes-doc-fake-variadic-not-valid =
+passes_doc_fake_variadic_not_valid =
     `#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity
 
-passes-doc-keyword-only-impl = `#[doc(keyword = "...")]` should be used on impl blocks
+passes_doc_keyword_only_impl = `#[doc(keyword = "...")]` should be used on impl blocks
 
-passes-doc-inline-conflict-first = this attribute...
-passes-doc-inline-conflict-second = ...conflicts with this attribute
-passes-doc-inline-conflict = conflicting doc inlining attributes
+passes_doc_inline_conflict_first = this attribute...
+passes_doc_inline_conflict_second = ...conflicts with this attribute
+passes_doc_inline_conflict = conflicting doc inlining attributes
     .help = remove one of the conflicting attributes
 
-passes-doc-inline-only-use = this attribute can only be applied to a `use` item
+passes_doc_inline_only_use = this attribute can only be applied to a `use` item
     .label = only applicable on `use` items
-    .not-a-use-item-label = not a `use` item
+    .not_a_use_item_label = not a `use` item
     .note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
 
-passes-doc-attr-not-crate-level =
+passes_doc_attr_not_crate_level =
     `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute
 
-passes-attr-crate-level = this attribute can only be applied at the crate level
+passes_attr_crate_level = this attribute can only be applied at the crate level
     .suggestion = to apply to the crate, use an inner attribute
     .help = to apply to the crate, use an inner attribute
     .note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 
-passes-doc-test-unknown = unknown `doc(test)` attribute `{$path}`
+passes_doc_test_unknown = unknown `doc(test)` attribute `{$path}`
 
-passes-doc-test-takes-list = `#[doc(test(...)]` takes a list of attributes
+passes_doc_test_takes_list = `#[doc(test(...)]` takes a list of attributes
 
-passes-doc-primitive = `doc(primitive)` should never have been stable
+passes_doc_primitive = `doc(primitive)` should never have been stable
 
-passes-doc-test-unknown-any = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_any = unknown `doc` attribute `{$path}`
 
-passes-doc-test-unknown-spotlight = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_spotlight = unknown `doc` attribute `{$path}`
     .note = `doc(spotlight)` was renamed to `doc(notable_trait)`
     .suggestion = use `notable_trait` instead
-    .no-op-note = `doc(spotlight)` is now a no-op
+    .no_op_note = `doc(spotlight)` is now a no-op
 
-passes-doc-test-unknown-include = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_include = unknown `doc` attribute `{$path}`
     .suggestion = use `doc = include_str!` instead
 
-passes-doc-invalid = invalid `doc` attribute
+passes_doc_invalid = invalid `doc` attribute
 
-passes-pass-by-value = `pass_by_value` attribute should be applied to a struct, enum or type alias
+passes_pass_by_value = `pass_by_value` attribute should be applied to a struct, enum or type alias
     .label = is not a struct, enum or type alias
 
-passes-allow-incoherent-impl =
+passes_allow_incoherent_impl =
     `rustc_allow_incoherent_impl` attribute should be applied to impl items.
     .label = the only currently supported targets are inherent methods
 
-passes-has-incoherent-inherent-impl =
+passes_has_incoherent_inherent_impl =
     `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
     .label = only adts, extern types and traits are supported
 
-passes-must-use-async =
+passes_must_use_async =
     `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
     .label = this attribute does nothing, the `Future`s returned by async functions are already `must_use`
 
-passes-must-use-no-effect = `#[must_use]` has no effect when applied to {$article} {$target}
+passes_must_use_no_effect = `#[must_use]` has no effect when applied to {$article} {$target}
 
-passes-must-not-suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait
+passes_must_not_suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait
     .label = is not a struct, enum, or trait
 
-passes-cold = {passes-should-be-applied-to-fn}
-    .warn = {-passes-previously-accepted}
-    .label = {passes-should-be-applied-to-fn.label}
+passes_cold = {passes_should_be_applied_to_fn}
+    .warn = {-passes_previously_accepted}
+    .label = {passes_should_be_applied_to_fn.label}
 
-passes-link = attribute should be applied to an `extern` block with non-Rust ABI
-    .warn = {-passes-previously-accepted}
+passes_link = attribute should be applied to an `extern` block with non-Rust ABI
+    .warn = {-passes_previously_accepted}
     .label = not an `extern` block
 
-passes-link-name = attribute should be applied to a foreign function or static
-    .warn = {-passes-previously-accepted}
+passes_link_name = attribute should be applied to a foreign function or static
+    .warn = {-passes_previously_accepted}
     .label = not a foreign function or static
     .help = try `#[link(name = "{$value}")]` instead
 
-passes-no-link = attribute should be applied to an `extern crate` item
+passes_no_link = attribute should be applied to an `extern crate` item
     .label = not an `extern crate` item
 
-passes-export-name = attribute should be applied to a free function, impl method or static
+passes_export_name = attribute should be applied to a free function, impl method or static
     .label = not a free function, impl method or static
 
-passes-rustc-layout-scalar-valid-range-not-struct = attribute should be applied to a struct
+passes_rustc_layout_scalar_valid_range_not_struct = attribute should be applied to a struct
     .label = not a struct
 
-passes-rustc-layout-scalar-valid-range-arg = expected exactly one integer literal argument
+passes_rustc_layout_scalar_valid_range_arg = expected exactly one integer literal argument
 
-passes-rustc-legacy-const-generics-only = #[rustc_legacy_const_generics] functions must only have const generics
+passes_rustc_legacy_const_generics_only = #[rustc_legacy_const_generics] functions must only have const generics
     .label = non-const generic parameter
 
-passes-rustc-legacy-const-generics-index = #[rustc_legacy_const_generics] must have one index for each generic parameter
+passes_rustc_legacy_const_generics_index = #[rustc_legacy_const_generics] must have one index for each generic parameter
     .label = generic parameters
 
-passes-rustc-legacy-const-generics-index-exceed = index exceeds number of arguments
+passes_rustc_legacy_const_generics_index_exceed = index exceeds number of arguments
     .label = there {$arg_count ->
         [one] is
         *[other] are
@@ -181,87 +181,87 @@ passes-rustc-legacy-const-generics-index-exceed = index exceeds number of argume
         *[other] arguments
     }
 
-passes-rustc-legacy-const-generics-index-negative = arguments should be non-negative integers
+passes_rustc_legacy_const_generics_index_negative = arguments should be non-negative integers
 
-passes-rustc-dirty-clean = attribute requires -Z query-dep-graph to be enabled
+passes_rustc_dirty_clean = attribute requires -Z query-dep-graph to be enabled
 
-passes-link-section = attribute should be applied to a function or static
-    .warn = {-passes-previously-accepted}
+passes_link_section = attribute should be applied to a function or static
+    .warn = {-passes_previously_accepted}
     .label = not a function or static
 
-passes-no-mangle-foreign = `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
-    .warn = {-passes-previously-accepted}
+passes_no_mangle_foreign = `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
+    .warn = {-passes_previously_accepted}
     .label = foreign {$foreign_item_kind}
     .note = symbol names in extern blocks are not mangled
     .suggestion = remove this attribute
 
-passes-no-mangle = attribute should be applied to a free function, impl method or static
-    .warn = {-passes-previously-accepted}
+passes_no_mangle = attribute should be applied to a free function, impl method or static
+    .warn = {-passes_previously_accepted}
     .label = not a free function, impl method or static
 
-passes-repr-ident = meta item in `repr` must be an identifier
+passes_repr_ident = meta item in `repr` must be an identifier
 
-passes-repr-conflicting = conflicting representation hints
+passes_repr_conflicting = conflicting representation hints
 
-passes-used-static = attribute must be applied to a `static` variable
+passes_used_static = attribute must be applied to a `static` variable
 
-passes-used-compiler-linker = `used(compiler)` and `used(linker)` can't be used together
+passes_used_compiler_linker = `used(compiler)` and `used(linker)` can't be used together
 
-passes-allow-internal-unstable = attribute should be applied to a macro
+passes_allow_internal_unstable = attribute should be applied to a macro
     .label = not a macro
 
-passes-debug-visualizer-placement = attribute should be applied to a module
+passes_debug_visualizer_placement = attribute should be applied to a module
 
-passes-debug-visualizer-invalid = invalid argument
-    .note-1 = expected: `natvis_file = "..."`
-    .note-2 = OR
-    .note-3 = expected: `gdb_script_file = "..."`
+passes_debug_visualizer_invalid = invalid argument
+    .note_1 = expected: `natvis_file = "..."`
+    .note_2 = OR
+    .note_3 = expected: `gdb_script_file = "..."`
 
-passes-rustc-allow-const-fn-unstable = attribute should be applied to `const fn`
+passes_rustc_allow_const_fn_unstable = attribute should be applied to `const fn`
     .label = not a `const fn`
 
-passes-rustc-std-internal-symbol = attribute should be applied to functions or statics
+passes_rustc_std_internal_symbol = attribute should be applied to functions or statics
     .label = not a function or static
 
-passes-const-trait = attribute should be applied to a trait
+passes_const_trait = attribute should be applied to a trait
 
-passes-stability-promotable = attribute cannot be applied to an expression
+passes_stability_promotable = attribute cannot be applied to an expression
 
-passes-deprecated = attribute is ignored here
+passes_deprecated = attribute is ignored here
 
-passes-macro-use = `#[{$name}]` only has an effect on `extern crate` and modules
+passes_macro_use = `#[{$name}]` only has an effect on `extern crate` and modules
 
-passes-macro-export = `#[macro_export]` only has an effect on macro definitions
+passes_macro_export = `#[macro_export]` only has an effect on macro definitions
 
-passes-plugin-registrar = `#[plugin_registrar]` only has an effect on functions
+passes_plugin_registrar = `#[plugin_registrar]` only has an effect on functions
 
-passes-unused-empty-lints-note = attribute `{$name}` with an empty list has no effect
+passes_unused_empty_lints_note = attribute `{$name}` with an empty list has no effect
 
-passes-unused-no-lints-note = attribute `{$name}` without any lints has no effect
+passes_unused_no_lints_note = attribute `{$name}` without any lints has no effect
 
-passes-unused-default-method-body-const-note =
+passes_unused_default_method_body_const_note =
     `default_method_body_is_const` has been replaced with `#[const_trait]` on traits
 
-passes-unused = unused attribute
+passes_unused = unused attribute
     .suggestion = remove this attribute
 
-passes-non-exported-macro-invalid-attrs = attribute should be applied to function or closure
+passes_non_exported_macro_invalid_attrs = attribute should be applied to function or closure
     .label = not a function or closure
 
-passes-unused-duplicate = unused attribute
+passes_unused_duplicate = unused attribute
     .suggestion = remove this attribute
     .note = attribute also specified here
-    .warn = {-passes-previously-accepted}
+    .warn = {-passes_previously_accepted}
 
-passes-unused-multiple = multiple `{$name}` attributes
+passes_unused_multiple = multiple `{$name}` attributes
     .suggestion = remove this attribute
     .note = attribute also specified here
 
-passes-rustc-lint-opt-ty = `#[rustc_lint_opt_ty]` should be applied to a struct
+passes_rustc_lint_opt_ty = `#[rustc_lint_opt_ty]` should be applied to a struct
     .label = not a struct
 
-passes-rustc-lint-opt-deny-field-access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field
+passes_rustc_lint_opt_deny_field_access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field
     .label = not a field
 
-passes-link-ordinal = attribute should be applied to a foreign function or static
-    .label = not a foreign function or static
\ No newline at end of file
+passes_link_ordinal = attribute should be applied to a foreign function or static
+    .label = not a foreign function or static
index f8a750da93f8d3442af9adb9b59b813d1cb4c9bb..97050635f45bf4fd751d3e269353392757aa8bc3 100644 (file)
@@ -1,20 +1,20 @@
-privacy-field-is-private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
-privacy-field-is-private-is-update-syntax-label = field `{$field_name}` is private
-privacy-field-is-private-label = private field
+privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
+privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private
+privacy_field_is_private_label = private field
 
-privacy-item-is-private = {$kind} `{$descr}` is private
+privacy_item_is_private = {$kind} `{$descr}` is private
     .label = private {$kind}
-privacy-unnamed-item-is-private = {$kind} is private
+privacy_unnamed_item_is_private = {$kind} is private
     .label = private {$kind}
 
-privacy-in-public-interface = {$vis_descr} {$kind} `{$descr}` in public interface
+privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interface
     .label = can't leak {$vis_descr} {$kind}
-    .visibility-label = `{$descr}` declared as {$vis_descr}
+    .visibility_label = `{$descr}` declared as {$vis_descr}
 
-privacy-from-private-dep-in-public-interface =
+privacy_from_private_dep_in_public_interface =
     {$kind} `{$descr}` from private dependency '{$krate}' in public interface
 
-private-in-public-lint =
+private_in_public_lint =
     {$vis_descr} {$kind} `{$descr}` in public interface (error {$kind ->
         [trait] E0445
         *[other] E0446
index c61735a57e163aaf929049df2823e9a326b52588..494b8f913934f9c2f0bc165b10f75f8aba646d81 100644 (file)
-typeck-field-multiply-specified-in-initializer =
+typeck_field_multiply_specified_in_initializer =
     field `{$ident}` specified more than once
     .label = used more than once
-    .previous-use-label = first use of `{$ident}`
+    .previous_use_label = first use of `{$ident}`
 
-typeck-unrecognized-atomic-operation =
+typeck_unrecognized_atomic_operation =
     unrecognized atomic operation function: `{$op}`
     .label = unrecognized atomic operation
 
-typeck-wrong-number-of-generic-arguments-to-intrinsic =
+typeck_wrong_number_of_generic_arguments_to_intrinsic =
     intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected}
     .label = expected {$expected} {$descr} {$expected ->
         [one] parameter
         *[other] parameters
     }
 
-typeck-unrecognized-intrinsic-function =
+typeck_unrecognized_intrinsic_function =
     unrecognized intrinsic function: `{$name}`
     .label = unrecognized intrinsic
 
-typeck-lifetimes-or-bounds-mismatch-on-trait =
+typeck_lifetimes_or_bounds_mismatch_on_trait =
     lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
     .label = lifetimes do not match {$item_kind} in trait
-    .generics-label = lifetimes in impl do not match this {$item_kind} in trait
+    .generics_label = lifetimes in impl do not match this {$item_kind} in trait
 
-typeck-drop-impl-on-wrong-item =
+typeck_drop_impl_on_wrong_item =
     the `Drop` trait may only be implemented for structs, enums, and unions
     .label = must be a struct, enum, or union
 
-typeck-field-already-declared =
+typeck_field_already_declared =
     field `{$field_name}` is already declared
     .label = field already declared
-    .previous-decl-label = `{$field_name}` first declared here
+    .previous_decl_label = `{$field_name}` first declared here
 
-typeck-copy-impl-on-type-with-dtor =
+typeck_copy_impl_on_type_with_dtor =
     the trait `Copy` may not be implemented for this type; the type has a destructor
     .label = `Copy` not allowed on types with destructors
 
-typeck-multiple-relaxed-default-bounds =
+typeck_multiple_relaxed_default_bounds =
     type parameter has more than one relaxed default bound, only one is supported
 
-typeck-copy-impl-on-non-adt =
+typeck_copy_impl_on_non_adt =
     the trait `Copy` may not be implemented for this type
     .label = type is not a structure or enumeration
 
-typeck-trait-object-declared-with-no-traits =
+typeck_trait_object_declared_with_no_traits =
     at least one trait is required for an object type
-    .alias-span = this alias does not contain a trait
+    .alias_span = this alias does not contain a trait
 
-typeck-ambiguous-lifetime-bound =
+typeck_ambiguous_lifetime_bound =
     ambiguous lifetime bound, explicit lifetime bound required
 
-typeck-assoc-type-binding-not-allowed =
+typeck_assoc_type_binding_not_allowed =
     associated type bindings are not allowed here
     .label = associated type not allowed here
 
-typeck-functional-record-update-on-non-struct =
+typeck_functional_record_update_on_non_struct =
     functional record update syntax requires a struct
 
-typeck-typeof-reserved-keyword-used =
+typeck_typeof_reserved_keyword_used =
     `typeof` is a reserved keyword but unimplemented
     .suggestion = consider replacing `typeof(...)` with an actual type
     .label = reserved keyword
 
-typeck-return-stmt-outside-of-fn-body =
+typeck_return_stmt_outside_of_fn_body =
     return statement outside of function body
-    .encl-body-label = the return is part of this body...
-    .encl-fn-label = ...not the enclosing function body
+    .encl_body_label = the return is part of this body...
+    .encl_fn_label = ...not the enclosing function body
 
-typeck-yield-expr-outside-of-generator =
+typeck_yield_expr_outside_of_generator =
     yield expression outside of generator literal
 
-typeck-struct-expr-non-exhaustive =
+typeck_struct_expr_non_exhaustive =
     cannot create non-exhaustive {$what} using struct expression
 
-typeck-method-call-on-unknown-type =
+typeck_method_call_on_unknown_type =
     the type of this value must be known to call a method on a raw pointer on it
 
-typeck-value-of-associated-struct-already-specified =
+typeck_value_of_associated_struct_already_specified =
     the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified
     .label = re-bound here
-    .previous-bound-label = `{$item_name}` bound here first
+    .previous_bound_label = `{$item_name}` bound here first
 
-typeck-address-of-temporary-taken = cannot take address of a temporary
+typeck_address_of_temporary_taken = cannot take address of a temporary
     .label = temporary value
 
-typeck-add-return-type-add = try adding a return type
+typeck_add_return_type_add = try adding a return type
 
-typeck-add-return-type-missing-here = a return type might be missing here
+typeck_add_return_type_missing_here = a return type might be missing here
 
-typeck-expected-default-return-type = expected `()` because of default return type
+typeck_expected_default_return_type = expected `()` because of default return type
 
-typeck-expected-return-type = expected `{$expected}` because of return type
+typeck_expected_return_type = expected `{$expected}` because of return type
 
-typeck-unconstrained-opaque-type = unconstrained opaque type
+typeck_unconstrained_opaque_type = unconstrained opaque type
     .note = `{$name}` must be used in combination with a concrete type within the same module
 
-typeck-missing-type-params =
+typeck_missing_type_params =
     the type {$parameterCount ->
         [one] parameter
         *[other] parameters
@@ -111,15 +111,15 @@ typeck-missing-type-params =
         [one] type
         *[other] types
     }
-    .no-suggestion-label = missing {$parameterCount ->
+    .no_suggestion_label = missing {$parameterCount ->
         [one] reference
         *[other] references
     } to {$parameters}
     .note = because of the default `Self` reference, type parameters must be specified on object types
 
-typeck-manual-implementation =
+typeck_manual_implementation =
     manual implementations of `{$trait_name}` are experimental
     .label = manual implementations of `{$trait_name}` are experimental
     .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-typeck-substs-on-overridden-impl = could not resolve substs on overridden impl
+typeck_substs_on_overridden_impl = could not resolve substs on overridden impl
index 2ac5c1960cd56acd6913ad5c95857304c29c6f8d..9e73a399809276c526153013509cae4a178bc4d7 100644 (file)
@@ -1,4 +1,3 @@
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(once_cell)]
 #![feature(rustc_attrs)]
 #![feature(type_alias_impl_trait)]
index 61d953cd6f1ccb71e36f92c96ab40fdd4853f641..753e2f07c042eb81cf74b4b961d1fbf88cb44645 100644 (file)
@@ -273,40 +273,58 @@ fn translate_message<'a>(
             DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
         };
 
-        let bundle = match self.fluent_bundle() {
-            Some(bundle) if bundle.has_message(&identifier) => bundle,
-            _ => self.fallback_fluent_bundle(),
-        };
+        let translate_with_bundle = |bundle: &'a FluentBundle| -> Option<(Cow<'_, str>, Vec<_>)> {
+            let message = bundle.get_message(&identifier)?;
+            let value = match attr {
+                Some(attr) => message.get_attribute(attr)?.value(),
+                None => message.value()?,
+            };
+            debug!(?message, ?value);
 
-        let message = bundle.get_message(&identifier).expect("missing diagnostic in fluent bundle");
-        let value = match attr {
-            Some(attr) => {
-                if let Some(attr) = message.get_attribute(attr) {
-                    attr.value()
-                } else {
-                    panic!("missing attribute `{attr}` in fluent message `{identifier}`")
-                }
-            }
-            None => {
-                if let Some(value) = message.value() {
-                    value
-                } else {
-                    panic!("missing value in fluent message `{identifier}`")
-                }
-            }
+            let mut errs = vec![];
+            let translated = bundle.format_pattern(value, Some(&args), &mut errs);
+            debug!(?translated, ?errs);
+            Some((translated, errs))
         };
 
-        let mut err = vec![];
-        let translated = bundle.format_pattern(value, Some(&args), &mut err);
-        trace!(?translated, ?err);
-        debug_assert!(
-            err.is_empty(),
-            "identifier: {:?}, args: {:?}, errors: {:?}",
-            identifier,
-            args,
-            err
-        );
-        translated
+        self.fluent_bundle()
+            .and_then(|bundle| translate_with_bundle(bundle))
+            // If `translate_with_bundle` returns `None` with the primary bundle, this is likely
+            // just that the primary bundle doesn't contain the message being translated, so
+            // proceed to the fallback bundle.
+            //
+            // However, when errors are produced from translation, then that means the translation
+            // is broken (e.g. `{$foo}` exists in a translation but `foo` isn't provided).
+            //
+            // In debug builds, assert so that compiler devs can spot the broken translation and
+            // fix it..
+            .inspect(|(_, errs)| {
+                debug_assert!(
+                    errs.is_empty(),
+                    "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
+                    identifier,
+                    attr,
+                    args,
+                    errs
+                );
+            })
+            // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so
+            // just hide it and try with the fallback bundle.
+            .filter(|(_, errs)| errs.is_empty())
+            .or_else(|| translate_with_bundle(self.fallback_fluent_bundle()))
+            .map(|(translated, errs)| {
+                // Always bail out for errors with the fallback bundle.
+                assert!(
+                    errs.is_empty(),
+                    "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
+                    identifier,
+                    attr,
+                    args,
+                    errs
+                );
+                translated
+            })
+            .expect("failed to find message in primary or fallback fluent bundles")
     }
 
     /// Formats the substitutions of the primary_span
index 15c1858023de7f0de498a09245e7257fda773372..d2eb4f212eb88f67bf29f5a84a49ff5214a68298 100644 (file)
@@ -5,10 +5,10 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(drain_filter)]
 #![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
+#![feature(adt_const_params)]
 #![feature(let_else)]
 #![feature(never_type)]
-#![feature(adt_const_params)]
+#![feature(result_option_inspect)]
 #![feature(rustc_attrs)]
 #![allow(incomplete_features)]
 #![allow(rustc::potential_query_instability)]
index 20d01b6dc2688d9d8ba34a751490b65f5a74efee..91a183427843e941c59db125f62d054116d0c6d1 100644 (file)
@@ -2,7 +2,6 @@
 #![feature(associated_type_bounds)]
 #![feature(associated_type_defaults)]
 #![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(macro_metavar_expr)]
 #![feature(proc_macro_diagnostic)]
index 7a87a3e4882601700eb7e5ebd1ef9272d4769d8a..2610d0b92d8f39e9e29494aa0e7e4c01ac1d161d 100644 (file)
@@ -3332,12 +3332,14 @@ pub enum Node<'hir> {
     Field(&'hir FieldDef<'hir>),
     AnonConst(&'hir AnonConst),
     Expr(&'hir Expr<'hir>),
+    ExprField(&'hir ExprField<'hir>),
     Stmt(&'hir Stmt<'hir>),
     PathSegment(&'hir PathSegment<'hir>),
     Ty(&'hir Ty<'hir>),
     TypeBinding(&'hir TypeBinding<'hir>),
     TraitRef(&'hir TraitRef<'hir>),
     Pat(&'hir Pat<'hir>),
+    PatField(&'hir PatField<'hir>),
     Arm(&'hir Arm<'hir>),
     Block(&'hir Block<'hir>),
     Local(&'hir Local<'hir>),
@@ -3388,6 +3390,8 @@ pub fn ident(&self) -> Option<Ident> {
             | Node::Block(..)
             | Node::Ctor(..)
             | Node::Pat(..)
+            | Node::PatField(..)
+            | Node::ExprField(..)
             | Node::Arm(..)
             | Node::Local(..)
             | Node::Crate(..)
index 51b1bfad8a0d85a2cbdcc16d9178866dab6a57b5..900370937f79aecd7c507c71aacea749b2bcd9c5 100644 (file)
@@ -325,6 +325,9 @@ fn visit_arm(&mut self, a: &'v Arm<'v>) {
     fn visit_pat(&mut self, p: &'v Pat<'v>) {
         walk_pat(self, p)
     }
+    fn visit_pat_field(&mut self, f: &'v PatField<'v>) {
+        walk_pat_field(self, f)
+    }
     fn visit_array_length(&mut self, len: &'v ArrayLen) {
         walk_array_len(self, len)
     }
@@ -337,6 +340,9 @@ fn visit_expr(&mut self, ex: &'v Expr<'v>) {
     fn visit_let_expr(&mut self, lex: &'v Let<'v>) {
         walk_let_expr(self, lex)
     }
+    fn visit_expr_field(&mut self, field: &'v ExprField<'v>) {
+        walk_expr_field(self, field)
+    }
     fn visit_ty(&mut self, t: &'v Ty<'v>) {
         walk_ty(self, t)
     }
@@ -761,11 +767,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
         }
         PatKind::Struct(ref qpath, fields, _) => {
             visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
-            for field in fields {
-                visitor.visit_id(field.hir_id);
-                visitor.visit_ident(field.ident);
-                visitor.visit_pat(&field.pat)
-            }
+            walk_list!(visitor, visit_pat_field, fields);
         }
         PatKind::Or(pats) => walk_list!(visitor, visit_pat, pats),
         PatKind::Tuple(tuple_elements, _) => {
@@ -792,6 +794,12 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
     }
 }
 
+pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'v>) {
+    visitor.visit_id(field.hir_id);
+    visitor.visit_ident(field.ident);
+    visitor.visit_pat(&field.pat)
+}
+
 pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) {
     visitor.visit_id(foreign_item.hir_id());
     visitor.visit_ident(foreign_item.ident);
@@ -1059,6 +1067,12 @@ pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>)
     walk_list!(visitor, visit_ty, let_expr.ty);
 }
 
+pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) {
+    visitor.visit_id(field.hir_id);
+    visitor.visit_ident(field.ident);
+    visitor.visit_expr(&field.expr)
+}
+
 pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) {
     visitor.visit_id(expression.hir_id);
     match expression.kind {
@@ -1073,11 +1087,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
         }
         ExprKind::Struct(ref qpath, fields, ref optional_base) => {
             visitor.visit_qpath(qpath, expression.hir_id, expression.span);
-            for field in fields {
-                visitor.visit_id(field.hir_id);
-                visitor.visit_ident(field.ident);
-                visitor.visit_expr(&field.expr)
-            }
+            walk_list!(visitor, visit_expr_field, fields);
             walk_list!(visitor, visit_expr, optional_base);
         }
         ExprKind::Tup(subexpressions) => {
index 6236dea10c88f3c23258a1821f56199c7bef3085..78bfd7191dba9b3f713377ff4830ac3667644988 100644 (file)
@@ -56,6 +56,8 @@ pub enum Target {
     GenericParam(GenericParamKind),
     MacroDef,
     Param,
+    PatField,
+    ExprField,
 }
 
 impl Display for Target {
@@ -183,6 +185,8 @@ pub fn name(self) -> &'static str {
             },
             Target::MacroDef => "macro def",
             Target::Param => "function param",
+            Target::PatField => "pattern field",
+            Target::ExprField => "struct field",
         }
     }
 }
index e0179bd3ed1e85afc11a512ad3dc452dcf1a0621..e6fcb84730ea4701b8fd7c8e41d3e842600a7206 100644 (file)
@@ -83,12 +83,14 @@ pub fn print_node(&mut self, node: Node<'_>) {
             Node::Variant(a) => self.print_variant(a),
             Node::AnonConst(a) => self.print_anon_const(a),
             Node::Expr(a) => self.print_expr(a),
+            Node::ExprField(a) => self.print_expr_field(&a),
             Node::Stmt(a) => self.print_stmt(a),
             Node::PathSegment(a) => self.print_path_segment(a),
             Node::Ty(a) => self.print_type(a),
             Node::TypeBinding(a) => self.print_type_binding(a),
             Node::TraitRef(a) => self.print_trait_ref(a),
             Node::Pat(a) => self.print_pat(a),
+            Node::PatField(a) => self.print_patfield(&a),
             Node::Arm(a) => self.print_arm(a),
             Node::Infer(_) => self.word("_"),
             Node::Block(a) => {
@@ -911,6 +913,10 @@ pub fn print_local(
         if let Some(els) = els {
             self.nbsp();
             self.word_space("else");
+            // containing cbox, will be closed by print-block at `}`
+            self.cbox(0);
+            // head-box, will be closed by print-block after `{`
+            self.ibox(0);
             self.print_block(els);
         }
 
@@ -1123,20 +1129,7 @@ fn print_expr_struct(
     ) {
         self.print_qpath(qpath, true);
         self.word("{");
-        self.commasep_cmnt(
-            Consistent,
-            fields,
-            |s, field| {
-                s.ibox(INDENT_UNIT);
-                if !field.is_shorthand {
-                    s.print_ident(field.ident);
-                    s.word_space(":");
-                }
-                s.print_expr(field.expr);
-                s.end()
-            },
-            |f| f.span,
-        );
+        self.commasep_cmnt(Consistent, fields, |s, field| s.print_expr_field(field), |f| f.span);
         if let Some(expr) = wth {
             self.ibox(INDENT_UNIT);
             if !fields.is_empty() {
@@ -1153,6 +1146,20 @@ fn print_expr_struct(
         self.word("}");
     }
 
+    fn print_expr_field(&mut self, field: &hir::ExprField<'_>) {
+        if self.attrs(field.hir_id).is_empty() {
+            self.space();
+        }
+        self.cbox(INDENT_UNIT);
+        self.print_outer_attributes(&self.attrs(field.hir_id));
+        if !field.is_shorthand {
+            self.print_ident(field.ident);
+            self.word_space(":");
+        }
+        self.print_expr(&field.expr);
+        self.end()
+    }
+
     fn print_expr_tup(&mut self, exprs: &[hir::Expr<'_>]) {
         self.popen();
         self.commasep_exprs(Inconsistent, exprs);
@@ -1799,20 +1806,7 @@ pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
                 if !empty {
                     self.space();
                 }
-                self.commasep_cmnt(
-                    Consistent,
-                    fields,
-                    |s, f| {
-                        s.cbox(INDENT_UNIT);
-                        if !f.is_shorthand {
-                            s.print_ident(f.ident);
-                            s.word_nbsp(":");
-                        }
-                        s.print_pat(f.pat);
-                        s.end()
-                    },
-                    |f| f.pat.span,
-                );
+                self.commasep_cmnt(Consistent, &fields, |s, f| s.print_patfield(f), |f| f.pat.span);
                 if etc {
                     if !fields.is_empty() {
                         self.word_space(",");
@@ -1907,6 +1901,20 @@ pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
         self.ann.post(self, AnnNode::Pat(pat))
     }
 
+    pub fn print_patfield(&mut self, field: &hir::PatField<'_>) {
+        if self.attrs(field.hir_id).is_empty() {
+            self.space();
+        }
+        self.cbox(INDENT_UNIT);
+        self.print_outer_attributes(&self.attrs(field.hir_id));
+        if !field.is_shorthand {
+            self.print_ident(field.ident);
+            self.word_nbsp(":");
+        }
+        self.print_pat(field.pat);
+        self.end();
+    }
+
     pub fn print_param(&mut self, arg: &hir::Param<'_>) {
         self.print_outer_attributes(self.attrs(arg.hir_id));
         self.print_pat(arg.pat);
index 30ff364210da8610fa0b73cbcf43eb83affe04a1..4172ce3bb306a22add12777d422cf05834e58ef4 100644 (file)
@@ -172,7 +172,9 @@ pub fn iter_enumerated(
     }
 
     #[inline]
-    pub fn indices(&self) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + 'static {
+    pub fn indices(
+        &self,
+    ) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + Clone + 'static {
         (0..self.len()).map(|n| I::new(n))
     }
 
index 20864c657ffd7b2425bebbe43f7e3cfe109dc413..fcb87a9f32f1eca292ce75eda184beb6456987fa 100644 (file)
@@ -457,7 +457,7 @@ fn process_errors(
     }
 
     /// Adds a note if the types come from similarly named crates
-    fn check_and_note_conflicting_crates(&self, err: &mut Diagnostic, terr: &TypeError<'tcx>) {
+    fn check_and_note_conflicting_crates(&self, err: &mut Diagnostic, terr: TypeError<'tcx>) {
         use hir::def_id::CrateNum;
         use rustc_hir::definitions::DisambiguatedDefPathData;
         use ty::print::Printer;
@@ -561,7 +561,7 @@ fn path_generic_args(
                 }
             }
         };
-        match *terr {
+        match terr {
             TypeError::Sorts(ref exp_found) => {
                 // if they are both "path types", there's a chance of ambiguity
                 // due to different versions of the same crate
@@ -583,7 +583,7 @@ fn note_error_origin(
         err: &mut Diagnostic,
         cause: &ObligationCause<'tcx>,
         exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
-        terr: &TypeError<'tcx>,
+        terr: TypeError<'tcx>,
     ) {
         match *cause.code() {
             ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => {
@@ -1424,7 +1424,7 @@ fn lifetime_display(lifetime: Region<'_>) -> String {
     /// E0271, like `src/test/ui/issues/issue-39970.stderr`.
     #[tracing::instrument(
         level = "debug",
-        skip(self, diag, secondary_span, swap_secondary_and_primary, force_label)
+        skip(self, diag, secondary_span, swap_secondary_and_primary, prefer_label)
     )]
     pub fn note_type_err(
         &self,
@@ -1432,9 +1432,9 @@ pub fn note_type_err(
         cause: &ObligationCause<'tcx>,
         secondary_span: Option<(Span, String)>,
         mut values: Option<ValuePairs<'tcx>>,
-        terr: &TypeError<'tcx>,
+        terr: TypeError<'tcx>,
         swap_secondary_and_primary: bool,
-        force_label: bool,
+        prefer_label: bool,
     ) {
         let span = cause.span();
 
@@ -1612,7 +1612,7 @@ enum Mismatch<'a> {
             TypeError::ObjectUnsafeCoercion(_) => {}
             _ => {
                 let mut label_or_note = |span: Span, msg: &str| {
-                    if force_label || &[span] == diag.span.primary_spans() {
+                    if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
                         diag.span_label(span, msg);
                     } else {
                         diag.span_note(span, msg);
@@ -1713,7 +1713,7 @@ enum Mismatch<'a> {
             ty::error::TypeError::Sorts(terr)
                 if exp_found.map_or(false, |ef| terr.found == ef.found) =>
             {
-                Some(*terr)
+                Some(terr)
             }
             _ => exp_found,
         };
@@ -2091,7 +2091,7 @@ fn suggest_as_ref_where_appropriate(
     pub fn report_and_explain_type_error(
         &self,
         trace: TypeTrace<'tcx>,
-        terr: &TypeError<'tcx>,
+        terr: TypeError<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         use crate::traits::ObligationCauseCode::MatchExpressionArm;
 
@@ -2781,12 +2781,12 @@ pub enum FailureCode {
 }
 
 pub trait ObligationCauseExt<'tcx> {
-    fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode;
+    fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode;
     fn as_requirement_str(&self) -> &'static str;
 }
 
 impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
-    fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode {
+    fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode {
         use self::FailureCode::*;
         use crate::traits::ObligationCauseCode::*;
         match self.code() {
@@ -2823,7 +2823,7 @@ fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode {
                 TypeError::IntrinsicCast => {
                     Error0308("cannot coerce intrinsics to function pointers")
                 }
-                TypeError::ObjectUnsafeCoercion(did) => Error0038(*did),
+                TypeError::ObjectUnsafeCoercion(did) => Error0038(did),
                 _ => Error0308("mismatched types"),
             },
         }
index c1940c5c0824a3e096f40f61e0622f0b1cbe6015..8dabdfd55c7e8f719dddb5134581853a567bead3 100644 (file)
@@ -107,7 +107,7 @@ pub(super) fn report_concrete_failure(
         match origin {
             infer::Subtype(box trace) => {
                 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
-                let mut err = self.report_and_explain_type_error(trace, &terr);
+                let mut err = self.report_and_explain_type_error(trace, terr);
                 match (*sub, *sup) {
                     (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
                     (ty::RePlaceholder(_), _) => {
@@ -406,7 +406,7 @@ pub(super) fn report_placeholder_failure(
             }
             infer::Subtype(box trace) => {
                 let terr = TypeError::RegionsPlaceholderMismatch;
-                return self.report_and_explain_type_error(trace, &terr);
+                return self.report_and_explain_type_error(trace, terr);
             }
             _ => return self.report_concrete_failure(placeholder_origin, sub, sup),
         }
index d7d1b5fa218680207754c6ad4af269bd2d595b16..1e26e7bb86ef03a1b086e7e9821d9f52cbd4fd28 100644 (file)
@@ -1527,8 +1527,7 @@ pub fn report_mismatched_types(
         actual: Ty<'tcx>,
         err: TypeError<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
-        let trace = TypeTrace::types(cause, true, expected, actual);
-        self.report_and_explain_type_error(trace, &err)
+        self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err)
     }
 
     pub fn report_mismatched_consts(
@@ -1538,8 +1537,7 @@ pub fn report_mismatched_consts(
         actual: ty::Const<'tcx>,
         err: TypeError<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
-        let trace = TypeTrace::consts(cause, true, expected, actual);
-        self.report_and_explain_type_error(trace, &err)
+        self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err)
     }
 
     pub fn replace_bound_vars_with_fresh_vars<T>(
index 490ba52503fb24a3692e080d11034c5543c5fa36..1c515f5ee572230d0c1e9f34722b52d61dd5e25b 100644 (file)
@@ -18,7 +18,6 @@
 #![feature(control_flow_enum)]
 #![feature(extend_one)]
 #![feature(label_break_value)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
index 94f81b6607798f7027a227e67d1719858e2046eb..dc4799e4afce14a373336a7c44ca9212c6cf15fd 100644 (file)
@@ -330,7 +330,7 @@ pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R
 }
 
 // JUSTIFICATION: before session exists, only config
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
 pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
     tracing::trace!("run_compiler");
     util::run_in_thread_pool_with_globals(
index a9fdfa241416812eb2cac218a211cd0d05739499..9207a0488623c94e9ef3aa5fd89280f20942666d 100644 (file)
@@ -1,4 +1,4 @@
-#![cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#![allow(rustc::bad_opt_access)]
 use crate::interface::parse_cfgspecs;
 
 use rustc_data_structures::fx::FxHashSet;
index 5e5596f13c845a5508039529c368b5e98a9dacbb..e74978485a21c818e780d1d3a923593a73de7b8c 100644 (file)
@@ -559,7 +559,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
     // command line, then reuse the empty `base` Vec to hold the types that
     // will be found in crate attributes.
     // JUSTIFICATION: before wrapper fn is available
-    #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+    #[allow(rustc::bad_opt_access)]
     let mut base = session.opts.crate_types.clone();
     if base.is_empty() {
         base.extend(attr_types);
index cbf1a6775550106534f89da3f30f31dcadad279f..580a4566869f052e34e57c311d5fcc169fd75cee 100644 (file)
@@ -101,6 +101,12 @@ fn visit_pat(&mut self, p: &'a ast::Pat) {
         run_early_pass!(self, check_pat_post, p);
     }
 
+    fn visit_pat_field(&mut self, field: &'a ast::PatField) {
+        self.with_lint_attrs(field.id, &field.attrs, |cx| {
+            ast_visit::walk_pat_field(cx, field);
+        });
+    }
+
     fn visit_anon_const(&mut self, c: &'a ast::AnonConst) {
         self.check_id(c.id);
         ast_visit::walk_anon_const(self, c);
@@ -219,9 +225,10 @@ fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) {
     }
 
     fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
-        run_early_pass!(self, check_generic_param, param);
-        self.check_id(param.id);
-        ast_visit::walk_generic_param(self, param);
+        self.with_lint_attrs(param.id, &param.attrs, |cx| {
+            run_early_pass!(cx, check_generic_param, param);
+            ast_visit::walk_generic_param(cx, param);
+        });
     }
 
     fn visit_generics(&mut self, g: &'a ast::Generics) {
index 7ab9302d835a2d57da295324c08020b11b2a2dda..1cabb58bbebfd3f1444a0c1b61ff7e2c2d7b2c0f 100644 (file)
@@ -766,6 +766,12 @@ fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
         })
     }
 
+    fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
+        self.with_lint_attrs(field.hir_id, |builder| {
+            intravisit::walk_expr_field(builder, field);
+        })
+    }
+
     fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
         self.with_lint_attrs(s.hir_id, |builder| {
             intravisit::walk_field_def(builder, s);
@@ -801,6 +807,18 @@ fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
             intravisit::walk_impl_item(builder, impl_item);
         });
     }
+
+    fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
+        self.with_lint_attrs(field.hir_id, |builder| {
+            intravisit::walk_pat_field(builder, field);
+        })
+    }
+
+    fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
+        self.with_lint_attrs(p.hir_id, |builder| {
+            intravisit::walk_generic_param(builder, p);
+        });
+    }
 }
 
 pub fn provide(providers: &mut Providers) {
index ae2088fbeb6f632e73955463fccca23e0cfd9e1a..f087c624917e8dcea75b1771450cac27feb60f96 100644 (file)
@@ -33,7 +33,6 @@
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(iter_order_by)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(never_type)]
 #![recursion_limit = "256"]
index 8d04d68bf1c2de3e9f0ddd5d237ddd666103654c..2868aabfa07e21eea1923154ec83865eb81b6538 100644 (file)
@@ -437,19 +437,14 @@ fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &hir::TraitItem<'_>)
 
     fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
         if let PatKind::Binding(_, hid, ident, _) = p.kind {
-            if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
+            if let hir::Node::PatField(field) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
             {
-                if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind {
-                    if field_pats
-                        .iter()
-                        .any(|field| !field.is_shorthand && field.pat.hir_id == p.hir_id)
-                    {
-                        // Only check if a new name has been introduced, to avoid warning
-                        // on both the struct definition and this pattern.
-                        self.check_snake_case(cx, "variable", &ident);
-                    }
-                    return;
+                if !field.is_shorthand {
+                    // Only check if a new name has been introduced, to avoid warning
+                    // on both the struct definition and this pattern.
+                    self.check_snake_case(cx, "variable", &ident);
                 }
+                return;
             }
             self.check_snake_case(cx, "variable", &ident);
         }
index 5c07afeb7aa8f73f0794bbb3ba26c5a55131ee2f..cafd2c6e679949d5150102e02e452d706a408e35 100644 (file)
@@ -125,45 +125,51 @@ fn lint_overflowing_range_endpoint<'tcx>(
     lit_val: u128,
     max: u128,
     expr: &'tcx hir::Expr<'tcx>,
-    parent_expr: &'tcx hir::Expr<'tcx>,
     ty: &str,
 ) -> bool {
     // We only want to handle exclusive (`..`) ranges,
     // which are represented as `ExprKind::Struct`.
+    let par_id = cx.tcx.hir().get_parent_node(expr.hir_id);
+    let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false };
+    let field_par_id = cx.tcx.hir().get_parent_node(field.hir_id);
+    let Node::Expr(struct_expr) = cx.tcx.hir().get(field_par_id) else { return false };
+    if !is_range_literal(struct_expr) {
+        return false;
+    };
+    let ExprKind::Struct(_, eps, _) = &struct_expr.kind else { return false };
+    if eps.len() != 2 {
+        return false;
+    }
+
     let mut overwritten = false;
-    if let ExprKind::Struct(_, eps, _) = &parent_expr.kind {
-        if eps.len() != 2 {
-            return false;
-        }
-        // We can suggest using an inclusive range
-        // (`..=`) instead only if it is the `end` that is
-        // overflowing and only by 1.
-        if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
-            cx.struct_span_lint(OVERFLOWING_LITERALS, parent_expr.span, |lint| {
-                let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
-                err.set_arg("ty", ty);
-                if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
-                    use ast::{LitIntType, LitKind};
-                    // We need to preserve the literal's suffix,
-                    // as it may determine typing information.
-                    let suffix = match lit.node {
-                        LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
-                        LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
-                        LitKind::Int(_, LitIntType::Unsuffixed) => "",
-                        _ => bug!(),
-                    };
-                    let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
-                    err.span_suggestion(
-                        parent_expr.span,
-                        fluent::lint::suggestion,
-                        suggestion,
-                        Applicability::MachineApplicable,
-                    );
-                    err.emit();
-                    overwritten = true;
-                }
-            });
-        }
+    // We can suggest using an inclusive range
+    // (`..=`) instead only if it is the `end` that is
+    // overflowing and only by 1.
+    if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
+        cx.struct_span_lint(OVERFLOWING_LITERALS, struct_expr.span, |lint| {
+            let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
+            err.set_arg("ty", ty);
+            if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
+                use ast::{LitIntType, LitKind};
+                // We need to preserve the literal's suffix,
+                // as it may determine typing information.
+                let suffix = match lit.node {
+                    LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
+                    LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
+                    LitKind::Int(_, LitIntType::Unsuffixed) => "",
+                    _ => bug!(),
+                };
+                let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
+                err.span_suggestion(
+                    struct_expr.span,
+                    fluent::lint::suggestion,
+                    suggestion,
+                    Applicability::MachineApplicable,
+                );
+                err.emit();
+                overwritten = true;
+            }
+        });
     }
     overwritten
 }
@@ -339,16 +345,9 @@ fn lint_int_literal<'tcx>(
             return;
         }
 
-        let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
-        if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
-            if let hir::ExprKind::Struct(..) = par_e.kind {
-                if is_range_literal(par_e)
-                    && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
-                {
-                    // The overflowing literal lint was overridden.
-                    return;
-                }
-            }
+        if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
+            // The overflowing literal lint was overridden.
+            return;
         }
 
         cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
@@ -408,16 +407,13 @@ fn lint_uint_literal<'tcx>(
                         return;
                     }
                 }
-                hir::ExprKind::Struct(..) if is_range_literal(par_e) => {
-                    let t = t.name_str();
-                    if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
-                        // The overflowing literal lint was overridden.
-                        return;
-                    }
-                }
                 _ => {}
             }
         }
+        if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
+            // The overflowing literal lint was overridden.
+            return;
+        }
         if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
             report_bin_hex_error(
                 cx,
index 5f5b5de790e430e4e2823c491c0536325638c793..f9bffe6d8239230f1d571e47b0660f89d6274d42 100644 (file)
@@ -924,6 +924,30 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
                                                fromRust(Flags), unwrapDI<DIType>(Ty)));
 }
 
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType(
+    LLVMRustDIBuilderRef Builder,
+    LLVMMetadataRef Scope,
+    const char *Name,
+    size_t NameLen,
+    LLVMMetadataRef File,
+    unsigned LineNo,
+    LLVMMetadataRef Ty,
+    LLVMRustDIFlags Flags,
+    LLVMValueRef val,
+    uint32_t AlignInBits
+) {
+  return wrap(Builder->createStaticMemberType(
+    unwrapDI<DIDescriptor>(Scope),
+    StringRef(Name, NameLen),
+    unwrapDI<DIFile>(File),
+    LineNo,
+    unwrapDI<DIType>(Ty),
+    fromRust(Flags),
+    unwrap<llvm::ConstantInt>(val),
+    AlignInBits
+  ));
+}
+
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
     LLVMMetadataRef File, unsigned Line, unsigned Col) {
index 562d5e9f4d25e58138661ffdb79a810c33aaf478..2e7652ad333ffcdeafdeb5b87c7e8ddc17fee5a7 100644 (file)
@@ -189,13 +189,25 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
             if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
                 let _ = previous_defns.entry(name.to_string()).or_insert(ident_span);
 
-                // `typeck-foo-bar` => `foo_bar` (in `typeck.ftl`)
-                // `const-eval-baz` => `baz` (in `const_eval.ftl`)
+                if name.contains('-') {
+                    Diagnostic::spanned(
+                        ident_span,
+                        Level::Error,
+                        format!("name `{name}` contains a '-' character"),
+                    )
+                    .help("replace any '-'s with '_'s")
+                    .emit();
+                }
+
+                // `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`)
+                // `const_eval_baz` => `baz` (in `const_eval.ftl`)
+                // `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
+                // The last case we error about above, but we want to fall back gracefully
+                // so that only the error is being emitted and not also one about the macro
+                // failing.
                 let snake_name = Ident::new(
                     // FIXME: should probably trim prefix, not replace all occurrences
-                    &name
-                        .replace(&format!("{}-", res.ident).replace('_', "-"), "")
-                        .replace('-', "_"),
+                    &name.replace('-', "_").replace(&format!("{}_", res.ident), ""),
                     span,
                 );
                 constants.extend(quote! {
@@ -212,6 +224,16 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
                         continue;
                     }
 
+                    if attr_name.contains('-') {
+                        Diagnostic::spanned(
+                            ident_span,
+                            Level::Error,
+                            format!("attribute `{attr_name}` contains a '-' character"),
+                        )
+                        .help("replace any '-'s with '_'s")
+                        .emit();
+                    }
+
                     constants.extend(quote! {
                         pub const #snake_name: crate::SubdiagnosticMessage =
                             crate::SubdiagnosticMessage::FluentAttr(
index 3997900266641c79e133d054836490a55c2cadd8..733454cb2a7471d7634d62aa18843f4e78dced85 100644 (file)
@@ -38,9 +38,9 @@
 /// ```
 ///
 /// ```fluent
-/// move-out-of-borrow = cannot move out of {$name} because it is borrowed
+/// move_out_of_borrow = cannot move out of {$name} because it is borrowed
 ///     .label = cannot move out of borrow
-///     .first-borrow-label = `{$ty}` first borrowed here
+///     .first_borrow_label = `{$ty}` first borrowed here
 ///     .suggestion = consider cloning here
 /// ```
 ///
@@ -84,9 +84,9 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
 /// ```
 ///
 /// ```fluent
-/// lint-atomic-ordering-invalid-fail-success = `{$method}`'s success ordering must be at least as strong as its failure ordering
-///     .fail-label = `{$fail_ordering}` failure ordering
-///     .success-label = `{$success_ordering}` success ordering
+/// lint_atomic_ordering_invalid_fail_success = `{$method}`'s success ordering must be at least as strong as its failure ordering
+///     .fail_label = `{$fail_ordering}` failure ordering
+///     .success_label = `{$success_ordering}` success ordering
 ///     .suggestion = consider using `{$success_suggestion}` success ordering instead
 /// ```
 ///
@@ -140,11 +140,11 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
 /// ```
 ///
 /// ```fluent
-/// parser-expected-identifier = expected identifier
+/// parser_expected_identifier = expected identifier
 ///
-/// parser-expected-identifier-found = expected identifier, found {$found}
+/// parser_expected_identifier-found = expected identifier, found {$found}
 ///
-/// parser-raw-identifier = escape `{$ident}` to use it as an identifier
+/// parser_raw_identifier = escape `{$ident}` to use it as an identifier
 /// ```
 ///
 /// Then, later, to add the subdiagnostic:
index ab509b26f1c55eeb4a1b6a5469f6cff33a1e5c0b..2f9c13cf817ee7d185ba09ac514989feffcb0a96 100644 (file)
@@ -65,10 +65,10 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
 /// ..where `typeck.ftl` has the following contents..
 ///
 /// ```fluent
-/// typeck-field-multiply-specified-in-initializer =
+/// typeck_field_multiply_specified_in_initializer =
 ///     field `{$ident}` specified more than once
 ///     .label = used more than once
-///     .label-previous-use = first use of `{$ident}`
+///     .label_previous_use = first use of `{$ident}`
 /// ```
 /// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and
 /// will generate the following code:
@@ -81,11 +81,11 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
 /// mod fluent_generated {
 ///     mod typeck {
 ///         pub const field_multiply_specified_in_initializer: DiagnosticMessage =
-///             DiagnosticMessage::fluent("typeck-field-multiply-specified-in-initializer");
+///             DiagnosticMessage::fluent("typeck_field_multiply_specified_in_initializer");
 ///         pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage =
 ///             DiagnosticMessage::fluent_attr(
-///                 "typeck-field-multiply-specified-in-initializer",
-///                 "previous-use-label"
+///                 "typeck_field_multiply_specified_in_initializer",
+///                 "previous_use_label"
 ///             );
 ///     }
 /// }
index e192378bcc3d23cb7a4b535c566d03921766b111..75069a5f0dc015f56c9d8026bdf020f69ae0ae70 100644 (file)
@@ -4,7 +4,6 @@
 #![feature(generators)]
 #![feature(generic_associated_types)]
 #![feature(iter_from_generator)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(once_cell)]
 #![feature(proc_macro_internals)]
index 47b04c33ec1cd67b131be9439b977f2997b3c862..79e6804a28992c74f6d8a24f5adaa4e2a4ece81d 100644 (file)
@@ -297,6 +297,8 @@ pub(super) fn opt_def_kind(self, local_def_id: LocalDefId) -> Option<DefKind> {
             | Node::Infer(_)
             | Node::TraitRef(_)
             | Node::Pat(_)
+            | Node::PatField(_)
+            | Node::ExprField(_)
             | Node::Local(_)
             | Node::Param(_)
             | Node::Arm(_)
@@ -1020,6 +1022,7 @@ pub fn span_with_body(self, hir_id: HirId) -> Span {
             Node::Field(field) => field.span,
             Node::AnonConst(constant) => self.body(constant.body).value.span,
             Node::Expr(expr) => expr.span,
+            Node::ExprField(field) => field.span,
             Node::Stmt(stmt) => stmt.span,
             Node::PathSegment(seg) => {
                 let ident_span = seg.ident.span;
@@ -1030,6 +1033,7 @@ pub fn span_with_body(self, hir_id: HirId) -> Span {
             Node::TypeBinding(tb) => tb.span,
             Node::TraitRef(tr) => tr.path.span,
             Node::Pat(pat) => pat.span,
+            Node::PatField(field) => field.span,
             Node::Arm(arm) => arm.span,
             Node::Block(block) => block.span,
             Node::Ctor(..) => self.span_with_body(self.get_parent_node(hir_id)),
@@ -1241,12 +1245,14 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
         }
         Some(Node::AnonConst(_)) => node_str("const"),
         Some(Node::Expr(_)) => node_str("expr"),
+        Some(Node::ExprField(_)) => node_str("expr field"),
         Some(Node::Stmt(_)) => node_str("stmt"),
         Some(Node::PathSegment(_)) => node_str("path segment"),
         Some(Node::Ty(_)) => node_str("type"),
         Some(Node::TypeBinding(_)) => node_str("type binding"),
         Some(Node::TraitRef(_)) => node_str("trait ref"),
         Some(Node::Pat(_)) => node_str("pat"),
+        Some(Node::PatField(_)) => node_str("pattern field"),
         Some(Node::Param(_)) => node_str("param"),
         Some(Node::Arm(_)) => node_str("arm"),
         Some(Node::Block(_)) => node_str("block"),
index 4e1254efd179fa7f4b4f9f3578e18d731914083d..6a6505d025663d65a32cb444e2249caf4bef93c5 100644 (file)
@@ -39,7 +39,6 @@
 #![feature(extern_types)]
 #![feature(new_uninit)]
 #![feature(once_cell)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(trusted_len)]
index 4b0bc3c1114de5905c9cfea75c8659cca92029da..8e6af936ded18442c2e3549bfaa394469cb7004f 100644 (file)
@@ -30,7 +30,8 @@ pub fn new(a_is_expected: bool, a: T, b: T) -> Self {
 }
 
 // Data structures used in type unification
-#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
+#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
+#[rustc_pass_by_value]
 pub enum TypeError<'tcx> {
     Mismatch,
     ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
@@ -211,7 +212,7 @@ fn report_maybe_different(
 }
 
 impl<'tcx> TypeError<'tcx> {
-    pub fn must_include_note(&self) -> bool {
+    pub fn must_include_note(self) -> bool {
         use self::TypeError::*;
         match self {
             CyclicTy(_) | CyclicConst(_) | UnsafetyMismatch(_) | ConstnessMismatch(_)
@@ -347,7 +348,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn note_and_explain_type_err(
         self,
         diag: &mut Diagnostic,
-        err: &TypeError<'tcx>,
+        err: TypeError<'tcx>,
         cause: &ObligationCause<'tcx>,
         sp: Span,
         body_owner_def_id: DefId,
@@ -568,7 +569,7 @@ fn foo(&self, x: T) -> T { x }
             }
             TargetFeatureCast(def_id) => {
                 let target_spans =
-                    self.get_attrs(*def_id, sym::target_feature).map(|attr| attr.span);
+                    self.get_attrs(def_id, sym::target_feature).map(|attr| attr.span);
                 diag.note(
                     "functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
                 );
@@ -640,7 +641,7 @@ fn expected_projection(
         self,
         diag: &mut Diagnostic,
         proj_ty: &ty::ProjectionTy<'tcx>,
-        values: &ExpectedFound<Ty<'tcx>>,
+        values: ExpectedFound<Ty<'tcx>>,
         body_owner_def_id: DefId,
         cause_code: &ObligationCauseCode<'_>,
     ) {
index a7d8431b6c7a2dd1bf3b2d7d2a354c9f5bc77853..e51ca65dc16b1bb820c082c172d64dd78bef5416 100644 (file)
@@ -5,7 +5,6 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(once_cell)]
index 98016659a05f7bc268938bbfc0d7a66fc98ed218..1c087b93b4965de083b51cdbb2f7398e47a1f129 100644 (file)
@@ -183,6 +183,18 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
 
     type MemoryKind = !;
 
+    #[inline(always)]
+    fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+        // We do not check for alignment to avoid having to carry an `Align`
+        // in `ConstValue::ByRef`.
+        false
+    }
+
+    #[inline(always)]
+    fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+        false // for now, we don't enforce validity
+    }
+
     fn load_mir(
         _ecx: &InterpCx<'mir, 'tcx, Self>,
         _instance: ty::InstanceDef<'tcx>,
index 2a51af582f5854c35d21a27e42f4b583166305f6..56fb601d2b53528d11ddf466cf1762d0c1047470 100644 (file)
@@ -1,6 +1,5 @@
 #![allow(rustc::potential_query_instability)]
 #![feature(box_patterns)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
index 68b65658c72b50503c3bc78635c84f30c771f62d..96bbf5802e738c734f6dc9f3298f7dd36a34852b 100644 (file)
@@ -1027,6 +1027,11 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) ->
         return false;
     }
 
+    if let DefKind::Static(_) = tcx.def_kind(def_id) {
+        // We cannot monomorphize statics from upstream crates.
+        return false;
+    }
+
     if !tcx.is_mir_available(def_id) {
         bug!("no MIR available for {:?}", def_id);
     }
index 261adbfc34671e70c2383b16cea3c5778769e960..5924eba9f8b423b9e59484feca8f343886550ca1 100644 (file)
@@ -3,7 +3,6 @@
 #![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
index 48909ff834234ba1a9bd80dca9bedd5dd21b1a92..93e70e9abdaca8bf3c3e913fbec59bc6b1a9bab4 100644 (file)
@@ -590,7 +590,7 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
             )
         } else if expected.is_empty() {
             (
-                format!("unexpected token: {}", actual),
+                format!("unexpected token: {actual}"),
                 (self.prev_token.span, "unexpected token after this".to_string()),
             )
         } else {
@@ -1496,7 +1496,7 @@ fn postfix_inc_dec_suggest(
         MultiSugg {
             msg: format!("use `{}= 1` instead", kind.op.chr()),
             patches: vec![
-                (pre_span, format!("{{ let {} = ", tmp_var)),
+                (pre_span, format!("{{ let {tmp_var} = ")),
                 (post_span, format!("; {} {}= 1; {} }}", base_src, kind.op.chr(), tmp_var)),
             ],
             applicability: Applicability::HasPlaceholders,
index 1bef277f3d0606138eef0f7d48e8668bfaa7d8c1..9d6d632c2e89af538f32478788458c569f939a9d 100644 (file)
@@ -2227,7 +2227,7 @@ fn parse_fn_block_param(&mut self) -> PResult<'a, Param> {
                     attrs: attrs.into(),
                     ty,
                     pat,
-                    span: lo.to(this.token.span),
+                    span: lo.to(this.prev_token.span),
                     id: DUMMY_NODE_ID,
                     is_placeholder: false,
                 },
index 72c23776d339918c69e565fae592b2c287ce6271..f3f070e6eb021675f7523cf3b8d52274a9ab3ce0 100644 (file)
@@ -68,7 +68,12 @@ pub fn parse_mod(
             if !self.maybe_consume_incorrect_semicolon(&items) {
                 let msg = &format!("expected item, found {token_str}");
                 let mut err = self.struct_span_err(self.token.span, msg);
-                err.span_label(self.token.span, "expected item");
+                let label = if self.is_kw_followed_by_ident(kw::Let) {
+                    "consider using `const` or `static` instead of `let` for global variables"
+                } else {
+                    "expected item"
+                };
+                err.span_label(self.token.span, label);
                 return Err(err);
             }
         }
@@ -670,14 +675,44 @@ fn parse_item_list<T>(
             }
             match parse_item(self) {
                 Ok(None) => {
+                    let is_unnecessary_semicolon = !items.is_empty()
+                        // When the close delim is `)` in a case like the following, `token.kind` is expected to be `token::CloseDelim(Delimiter::Parenthesis)`,
+                        // but the actual `token.kind` is `token::CloseDelim(Delimiter::Bracket)`.
+                        // This is because the `token.kind` of the close delim is treated as the same as
+                        // that of the open delim in `TokenTreesReader::parse_token_tree`, even if the delimiters of them are different.
+                        // Therefore, `token.kind` should not be compared here.
+                        //
+                        // issue-60075.rs
+                        // ```
+                        // trait T {
+                        //     fn qux() -> Option<usize> {
+                        //         let _ = if true {
+                        //         });
+                        //          ^ this close delim
+                        //         Some(4)
+                        //     }
+                        // ```
+                        && self
+                            .span_to_snippet(self.prev_token.span)
+                            .map_or(false, |snippet| snippet == "}")
+                        && self.token.kind == token::Semi;
+                    let semicolon_span = self.token.span;
                     // We have to bail or we'll potentially never make progress.
                     let non_item_span = self.token.span;
                     self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
-                    self.struct_span_err(non_item_span, "non-item in item list")
-                        .span_label(open_brace_span, "item list starts here")
+                    let mut err = self.struct_span_err(non_item_span, "non-item in item list");
+                    err.span_label(open_brace_span, "item list starts here")
                         .span_label(non_item_span, "non-item starts here")
-                        .span_label(self.prev_token.span, "item list ends here")
-                        .emit();
+                        .span_label(self.prev_token.span, "item list ends here");
+                    if is_unnecessary_semicolon {
+                        err.span_suggestion(
+                            semicolon_span,
+                            "consider removing this semicolon",
+                            "",
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    err.emit();
                     break;
                 }
                 Ok(Some(item)) => items.extend(item),
@@ -1127,6 +1162,16 @@ fn recover_const_mut(&mut self, const_span: Span) {
                     Applicability::MaybeIncorrect,
                 )
                 .emit();
+        } else if self.eat_keyword(kw::Let) {
+            let span = self.prev_token.span;
+            self.struct_span_err(const_span.to(span), "`const` and `let` are mutually exclusive")
+                .span_suggestion(
+                    const_span.to(span),
+                    "remove `let`",
+                    "const",
+                    Applicability::MaybeIncorrect,
+                )
+                .emit();
         }
     }
 
@@ -1539,8 +1584,12 @@ fn parse_single_struct_field(
                     }
                 }
 
-                if self.token.is_ident() {
-                    // This is likely another field; emit the diagnostic and keep going
+                if self.token.is_ident()
+                    || (self.token.kind == TokenKind::Pound
+                        && (self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Bracket))))
+                {
+                    // This is likely another field, TokenKind::Pound is used for `#[..]` attribute for next field,
+                    // emit the diagnostic and keep going
                     err.span_suggestion(
                         sp,
                         "try adding a comma",
@@ -2260,7 +2309,7 @@ fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResu
                 (pat, this.parse_ty_for_param()?)
             } else {
                 debug!("parse_param_general ident_to_pat");
-                let parser_snapshot_before_ty = this.clone();
+                let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
                 this.eat_incorrect_doc_comment_for_param_type();
                 let mut ty = this.parse_ty_for_param();
                 if ty.is_ok()
@@ -2283,13 +2332,13 @@ fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResu
                     // Recover from attempting to parse the argument as a type without pattern.
                     Err(err) => {
                         err.cancel();
-                        *this = parser_snapshot_before_ty;
+                        this.restore_snapshot(parser_snapshot_before_ty);
                         this.recover_arg_parse()?
                     }
                 }
             };
 
-            let span = lo.until(this.token.span);
+            let span = lo.to(this.prev_token.span);
 
             Ok((
                 Param {
index 89b5a8a9556886b29c9856f0242127ef6bb0fded..ade0f4fbc86a27b2e1bc4048e326958f63d79659 100644 (file)
@@ -55,6 +55,19 @@ pub(crate) fn parse_stmt_without_recovery(
             return Ok(Some(stmt.into_inner()));
         }
 
+        if self.token.is_keyword(kw::Mut) && self.is_keyword_ahead(1, &[kw::Let]) {
+            self.bump();
+            let mut_let_span = lo.to(self.token.span);
+            self.struct_span_err(mut_let_span, "invalid variable declaration")
+                .span_suggestion(
+                    mut_let_span,
+                    "switch the order of `mut` and `let`",
+                    "let mut",
+                    Applicability::MaybeIncorrect,
+                )
+                .emit();
+        }
+
         Ok(Some(if self.token.is_keyword(kw::Let) {
             self.parse_local_mk(lo, attrs, capture_semi, force_collect)?
         } else if self.is_kw_followed_by_ident(kw::Mut) {
@@ -247,6 +260,22 @@ fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'
     /// Parses a local variable declaration.
     fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
         let lo = self.prev_token.span;
+
+        if self.token.is_keyword(kw::Const) && self.look_ahead(1, |t| t.is_ident()) {
+            self.struct_span_err(
+                lo.to(self.token.span),
+                "`const` and `let` are mutually exclusive",
+            )
+            .span_suggestion(
+                lo.to(self.token.span),
+                "remove `let`",
+                "const",
+                Applicability::MaybeIncorrect,
+            )
+            .emit();
+            self.bump();
+        }
+
         let (pat, colon) = self.parse_pat_before_ty(None, RecoverComma::Yes, "`let` bindings")?;
 
         let (err, ty) = if colon {
index f75fffb6871f73aed9194c51de005b04c80da836..5789531d2ff5ae3b1a47a975bd7521e4803917ac 100644 (file)
@@ -652,7 +652,9 @@ fn check_doc_alias_value(
             | Target::ForeignStatic
             | Target::ForeignTy
             | Target::GenericParam(..)
-            | Target::MacroDef => None,
+            | Target::MacroDef
+            | Target::PatField
+            | Target::ExprField => None,
         } {
             tcx.sess.emit_err(errors::DocAliasBadLocation { span, attr_str, location });
             return false;
@@ -2066,6 +2068,11 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         intravisit::walk_expr(self, expr)
     }
 
+    fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
+        self.check_attributes(field.hir_id, field.span, Target::ExprField, None);
+        intravisit::walk_expr_field(self, field)
+    }
+
     fn visit_variant(&mut self, variant: &'tcx hir::Variant<'tcx>) {
         self.check_attributes(variant.id, variant.span, Target::Variant, None);
         intravisit::walk_variant(self, variant)
@@ -2076,6 +2083,11 @@ fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
 
         intravisit::walk_param(self, param);
     }
+
+    fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
+        self.check_attributes(field.hir_id, field.span, Target::PatField, None);
+        intravisit::walk_pat_field(self, field);
+    }
 }
 
 fn is_c_like_enum(item: &Item<'_>) -> bool {
index defa9d15296e08ac80b70d943c9d83873afc60ac..4af041dac0d8390789abae5de00af8024e6a3113 100644 (file)
@@ -7,7 +7,6 @@
 #![allow(rustc::potential_query_instability)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(iter_intersperse)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
index 461dd52b9f2f5c734021e4ab37c89e08fef4ea4a..7124b84bfef3893414cc39da5c93d41da1134446 100644 (file)
@@ -98,7 +98,7 @@
 use rustc_middle::ty::{self, DefIdTree, RootVariableMinCaptureList, Ty, TyCtxt};
 use rustc_session::lint;
 use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
 
 use std::collections::VecDeque;
 use std::io;
@@ -1549,6 +1549,8 @@ fn check_unused_vars_in_pat(
                 .or_insert_with(|| (ln, var, vec![id_and_sp]));
         });
 
+        let can_remove = matches!(&pat.kind, hir::PatKind::Struct(_, _, true));
+
         for (_, (ln, var, hir_ids_and_spans)) in vars {
             if self.used_on_entry(ln, var) {
                 let id = hir_ids_and_spans[0].0;
@@ -1556,16 +1558,18 @@ fn check_unused_vars_in_pat(
                     hir_ids_and_spans.into_iter().map(|(_, _, ident_span)| ident_span).collect();
                 on_used_on_entry(spans, id, ln, var);
             } else {
-                self.report_unused(hir_ids_and_spans, ln, var);
+                self.report_unused(hir_ids_and_spans, ln, var, can_remove);
             }
         }
     }
 
+    #[tracing::instrument(skip(self), level = "INFO")]
     fn report_unused(
         &self,
         hir_ids_and_spans: Vec<(HirId, Span, Span)>,
         ln: LiveNode,
         var: Variable,
+        can_remove: bool,
     ) {
         let first_hir_id = hir_ids_and_spans[0].0;
 
@@ -1590,6 +1594,32 @@ fn report_unused(
                             .emit();
                     },
                 )
+            } else if can_remove {
+                self.ir.tcx.struct_span_lint_hir(
+                    lint::builtin::UNUSED_VARIABLES,
+                    first_hir_id,
+                    hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::<Vec<_>>(),
+                    |lint| {
+                        let mut err = lint.build(&format!("unused variable: `{}`", name));
+                        err.multipart_suggestion(
+                            "try removing the field",
+                            hir_ids_and_spans
+                                .iter()
+                                .map(|(_, pat_span, _)| {
+                                    let span = self
+                                        .ir
+                                        .tcx
+                                        .sess
+                                        .source_map()
+                                        .span_extend_to_next_char(*pat_span, ',', true);
+                                    (span.with_hi(BytePos(span.hi().0 + 1)), String::new())
+                                })
+                                .collect(),
+                            Applicability::MachineApplicable,
+                        );
+                        err.emit();
+                    },
+                );
             } else {
                 let (shorthands, non_shorthands): (Vec<_>, Vec<_>) =
                     hir_ids_and_spans.iter().copied().partition(|(hir_id, _, ident_span)| {
index 574e8073d8efd508fdc72891a80805ee56ae0a5d..f884e04a9511254977a3a96cf40142e8129f98ed 100644 (file)
@@ -460,7 +460,7 @@ fn visit_variant(&mut self, var: &'tcx Variant<'tcx>) {
                         AnnotationKind::Required,
                         InheritDeprecation::Yes,
                         InheritConstStability::No,
-                        InheritStability::No,
+                        InheritStability::Yes,
                         |_| {},
                     );
                 }
@@ -600,6 +600,9 @@ fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
 
     fn visit_variant(&mut self, var: &'tcx Variant<'tcx>) {
         self.check_missing_stability(self.tcx.hir().local_def_id(var.id), var.span);
+        if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
+            self.check_missing_stability(self.tcx.hir().local_def_id(ctor_hir_id), var.span);
+        }
         intravisit::walk_variant(self, var);
     }
 
@@ -962,58 +965,113 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
     remaining_lib_features.remove(&sym::libc);
     remaining_lib_features.remove(&sym::test);
 
-    // We always collect the lib features declared in the current crate, even if there are
-    // no unknown features, because the collection also does feature attribute validation.
-    let local_defined_features = tcx.lib_features(());
-    let mut all_lib_features: FxHashMap<_, _> =
-        local_defined_features.to_vec().iter().map(|el| *el).collect();
-    let mut implications = tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE).clone();
-    for &cnum in tcx.crates(()) {
-        implications.extend(tcx.stability_implications(cnum));
-        all_lib_features.extend(tcx.defined_lib_features(cnum).iter().map(|el| *el));
-    }
-
-    // Check that every feature referenced by an `implied_by` exists (for features defined in the
-    // local crate).
-    for (implied_by, feature) in tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE) {
-        // Only `implied_by` needs to be checked, `feature` is guaranteed to exist.
-        if !all_lib_features.contains_key(implied_by) {
-            let span = local_defined_features
-                .stable
-                .get(feature)
-                .map(|(_, span)| span)
-                .or_else(|| local_defined_features.unstable.get(feature))
-                .expect("feature that implied another does not exist");
-            tcx.sess
-                .struct_span_err(
-                    *span,
-                    format!("feature `{implied_by}` implying `{feature}` does not exist"),
-                )
-                .emit();
-        }
-    }
-
-    if !remaining_lib_features.is_empty() {
-        for (feature, since) in all_lib_features.iter() {
+    /// For each feature in `defined_features`..
+    ///
+    /// - If it is in `remaining_lib_features` (those features with `#![feature(..)]` attributes in
+    ///   the current crate), check if it is stable (or partially stable) and thus an unnecessary
+    ///   attribute.
+    /// - If it is in `remaining_implications` (a feature that is referenced by an `implied_by`
+    ///   from the current crate), then remove it from the remaining implications.
+    ///
+    /// Once this function has been invoked for every feature (local crate and all extern crates),
+    /// then..
+    ///
+    /// - If features remain in `remaining_lib_features`, then the user has enabled a feature that
+    ///   does not exist.
+    /// - If features remain in `remaining_implications`, the `implied_by` refers to a feature that
+    ///   does not exist.
+    ///
+    /// By structuring the code in this way: checking the features defined from each crate one at a
+    /// time, less loading from metadata is performed and thus compiler performance is improved.
+    fn check_features<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        remaining_lib_features: &mut FxIndexMap<&Symbol, Span>,
+        remaining_implications: &mut FxHashMap<Symbol, Symbol>,
+        defined_features: &[(Symbol, Option<Symbol>)],
+        all_implications: &FxHashMap<Symbol, Symbol>,
+    ) {
+        for (feature, since) in defined_features {
             if let Some(since) = since && let Some(span) = remaining_lib_features.get(&feature) {
                 // Warn if the user has enabled an already-stable lib feature.
-                if let Some(implies) = implications.get(&feature) {
+                if let Some(implies) = all_implications.get(&feature) {
                     unnecessary_partially_stable_feature_lint(tcx, *span, *feature, *implies, *since);
                 } else {
                     unnecessary_stable_feature_lint(tcx, *span, *feature, *since);
                 }
+
             }
-            remaining_lib_features.remove(&feature);
-            if remaining_lib_features.is_empty() {
+            remaining_lib_features.remove(feature);
+
+            // `feature` is the feature doing the implying, but `implied_by` is the feature with
+            // the attribute that establishes this relationship. `implied_by` is guaranteed to be a
+            // feature defined in the local crate because `remaining_implications` is only the
+            // implications from this crate.
+            remaining_implications.remove(feature);
+
+            if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
                 break;
             }
         }
     }
 
+    // All local crate implications need to have the feature that implies it confirmed to exist.
+    let mut remaining_implications =
+        tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE).clone();
+
+    // We always collect the lib features declared in the current crate, even if there are
+    // no unknown features, because the collection also does feature attribute validation.
+    let local_defined_features = tcx.lib_features(()).to_vec();
+    if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() {
+        // Loading the implications of all crates is unavoidable to be able to emit the partial
+        // stabilization diagnostic, but it can be avoided when there are no
+        // `remaining_lib_features`.
+        let mut all_implications = remaining_implications.clone();
+        for &cnum in tcx.crates(()) {
+            all_implications.extend(tcx.stability_implications(cnum));
+        }
+
+        check_features(
+            tcx,
+            &mut remaining_lib_features,
+            &mut remaining_implications,
+            local_defined_features.as_slice(),
+            &all_implications,
+        );
+
+        for &cnum in tcx.crates(()) {
+            if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
+                break;
+            }
+            check_features(
+                tcx,
+                &mut remaining_lib_features,
+                &mut remaining_implications,
+                tcx.defined_lib_features(cnum).to_vec().as_slice(),
+                &all_implications,
+            );
+        }
+    }
+
     for (feature, span) in remaining_lib_features {
         struct_span_err!(tcx.sess, span, E0635, "unknown feature `{}`", feature).emit();
     }
 
+    for (implied_by, feature) in remaining_implications {
+        let local_defined_features = tcx.lib_features(());
+        let span = local_defined_features
+            .stable
+            .get(&feature)
+            .map(|(_, span)| span)
+            .or_else(|| local_defined_features.unstable.get(&feature))
+            .expect("feature that implied another does not exist");
+        tcx.sess
+            .struct_span_err(
+                *span,
+                format!("feature `{implied_by}` implying `{feature}` does not exist"),
+            )
+            .emit();
+    }
+
     // FIXME(#44232): the `used_features` table no longer exists, so we
     // don't lint about unused features. We should re-enable this one day!
 }
index f7c28eff55b763c4cfc1c6b83fa64b0d7f36fab0..27fa402edcec8dfe3e36f4033e4dd4c3d1e8f8e1 100644 (file)
@@ -5,8 +5,8 @@
 #![feature(try_blocks)]
 #![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
-#![cfg_attr(not(bootstrap), deny(rustc::untranslatable_diagnostic))]
-#![cfg_attr(not(bootstrap), deny(rustc::diagnostic_outside_of_impl))]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 mod errors;
 
index cb133841bca5a2ac7c9ce97cc322fb280dd34615..09c1f44826fa4b41772c5921931041849d17a6ad 100644 (file)
@@ -985,27 +985,45 @@ fn smart_resolve_context_dependent_help(
         let ns = source.namespace();
         let is_expected = &|res| source.is_expected(res);
 
-        let path_sep = |err: &mut Diagnostic, expr: &Expr| match expr.kind {
-            ExprKind::Field(_, ident) => {
+        let path_sep = |err: &mut Diagnostic, expr: &Expr, kind: DefKind| {
+            const MESSAGE: &str = "use the path separator to refer to an item";
+
+            let (lhs_span, rhs_span) = match &expr.kind {
+                ExprKind::Field(base, ident) => (base.span, ident.span),
+                ExprKind::MethodCall(_, receiver, _, span) => (receiver.span, *span),
+                _ => return false,
+            };
+
+            if lhs_span.eq_ctxt(rhs_span) {
                 err.span_suggestion(
-                    expr.span,
-                    "use the path separator to refer to an item",
-                    format!("{}::{}", path_str, ident),
+                    lhs_span.between(rhs_span),
+                    MESSAGE,
+                    "::",
                     Applicability::MaybeIncorrect,
                 );
                 true
-            }
-            ExprKind::MethodCall(ref segment, ..) => {
-                let span = expr.span.with_hi(segment.ident.span.hi());
-                err.span_suggestion(
-                    span,
-                    "use the path separator to refer to an item",
-                    format!("{}::{}", path_str, segment.ident),
+            } else if kind == DefKind::Struct
+            && let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span)
+            && let Ok(snippet) = self.r.session.source_map().span_to_snippet(lhs_source_span)
+            {
+                // The LHS is a type that originates from a macro call.
+                // We have to add angle brackets around it.
+
+                err.span_suggestion_verbose(
+                    lhs_source_span.until(rhs_span),
+                    MESSAGE,
+                    format!("<{snippet}>::"),
                     Applicability::MaybeIncorrect,
                 );
                 true
+            } else {
+                // Either we were unable to obtain the source span / the snippet or
+                // the LHS originates from a macro call and it is not a type and thus
+                // there is no way to replace `.` with `::` and still somehow suggest
+                // valid Rust code.
+
+                false
             }
-            _ => false,
         };
 
         let find_span = |source: &PathSource<'_>, err: &mut Diagnostic| {
@@ -1027,7 +1045,7 @@ fn smart_resolve_context_dependent_help(
             match source {
                 PathSource::Expr(Some(
                     parent @ Expr { kind: ExprKind::Field(..) | ExprKind::MethodCall(..), .. },
-                )) if path_sep(err, &parent) => {}
+                )) if path_sep(err, &parent, DefKind::Struct) => {}
                 PathSource::Expr(
                     None
                     | Some(Expr {
@@ -1143,8 +1161,11 @@ fn smart_resolve_context_dependent_help(
                     }
                 }
             }
-            (Res::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => {
-                if !path_sep(err, &parent) {
+            (
+                Res::Def(kind @ (DefKind::Mod | DefKind::Trait), _),
+                PathSource::Expr(Some(parent)),
+            ) => {
+                if !path_sep(err, &parent, kind) {
                     return false;
                 }
             }
index ef3c3da89c572b6b24b3766ff1db0c68d519d7c5..9c213da8c2a2cd4146ff30439b6ea30e5165e72f 100644 (file)
@@ -10,7 +10,6 @@
 #![feature(box_patterns)]
 #![feature(drain_filter)]
 #![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(iter_intersperse)]
 #![feature(let_else)]
 #![feature(never_type)]
index 6a8298605a23b8624d657e2912e8ed6ebca1e5e4..68519c8fa828ea6e2c866e5fcec4751ab2735570 100644 (file)
@@ -949,7 +949,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
         ret.insert((sym::debug_assertions, None));
     }
     // JUSTIFICATION: before wrapper fn is available
-    #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+    #[allow(rustc::bad_opt_access)]
     if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
         ret.insert((sym::proc_macro, None));
     }
@@ -2198,7 +2198,7 @@ fn parse_remap_path_prefix(
 }
 
 // JUSTIFICATION: before wrapper fn is available
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
 pub fn build_session_options(matches: &getopts::Matches) -> Options {
     let color = parse_color(matches);
 
index 44cf504864254c3627439e9cf7c60a49d361a24a..0617bd5fae786696dce2598ebe181fbaf0d5fd5e 100644 (file)
@@ -1,5 +1,4 @@
 #![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
index 1827f1c208de7a5648040c2cf0a82fa6a3afe267..63ae91f8e6cee8a9c8c7812a6ea16b45d4918508 100644 (file)
@@ -127,11 +127,11 @@ pub fn dep_tracking_hash(&self, for_crate_hash: bool) -> u64 {
     /// `CodegenOptions`, think about how it influences incremental compilation. If in
     /// doubt, specify `[TRACKED]`, which is always "correct" but might lead to
     /// unnecessary re-compilation.
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_ty)]
+    #[rustc_lint_opt_ty]
     pub struct Options {
         /// The crate config requested for the session, which may be combined
         /// with additional crate configurations during the compile process.
-        #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::crate_types` instead of this field"))]
+        #[rustc_lint_opt_deny_field_access("use `Session::crate_types` instead of this field")]
         crate_types: Vec<CrateType> [TRACKED],
         optimize: OptLevel [TRACKED],
         /// Include the `debug_assertions` flag in dependency tracking, since it
@@ -178,9 +178,9 @@ pub struct Options {
         /// what rustc was invoked with, but massaged a bit to agree with
         /// commands like `--emit llvm-ir` which they're often incompatible with
         /// if we otherwise use the defaults of rustc.
-        #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::codegen_units` instead of this field"))]
+        #[rustc_lint_opt_deny_field_access("use `Session::codegen_units` instead of this field")]
         cli_forced_codegen_units: Option<usize> [UNTRACKED],
-        #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field"))]
+        #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
         cli_forced_thinlto_off: bool [UNTRACKED],
 
         /// Remap source path prefixes in all output (messages, object files, debug, etc.).
@@ -231,7 +231,7 @@ macro_rules! options {
      ),* ,) =>
 (
     #[derive(Clone)]
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_ty)]
+    #[rustc_lint_opt_ty]
     pub struct $struct_name { $( $( #[$attr] )* pub $opt: $t),* }
 
     impl Default for $struct_name {
@@ -282,7 +282,7 @@ pub(super) fn $opt(cg: &mut super::$struct_name, v: Option<&str>) -> bool {
 
 impl Options {
     // JUSTIFICATION: defn of the suggested wrapper fn
-    #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+    #[allow(rustc::bad_opt_access)]
     pub fn time_passes(&self) -> bool {
         self.unstable_opts.time_passes || self.unstable_opts.time
     }
@@ -290,7 +290,7 @@ pub fn time_passes(&self) -> bool {
 
 impl CodegenOptions {
     // JUSTIFICATION: defn of the suggested wrapper fn
-    #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+    #[allow(rustc::bad_opt_access)]
     pub fn instrument_coverage(&self) -> InstrumentCoverage {
         self.instrument_coverage.unwrap_or(InstrumentCoverage::Off)
     }
@@ -1091,7 +1091,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
 
     ar: String = (String::new(), parse_string, [UNTRACKED],
         "this option is deprecated and does nothing"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::code_model` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::code_model` instead of this field")]
     code_model: Option<CodeModel> = (None, parse_code_model, [TRACKED],
         "choose the code model to use (`rustc --print code-models` for details)"),
     codegen_units: Option<usize> = (None, parse_opt_number, [UNTRACKED],
@@ -1111,14 +1111,14 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "extra data to put in each output filename"),
     force_frame_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "force use of the frame pointers"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")]
     force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "force use of unwind tables"),
     incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "enable incremental compilation"),
     inline_threshold: Option<u32> = (None, parse_opt_number, [TRACKED],
         "set the threshold for inlining a function"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
     instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
         "instrument the generated code to support LLVM source-based code coverage \
         reports (note, the compiler build config must include `profiler = true`); \
@@ -1131,7 +1131,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "a single extra argument to append to the linker invocation (can be used several times)"),
     link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
         "extra arguments to append to the linker invocation (space separated)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::link_dead_code` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::link_dead_code` instead of this field")]
     link_dead_code: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "keep dead code at link time (useful for code coverage) (default: no)"),
     link_self_contained: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
@@ -1146,7 +1146,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "generate build artifacts that are compatible with linker-based LTO"),
     llvm_args: Vec<String> = (Vec::new(), parse_list, [TRACKED],
         "a list of arguments to pass to LLVM (space separated)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
     lto: LtoCli = (LtoCli::Unspecified, parse_lto, [TRACKED],
         "perform LLVM link-time optimizations"),
     metadata: Vec<String> = (Vec::new(), parse_list, [TRACKED],
@@ -1163,10 +1163,10 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "disable LLVM's SLP vectorization pass"),
     opt_level: String = ("0".to_string(), parse_string, [TRACKED],
         "optimization level (0-3, s, or z; default: 0)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::overflow_checks` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::overflow_checks` instead of this field")]
     overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "use overflow checks for integer arithmetic"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::panic_strategy` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::panic_strategy` instead of this field")]
     panic: Option<PanicStrategy> = (None, parse_opt_panic_strategy, [TRACKED],
         "panic strategy to compile crate with"),
     passes: Vec<String> = (Vec::new(), parse_list, [TRACKED],
@@ -1178,7 +1178,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "compile the program with profiling instrumentation"),
     profile_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
         "use the given `.profdata` file for profile-guided optimization"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::relocation_model` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::relocation_model` instead of this field")]
     relocation_model: Option<RelocModel> = (None, parse_relocation_model, [TRACKED],
         "control generation of position-independent code (PIC) \
         (`rustc --print relocation-models` for details)"),
@@ -1190,7 +1190,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "save all temporary output files during compilation (default: no)"),
     soft_float: bool = (false, parse_bool, [TRACKED],
         "use soft float ABI (*eabihf targets only) (default: no)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field")]
     split_debuginfo: Option<SplitDebuginfo> = (None, parse_split_debuginfo, [TRACKED],
         "how to handle split-debuginfo, a platform-specific option"),
     strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
@@ -1226,13 +1226,13 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "encode MIR of all functions into the crate metadata (default: no)"),
     assume_incomplete_release: bool = (false, parse_bool, [TRACKED],
         "make cfg(version) treat the current version as incomplete (default: no)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::asm_comments` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::asm_comments` instead of this field")]
     asm_comments: bool = (false, parse_bool, [TRACKED],
         "generate comments into the assembly (may change behavior) (default: no)"),
     assert_incr_state: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "assert that the incremental cache is in given state: \
          either `loaded` or `not-loaded`."),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field")]
     binary_dep_depinfo: bool = (false, parse_bool, [TRACKED],
         "include artifacts (sysroot, crate dependencies) used during compilation in dep-info \
         (default: no)"),
@@ -1310,7 +1310,9 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "emit the bc module with thin LTO info (default: yes)"),
     export_executable_symbols: bool = (false, parse_bool, [TRACKED],
         "export symbols from executables, as if they were dynamic libraries"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::fewer_names` instead of this field"))]
+    extra_const_ub_checks: bool = (false, parse_bool, [TRACKED],
+        "turns on more checks to detect const UB, which can be slow (default: no)"),
+    #[rustc_lint_opt_deny_field_access("use `Session::fewer_names` instead of this field")]
     fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
         (default: no)"),
@@ -1353,7 +1355,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "control whether `#[inline]` functions are in all CGUs"),
     input_stats: bool = (false, parse_bool, [UNTRACKED],
         "gather statistics about the input (default: no)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
     instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
         "instrument the generated code to support LLVM source-based code coverage \
         reports (note, the compiler build config must include `profiler = true`); \
@@ -1362,7 +1364,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         `=except-unused-generics`
         `=except-unused-functions`
         `=off` (default)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::instrument_mcount` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::instrument_mcount` instead of this field")]
     instrument_mcount: bool = (false, parse_bool, [TRACKED],
         "insert function instrument code for mcount-based tracing (default: no)"),
     keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
@@ -1386,7 +1388,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
     merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
         "control the operation of the MergeFunctions LLVM pass, taking \
         the same values as the target option of the same name"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::meta_stats` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::meta_stats` instead of this field")]
     meta_stats: bool = (false, parse_bool, [UNTRACKED],
         "gather metadata statistics (default: no)"),
     mir_emit_retag: bool = (false, parse_bool, [TRACKED],
@@ -1398,7 +1400,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         disabled by other flags as usual."),
     mir_pretty_relative_line_numbers: bool = (false, parse_bool, [UNTRACKED],
         "use line numbers relative to the function in mir pretty printing"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")]
     mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED],
         "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
     move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
@@ -1465,7 +1467,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         See #77382 and #74551."),
     print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
         "make rustc print the total optimization fuel used by a crate"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::print_llvm_passes` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::print_llvm_passes` instead of this field")]
     print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
         "print the LLVM optimization passes being run (default: no)"),
     print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
@@ -1543,7 +1545,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "exclude spans when debug-printing compiler state (default: no)"),
     src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
         "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")]
     stack_protector: StackProtector = (StackProtector::None, parse_stack_protector, [TRACKED],
         "control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"),
     strict_init_checks: bool = (false, parse_bool, [TRACKED],
@@ -1564,7 +1566,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
     symbol_mangling_version: Option<SymbolManglingVersion> = (None,
         parse_symbol_mangling_version, [TRACKED],
         "which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::teach` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::teach` instead of this field")]
     teach: bool = (false, parse_bool, [TRACKED],
         "show extended diagnostic help (default: no)"),
     temps_dir: Option<String> = (None, parse_opt_string, [UNTRACKED],
@@ -1580,7 +1582,7 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "emit directionality isolation markers in translated diagnostics"),
     tune_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
         "select processor to schedule for (`rustc --print target-cpus` for details)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
     thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "enable ThinLTO when possible"),
     thir_unsafeck: bool = (false, parse_bool, [TRACKED],
@@ -1589,19 +1591,19 @@ pub(crate) fn parse_proc_macro_execution_strategy(
     /// a sequential compiler for now. This'll likely be adjusted
     /// in the future. Note that -Zthreads=0 is the way to get
     /// the num_cpus behavior.
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::threads` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::threads` instead of this field")]
     threads: usize = (1, parse_threads, [UNTRACKED],
         "use a thread pool with N threads"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field")]
     time: bool = (false, parse_bool, [UNTRACKED],
         "measure time of rustc processes (default: no)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::time_llvm_passes` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::time_llvm_passes` instead of this field")]
     time_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
         "measure time of each LLVM pass (default: no)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field")]
     time_passes: bool = (false, parse_bool, [UNTRACKED],
         "measure time of each rustc pass (default: no)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::tls_model` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::tls_model` instead of this field")]
     tls_model: Option<TlsModel> = (None, parse_tls_model, [TRACKED],
         "choose the TLS model to use (`rustc --print tls-models` for details)"),
     trace_macros: bool = (false, parse_bool, [UNTRACKED],
@@ -1636,17 +1638,17 @@ pub(crate) fn parse_proc_macro_execution_strategy(
         "enable unsound and buggy MIR optimizations (default: no)"),
     /// This name is kind of confusing: Most unstable options enable something themselves, while
     /// this just allows "normal" options to be feature-gated.
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field")]
     unstable_options: bool = (false, parse_bool, [UNTRACKED],
         "adds unstable command line options to rustc interface (default: no)"),
     use_ctors_section: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "use legacy .ctors section for initializers rather than .init_array"),
     validate_mir: bool = (false, parse_bool, [UNTRACKED],
         "validate MIR after each transformation"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::verbose` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::verbose` instead of this field")]
     verbose: bool = (false, parse_bool, [UNTRACKED],
         "in general, enable more debug printouts (default: no)"),
-    #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::verify_llvm_ir` instead of this field"))]
+    #[rustc_lint_opt_deny_field_access("use `Session::verify_llvm_ir` instead of this field")]
     verify_llvm_ir: bool = (false, parse_bool, [TRACKED],
         "verify LLVM IR (default: no)"),
     virtual_function_elimination: bool = (false, parse_bool, [TRACKED],
index 9669287b3f37075f26563c344d84b005d3973d25..80de451276c2c71e47d601b53feef202923808f4 100644 (file)
@@ -638,7 +638,7 @@ pub fn crt_static(&self, crate_type: Option<CrateType>) -> bool {
         let found_positive = requested_features.clone().any(|r| r == "+crt-static");
 
         // JUSTIFICATION: necessary use of crate_types directly (see FIXME below)
-        #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+        #[allow(rustc::bad_opt_access)]
         if found_positive || found_negative {
             found_positive
         } else if crate_type == Some(CrateType::ProcMacro)
@@ -894,7 +894,7 @@ pub fn first_attr_value_str_by_name(
 }
 
 // JUSTIFICATION: defn of the suggested wrapper fns
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
 impl Session {
     pub fn verbose(&self) -> bool {
         self.opts.unstable_opts.verbose
@@ -1174,7 +1174,7 @@ pub fn link_dead_code(&self) -> bool {
 }
 
 // JUSTIFICATION: part of session construction
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
 fn default_emitter(
     sopts: &config::Options,
     registry: rustc_errors::registry::Registry,
@@ -1260,7 +1260,7 @@ pub enum DiagnosticOutput {
 }
 
 // JUSTIFICATION: literally session construction
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
 pub fn build_session(
     sopts: config::Options,
     local_crate_source_file: Option<PathBuf>,
@@ -1437,7 +1437,7 @@ pub fn build_session(
 /// If it is useful to have a Session available already for validating a commandline argument, you
 /// can do so here.
 // JUSTIFICATION: needs to access args to validate them
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
 fn validate_commandline_args_with_session_available(sess: &Session) {
     // Since we don't know if code in an rlib will be linked to statically or
     // dynamically downstream, rustc generates `__imp_` symbols that help linkers
index 28381157d50a9752d421a20aab17dcecfd1e49fb..ad9f5ba85a1912d23d50aa413de0d3e8bdcf8f2c 100644 (file)
@@ -722,7 +722,7 @@ pub fn span_extend_while(
         })
     }
 
-    /// Extends the given `Span` to just after the next occurrence of `c`.
+    /// Extends the given `Span` to just before the next occurrence of `c`.
     pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
         if let Ok(next_source) = self.span_to_next_source(sp) {
             let next_source = next_source.split(c).next().unwrap_or("");
index 52ac3622eca8d867136b99f025eeb44e332c7265..c126390f5a908dd80234871252ce842168ba5b47 100644 (file)
@@ -63,7 +63,7 @@ pub(super) fn all(obj: &'static str) -> CrtObjects {
     ])
 }
 
-pub(super) fn pre_musl_fallback() -> CrtObjects {
+pub(super) fn pre_musl_self_contained() -> CrtObjects {
     new(&[
         (LinkOutputKind::DynamicNoPicExe, &["crt1.o", "crti.o", "crtbegin.o"]),
         (LinkOutputKind::DynamicPicExe, &["Scrt1.o", "crti.o", "crtbeginS.o"]),
@@ -74,7 +74,7 @@ pub(super) fn pre_musl_fallback() -> CrtObjects {
     ])
 }
 
-pub(super) fn post_musl_fallback() -> CrtObjects {
+pub(super) fn post_musl_self_contained() -> CrtObjects {
     new(&[
         (LinkOutputKind::DynamicNoPicExe, &["crtend.o", "crtn.o"]),
         (LinkOutputKind::DynamicPicExe, &["crtendS.o", "crtn.o"]),
@@ -85,7 +85,7 @@ pub(super) fn post_musl_fallback() -> CrtObjects {
     ])
 }
 
-pub(super) fn pre_mingw_fallback() -> CrtObjects {
+pub(super) fn pre_mingw_self_contained() -> CrtObjects {
     new(&[
         (LinkOutputKind::DynamicNoPicExe, &["crt2.o", "rsbegin.o"]),
         (LinkOutputKind::DynamicPicExe, &["crt2.o", "rsbegin.o"]),
@@ -96,7 +96,7 @@ pub(super) fn pre_mingw_fallback() -> CrtObjects {
     ])
 }
 
-pub(super) fn post_mingw_fallback() -> CrtObjects {
+pub(super) fn post_mingw_self_contained() -> CrtObjects {
     all("rsend.o")
 }
 
@@ -108,7 +108,7 @@ pub(super) fn post_mingw() -> CrtObjects {
     all("rsend.o")
 }
 
-pub(super) fn pre_wasi_fallback() -> CrtObjects {
+pub(super) fn pre_wasi_self_contained() -> CrtObjects {
     // Use crt1-command.o instead of crt1.o to enable support for new-style
     // commands. See https://reviews.llvm.org/D81689 for more info.
     new(&[
@@ -120,37 +120,41 @@ pub(super) fn pre_wasi_fallback() -> CrtObjects {
     ])
 }
 
-pub(super) fn post_wasi_fallback() -> CrtObjects {
+pub(super) fn post_wasi_self_contained() -> CrtObjects {
     new(&[])
 }
 
-/// Which logic to use to determine whether to fall back to the "self-contained" mode or not.
+/// Which logic to use to determine whether to use self-contained linking mode
+/// if `-Clink-self-contained` is not specified explicitly.
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
-pub enum CrtObjectsFallback {
+pub enum LinkSelfContainedDefault {
+    False,
+    True,
     Musl,
     Mingw,
-    Wasm,
 }
 
-impl FromStr for CrtObjectsFallback {
+impl FromStr for LinkSelfContainedDefault {
     type Err = ();
 
-    fn from_str(s: &str) -> Result<CrtObjectsFallback, ()> {
+    fn from_str(s: &str) -> Result<LinkSelfContainedDefault, ()> {
         Ok(match s {
-            "musl" => CrtObjectsFallback::Musl,
-            "mingw" => CrtObjectsFallback::Mingw,
-            "wasm" => CrtObjectsFallback::Wasm,
+            "false" => LinkSelfContainedDefault::False,
+            "true" | "wasm" => LinkSelfContainedDefault::True,
+            "musl" => LinkSelfContainedDefault::Musl,
+            "mingw" => LinkSelfContainedDefault::Mingw,
             _ => return Err(()),
         })
     }
 }
 
-impl ToJson for CrtObjectsFallback {
+impl ToJson for LinkSelfContainedDefault {
     fn to_json(&self) -> Json {
         match *self {
-            CrtObjectsFallback::Musl => "musl",
-            CrtObjectsFallback::Mingw => "mingw",
-            CrtObjectsFallback::Wasm => "wasm",
+            LinkSelfContainedDefault::False => "false",
+            LinkSelfContainedDefault::True => "true",
+            LinkSelfContainedDefault::Musl => "musl",
+            LinkSelfContainedDefault::Mingw => "mingw",
         }
         .to_json()
     }
index 207a87ab0390328cc3763860b4105d9f8e22fc16..61553e71b4500ae4dea3910a6910bf57e9524bf1 100644 (file)
@@ -1,13 +1,13 @@
-use crate::spec::crt_objects::{self, CrtObjectsFallback};
+use crate::spec::crt_objects::{self, LinkSelfContainedDefault};
 use crate::spec::TargetOptions;
 
 pub fn opts() -> TargetOptions {
     let mut base = super::linux_base::opts();
 
     base.env = "musl".into();
-    base.pre_link_objects_fallback = crt_objects::pre_musl_fallback();
-    base.post_link_objects_fallback = crt_objects::post_musl_fallback();
-    base.crt_objects_fallback = Some(CrtObjectsFallback::Musl);
+    base.pre_link_objects_self_contained = crt_objects::pre_musl_self_contained();
+    base.post_link_objects_self_contained = crt_objects::post_musl_self_contained();
+    base.link_self_contained = LinkSelfContainedDefault::Musl;
 
     // These targets statically link libc by default
     base.crt_static_default = true;
index f7abeafd38f10d5870e037edca98ca230c0bd3c2..0b49edc232c06afc2aa77e6b9ba53a5adba8b4e5 100644 (file)
@@ -37,7 +37,7 @@
 use crate::abi::Endian;
 use crate::json::{Json, ToJson};
 use crate::spec::abi::{lookup as lookup_abi, Abi};
-use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
+use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_span::symbol::{sym, Symbol};
@@ -1172,13 +1172,10 @@ pub struct TargetOptions {
     /// Objects to link before and after all other object code.
     pub pre_link_objects: CrtObjects,
     pub post_link_objects: CrtObjects,
-    /// Same as `(pre|post)_link_objects`, but when we fail to pull the objects with help of the
-    /// target's native gcc and fall back to the "self-contained" mode and pull them manually.
-    /// See `crt_objects.rs` for some more detailed documentation.
-    pub pre_link_objects_fallback: CrtObjects,
-    pub post_link_objects_fallback: CrtObjects,
-    /// Which logic to use to determine whether to fall back to the "self-contained" mode or not.
-    pub crt_objects_fallback: Option<CrtObjectsFallback>,
+    /// Same as `(pre|post)_link_objects`, but when self-contained linking mode is enabled.
+    pub pre_link_objects_self_contained: CrtObjects,
+    pub post_link_objects_self_contained: CrtObjects,
+    pub link_self_contained: LinkSelfContainedDefault,
 
     /// Linker arguments that are unconditionally passed after any
     /// user-defined but before post-link objects. Standard platform
@@ -1554,9 +1551,9 @@ fn default() -> TargetOptions {
             relro_level: RelroLevel::None,
             pre_link_objects: Default::default(),
             post_link_objects: Default::default(),
-            pre_link_objects_fallback: Default::default(),
-            post_link_objects_fallback: Default::default(),
-            crt_objects_fallback: None,
+            pre_link_objects_self_contained: Default::default(),
+            post_link_objects_self_contained: Default::default(),
+            link_self_contained: LinkSelfContainedDefault::False,
             late_link_args: LinkArgs::new(),
             late_link_args_dynamic: LinkArgs::new(),
             late_link_args_static: LinkArgs::new(),
@@ -1977,20 +1974,20 @@ macro_rules! key {
                 Ok::<(), String>(())
             } );
 
-            ($key_name:ident, crt_objects_fallback) => ( {
-                let name = (stringify!($key_name)).replace("_", "-");
-                obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
-                    match s.parse::<CrtObjectsFallback>() {
-                        Ok(fallback) => base.$key_name = Some(fallback),
-                        _ => return Some(Err(format!("'{}' is not a valid CRT objects fallback. \
-                                                      Use 'musl', 'mingw' or 'wasm'", s))),
+            ($key_name:ident = $json_name:expr, link_self_contained) => ( {
+                let name = $json_name;
+                obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
+                    match s.parse::<LinkSelfContainedDefault>() {
+                        Ok(lsc_default) => base.$key_name = lsc_default,
+                        _ => return Some(Err(format!("'{}' is not a valid `-Clink-self-contained` default. \
+                                                      Use 'false', 'true', 'musl' or 'mingw'", s))),
                     }
                     Some(Ok(()))
                 })).unwrap_or(Ok(()))
             } );
-            ($key_name:ident, link_objects) => ( {
-                let name = (stringify!($key_name)).replace("_", "-");
-                if let Some(val) = obj.remove(&name) {
+            ($key_name:ident = $json_name:expr, link_objects) => ( {
+                let name = $json_name;
+                if let Some(val) = obj.remove(name) {
                     let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
                         JSON object with fields per CRT object kind.", name))?;
                     let mut args = CrtObjects::new();
@@ -2112,11 +2109,11 @@ macro_rules! key {
         key!(linker_flavor, LinkerFlavor)?;
         key!(linker, optional);
         key!(lld_flavor, LldFlavor)?;
-        key!(pre_link_objects, link_objects);
-        key!(post_link_objects, link_objects);
-        key!(pre_link_objects_fallback, link_objects);
-        key!(post_link_objects_fallback, link_objects);
-        key!(crt_objects_fallback, crt_objects_fallback)?;
+        key!(pre_link_objects = "pre-link-objects", link_objects);
+        key!(post_link_objects = "post-link-objects", link_objects);
+        key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects);
+        key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects);
+        key!(link_self_contained = "crt-objects-fallback", link_self_contained)?;
         key!(pre_link_args, link_args);
         key!(late_link_args, link_args);
         key!(late_link_args_dynamic, link_args);
@@ -2357,9 +2354,9 @@ macro_rules! target_option_val {
         target_option_val!(lld_flavor);
         target_option_val!(pre_link_objects);
         target_option_val!(post_link_objects);
-        target_option_val!(pre_link_objects_fallback);
-        target_option_val!(post_link_objects_fallback);
-        target_option_val!(crt_objects_fallback);
+        target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback");
+        target_option_val!(post_link_objects_self_contained, "post-link-objects-fallback");
+        target_option_val!(link_self_contained, "crt-objects-fallback");
         target_option_val!(link_args - pre_link_args);
         target_option_val!(link_args - late_link_args);
         target_option_val!(link_args - late_link_args_dynamic);
index 1db6db78b17e4f8e0e7125270f6110ccbf843b55..03e579aee0a96f042c7188a704c10d54cfb608f4 100644 (file)
@@ -110,9 +110,9 @@ fn check_consistency(&self) {
         }
 
         assert!(
-            (self.pre_link_objects_fallback.is_empty()
-                && self.post_link_objects_fallback.is_empty())
-                || self.crt_objects_fallback.is_some()
+            (self.pre_link_objects_self_contained.is_empty()
+                && self.post_link_objects_self_contained.is_empty())
+                || self.link_self_contained != LinkSelfContainedDefault::False
         );
 
         // If your target really needs to deviate from the rules below,
index 280457d68b99e436502f18986b3bdc49a06c1705..9c30487f4abe796debeffff725252b07b49a4ce4 100644 (file)
@@ -82,8 +82,8 @@ pub fn target() -> Target {
     options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
     options.add_pre_link_args(LinkerFlavor::Gcc, &["--target=wasm32-wasi"]);
 
-    options.pre_link_objects_fallback = crt_objects::pre_wasi_fallback();
-    options.post_link_objects_fallback = crt_objects::post_wasi_fallback();
+    options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
+    options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();
 
     // Right now this is a bit of a workaround but we're currently saying that
     // the target by default has a static crt which we're taking as a signal
index 9216d3e7b65f60358424dd212d6f71c058d0b7fe..28a07701eae74ec2bb2b2b3ca9e0d07a4535f5f7 100644 (file)
@@ -1,4 +1,4 @@
-use super::crt_objects::CrtObjectsFallback;
+use super::crt_objects::LinkSelfContainedDefault;
 use super::{cvs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel};
 
 pub fn options() -> TargetOptions {
@@ -96,7 +96,8 @@ macro_rules! args {
 
         pre_link_args,
 
-        crt_objects_fallback: Some(CrtObjectsFallback::Wasm),
+        // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
+        link_self_contained: LinkSelfContainedDefault::True,
 
         // This has no effect in LLVM 8 or prior, but in LLVM 9 and later when
         // PIC code is implemented this has quite a drastic effect if it stays
index 90e0af3e38afead9a3d7bbe6a6e4798c73522ac2..0107f7a52c6ffebc0e2f04e5c1b5215f989e0c70 100644 (file)
@@ -1,4 +1,4 @@
-use crate::spec::crt_objects::{self, CrtObjectsFallback};
+use crate::spec::crt_objects::{self, LinkSelfContainedDefault};
 use crate::spec::{cvs, LinkerFlavor, TargetOptions};
 
 pub fn opts() -> TargetOptions {
@@ -76,9 +76,9 @@ pub fn opts() -> TargetOptions {
         pre_link_args,
         pre_link_objects: crt_objects::pre_mingw(),
         post_link_objects: crt_objects::post_mingw(),
-        pre_link_objects_fallback: crt_objects::pre_mingw_fallback(),
-        post_link_objects_fallback: crt_objects::post_mingw_fallback(),
-        crt_objects_fallback: Some(CrtObjectsFallback::Mingw),
+        pre_link_objects_self_contained: crt_objects::pre_mingw_self_contained(),
+        post_link_objects_self_contained: crt_objects::post_mingw_self_contained(),
+        link_self_contained: LinkSelfContainedDefault::Mingw,
         late_link_args,
         late_link_args_dynamic,
         late_link_args_static,
index c33629192cb2b19e2aca27fee9f450a5d3976a2d..9c252fcfe1c638c3246fd6bf3ce687e6f188d561 100644 (file)
@@ -17,7 +17,6 @@
 #![feature(drain_filter)]
 #![feature(hash_drain_filter)]
 #![feature(label_break_value)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(if_let_guard)]
 #![feature(never_type)]
index 8ab1aa65d3a9f43dccd5460bbdc5f3dce4af1a1e..9bb41b900b89a35f34a6d8f393dfadea91a20de0 100644 (file)
@@ -307,7 +307,13 @@ fn negative_impl<'cx, 'tcx>(
             tcx.impl_subject(impl1_def_id),
         ) {
             Ok(s) => s,
-            Err(err) => bug!("failed to fully normalize {:?}: {:?}", impl1_def_id, err),
+            Err(err) => {
+                tcx.sess.delay_span_bug(
+                    tcx.def_span(impl1_def_id),
+                    format!("failed to fully normalize {:?}: {:?}", impl1_def_id, err),
+                );
+                return false;
+            }
         };
 
         // Attempt to prove that impl2 applies, given all of the above.
@@ -734,7 +740,21 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
         result
     }
 
-    // FIXME: Constants should participate in orphan checking.
+    /// All possible values for a constant parameter already exist
+    /// in the crate defining the trait, so they are always non-local[^1].
+    ///
+    /// Because there's no way to have an impl where the first local
+    /// generic argument is a constant, we also don't have to fail
+    /// the orphan check when encountering a parameter or a generic constant.
+    ///
+    /// This means that we can completely ignore constants during the orphan check.
+    ///
+    /// See `src/test/ui/coherence/const-generics-orphan-check-ok.rs` for examples.
+    ///
+    /// [^1]: This might not hold for function pointers or trait objects in the future.
+    /// As these should be quite rare as const arguments and especially rare as impl
+    /// parameters, allowing uncovered const parameters in impls seems more useful
+    /// than allowing `impl<T> Trait<local_fn_ptr, T> for i32` to compile.
     fn visit_const(&mut self, _c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
         ControlFlow::CONTINUE
     }
index e4f918b4b0eaebce14bb850d5da16da1115b5fde..4260cb53adc1c6fe07a10422b497414746643c2a 100644 (file)
@@ -1507,8 +1507,7 @@ fn report_projection_error(
         }
 
         self.probe(|_| {
-            let err_buf;
-            let mut err = &error.err;
+            let mut err = error.err;
             let mut values = None;
 
             // try to find the mismatched types to report the error with.
@@ -1544,14 +1543,13 @@ fn report_projection_error(
                         | ObligationCauseCode::ObjectCastObligation(..)
                         | ObligationCauseCode::OpaqueType
                 );
-                if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
+                if let Err(new_err) = self.at(&obligation.cause, obligation.param_env).eq_exp(
                     is_normalized_ty_expected,
                     normalized_ty,
                     data.term,
                 ) {
                     values = Some((data, is_normalized_ty_expected, normalized_ty, data.term));
-                    err_buf = error;
-                    err = &err_buf;
+                    err = new_err;
                 }
             }
 
index 414857f0acc8096b4f938f9e6e3c85405ab06c91..7a5e67ff74b32daa78845d419948750b035633eb 100644 (file)
@@ -31,9 +31,9 @@ pub fn obligations<'a, 'tcx>(
                     if resolved_ty == ty {
                         // No progress, bail out to prevent "livelock".
                         return None;
+                    } else {
+                        resolved_ty
                     }
-
-                    resolved_ty
                 }
                 _ => ty,
             }
@@ -41,16 +41,14 @@ pub fn obligations<'a, 'tcx>(
         }
         GenericArgKind::Const(ct) => {
             match ct.kind() {
-                ty::ConstKind::Infer(infer) => {
-                    let resolved = infcx.shallow_resolve(infer);
-                    if resolved == infer {
+                ty::ConstKind::Infer(_) => {
+                    let resolved = infcx.shallow_resolve(ct);
+                    if resolved == ct {
                         // No progress.
                         return None;
+                    } else {
+                        resolved
                     }
-
-                    infcx
-                        .tcx
-                        .mk_const(ty::ConstS { kind: ty::ConstKind::Infer(resolved), ty: ct.ty() })
                 }
                 _ => ct,
             }
index 758f1ef97664f1d4c6572e837342907561829fcd..1e6cb53f3eeaed8247baf6006e4df396442714ce 100644 (file)
@@ -44,7 +44,7 @@
 };
 use rustc_trait_selection::traits::wf::object_region_bounds;
 
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 use std::collections::BTreeSet;
 use std::slice;
 
@@ -368,36 +368,13 @@ fn create_substs_for_ast_path<'a>(
             return (tcx.intern_substs(&[]), arg_count);
         }
 
-        let is_object = self_ty.map_or(false, |ty| ty == self.tcx().types.trait_object_dummy_self);
-
         struct SubstsForAstPathCtxt<'a, 'tcx> {
             astconv: &'a (dyn AstConv<'tcx> + 'a),
             def_id: DefId,
             generic_args: &'a GenericArgs<'a>,
             span: Span,
-            missing_type_params: Vec<Symbol>,
             inferred_params: Vec<Span>,
             infer_args: bool,
-            is_object: bool,
-        }
-
-        impl<'tcx, 'a> SubstsForAstPathCtxt<'tcx, 'a> {
-            fn default_needs_object_self(&mut self, param: &ty::GenericParamDef) -> bool {
-                let tcx = self.astconv.tcx();
-                if let GenericParamDefKind::Type { has_default, .. } = param.kind {
-                    if self.is_object && has_default {
-                        let default_ty = tcx.at(self.span).type_of(param.def_id);
-                        let self_param = tcx.types.self_param;
-                        if default_ty.walk().any(|arg| arg == self_param.into()) {
-                            // There is no suitable inference default for a type parameter
-                            // that references self, in an object type.
-                            return true;
-                        }
-                    }
-                }
-
-                false
-            }
         }
 
         impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for SubstsForAstPathCtxt<'a, 'tcx> {
@@ -500,41 +477,23 @@ fn inferred_kind(
                     GenericParamDefKind::Type { has_default, .. } => {
                         if !infer_args && has_default {
                             // No type parameter provided, but a default exists.
-
-                            // If we are converting an object type, then the
-                            // `Self` parameter is unknown. However, some of the
-                            // other type parameters may reference `Self` in their
-                            // defaults. This will lead to an ICE if we are not
-                            // careful!
-                            if self.default_needs_object_self(param) {
-                                self.missing_type_params.push(param.name);
-                                tcx.ty_error().into()
-                            } else {
-                                // This is a default type parameter.
-                                let substs = substs.unwrap();
-                                if substs.iter().any(|arg| match arg.unpack() {
-                                    GenericArgKind::Type(ty) => ty.references_error(),
-                                    _ => false,
-                                }) {
-                                    // Avoid ICE #86756 when type error recovery goes awry.
-                                    return tcx.ty_error().into();
-                                }
-                                self.astconv
-                                    .normalize_ty(
-                                        self.span,
-                                        EarlyBinder(tcx.at(self.span).type_of(param.def_id))
-                                            .subst(tcx, substs),
-                                    )
-                                    .into()
+                            let substs = substs.unwrap();
+                            if substs.iter().any(|arg| match arg.unpack() {
+                                GenericArgKind::Type(ty) => ty.references_error(),
+                                _ => false,
+                            }) {
+                                // Avoid ICE #86756 when type error recovery goes awry.
+                                return tcx.ty_error().into();
                             }
+                            self.astconv
+                                .normalize_ty(
+                                    self.span,
+                                    EarlyBinder(tcx.at(self.span).type_of(param.def_id))
+                                        .subst(tcx, substs),
+                                )
+                                .into()
                         } else if infer_args {
-                            // No type parameters were provided, we can infer all.
-                            let param = if !self.default_needs_object_self(param) {
-                                Some(param)
-                            } else {
-                                None
-                            };
-                            self.astconv.ty_infer(param, self.span).into()
+                            self.astconv.ty_infer(Some(param), self.span).into()
                         } else {
                             // We've already errored above about the mismatch.
                             tcx.ty_error().into()
@@ -564,10 +523,8 @@ fn inferred_kind(
             def_id,
             span,
             generic_args,
-            missing_type_params: vec![],
             inferred_params: vec![],
             infer_args,
-            is_object,
         };
         let substs = Self::create_substs_for_generic_args(
             tcx,
@@ -579,13 +536,6 @@ fn inferred_kind(
             &mut substs_ctx,
         );
 
-        self.complain_about_missing_type_params(
-            substs_ctx.missing_type_params,
-            def_id,
-            span,
-            generic_args.args.is_empty(),
-        );
-
         debug!(
             "create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}",
             generics, self_ty, substs
@@ -1490,23 +1440,71 @@ trait here instead: `trait NewTrait: {} {{}}`",
         // Erase the `dummy_self` (`trait_object_dummy_self`) used above.
         let existential_trait_refs = regular_traits.iter().map(|i| {
             i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| {
-                if trait_ref.self_ty() != dummy_self {
-                    // FIXME: There appears to be a missing filter on top of `expand_trait_aliases`,
-                    // which picks up non-supertraits where clauses - but also, the object safety
-                    // completely ignores trait aliases, which could be object safety hazards. We
-                    // `delay_span_bug` here to avoid an ICE in stable even when the feature is
-                    // disabled. (#66420)
-                    tcx.sess.delay_span_bug(
-                        DUMMY_SP,
-                        &format!(
-                            "trait_ref_to_existential called on {:?} with non-dummy Self",
-                            trait_ref,
-                        ),
+                assert_eq!(trait_ref.self_ty(), dummy_self);
+
+                // Verify that `dummy_self` did not leak inside default type parameters.  This
+                // could not be done at path creation, since we need to see through trait aliases.
+                let mut missing_type_params = vec![];
+                let mut references_self = false;
+                let generics = tcx.generics_of(trait_ref.def_id);
+                let substs: Vec<_> = trait_ref
+                    .substs
+                    .iter()
+                    .enumerate()
+                    .skip(1) // Remove `Self` for `ExistentialPredicate`.
+                    .map(|(index, arg)| {
+                        if let ty::GenericArgKind::Type(ty) = arg.unpack() {
+                            debug!(?ty);
+                            if ty == dummy_self {
+                                let param = &generics.params[index];
+                                missing_type_params.push(param.name);
+                                tcx.ty_error().into()
+                            } else if ty.walk().any(|arg| arg == dummy_self.into()) {
+                                references_self = true;
+                                tcx.ty_error().into()
+                            } else {
+                                arg
+                            }
+                        } else {
+                            arg
+                        }
+                    })
+                    .collect();
+                let substs = tcx.intern_substs(&substs[..]);
+
+                let span = i.bottom().1;
+                let empty_generic_args = trait_bounds.iter().any(|hir_bound| {
+                    hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
+                        && hir_bound.span.contains(span)
+                });
+                self.complain_about_missing_type_params(
+                    missing_type_params,
+                    trait_ref.def_id,
+                    span,
+                    empty_generic_args,
+                );
+
+                if references_self {
+                    let def_id = i.bottom().0.def_id();
+                    let mut err = struct_span_err!(
+                        tcx.sess,
+                        i.bottom().1,
+                        E0038,
+                        "the {} `{}` cannot be made into an object",
+                        tcx.def_kind(def_id).descr(def_id),
+                        tcx.item_name(def_id),
+                    );
+                    err.note(
+                        rustc_middle::traits::ObjectSafetyViolation::SupertraitSelf(smallvec![])
+                            .error_msg(),
                     );
+                    err.emit();
                 }
-                ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
+
+                ty::ExistentialTraitRef { def_id: trait_ref.def_id, substs }
             })
         });
+
         let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| {
             bound.map_bound(|b| {
                 if b.projection_ty.self_ty() != dummy_self {
index 15a995ae59a8bfd8966a1c7a0bce88d9b2cc1459..ec8d22e81d1c01dd702c8a2e513df63ba221ed99 100644 (file)
@@ -291,7 +291,7 @@ fn compare_predicate_entailment<'tcx>(
             debug!("sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
 
             let (impl_err_span, trait_err_span) =
-                extract_spans_for_error_reporting(&infcx, &terr, &cause, impl_m, trait_m);
+                extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);
 
             cause.span = impl_err_span;
 
@@ -381,7 +381,7 @@ fn compare_predicate_entailment<'tcx>(
                     expected: trait_fty.into(),
                     found: impl_fty.into(),
                 })),
-                &terr,
+                terr,
                 false,
                 false,
             );
@@ -468,7 +468,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
 #[instrument(level = "debug", skip(infcx))]
 fn extract_spans_for_error_reporting<'a, 'tcx>(
     infcx: &infer::InferCtxt<'a, 'tcx>,
-    terr: &TypeError<'_>,
+    terr: TypeError<'_>,
     cause: &ObligationCause<'tcx>,
     impl_m: &ty::AssocItem,
     trait_m: &ty::AssocItem,
@@ -488,7 +488,7 @@ fn extract_spans_for_error_reporting<'a, 'tcx>(
             _ => bug!("{:?} is not a TraitItemKind::Fn", trait_m),
         });
 
-    match *terr {
+    match terr {
         TypeError::ArgumentMutability(i) => {
             (impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i)))
         }
@@ -1143,7 +1143,7 @@ pub(crate) fn compare_const_impl<'tcx>(
                     expected: trait_ty.into(),
                     found: impl_ty.into(),
                 })),
-                &terr,
+                terr,
                 false,
                 false,
             );
index bac0be44aa9a2f4b04d1b902fe93d2afaa463d18..07046f3f0326b119185f836728bd3bf49df39873 100644 (file)
@@ -638,11 +638,9 @@ pub(crate) fn maybe_get_struct_pattern_shorthand_field(
         }?;
 
         match hir.find(hir.get_parent_node(expr.hir_id))? {
-            Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(_, fields, ..), .. }) => {
-                for field in *fields {
-                    if field.ident.name == local.name && field.is_shorthand {
-                        return Some(local.name);
-                    }
+            Node::ExprField(field) => {
+                if field.ident.name == local.name && field.is_shorthand {
+                    return Some(local.name);
                 }
             }
             _ => {}
@@ -1073,21 +1071,16 @@ pub fn check_for_cast(
 
         let mut sugg = vec![];
 
-        if let Some(hir::Node::Expr(hir::Expr {
-            kind: hir::ExprKind::Struct(_, fields, _), ..
-        })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id))
+        if let Some(hir::Node::ExprField(field)) =
+            self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id))
         {
             // `expr` is a literal field for a struct, only suggest if appropriate
-            match (*fields)
-                .iter()
-                .find(|field| field.expr.hir_id == expr.hir_id && field.is_shorthand)
-            {
+            if field.is_shorthand {
                 // This is a field literal
-                Some(field) => {
-                    sugg.push((field.ident.span.shrink_to_lo(), format!("{}: ", field.ident)));
-                }
+                sugg.push((field.ident.span.shrink_to_lo(), format!("{}: ", field.ident)));
+            } else {
                 // Likely a field was meant, but this field wasn't found. Do not suggest anything.
-                None => return false,
+                return false;
             }
         };
 
index 1d1f755947fdcde4a167d5776f08a80c8746af3c..aab60de80ef14e65592dea4556e3495a5e11367a 100644 (file)
@@ -58,7 +58,17 @@ pub(in super::super) fn check_asms(&self) {
         debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len());
         for (asm, hir_id) in deferred_asm_checks.drain(..) {
             let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id);
-            InlineAsmCtxt::new_in_fn(self)
+            let get_operand_ty = |expr| {
+                let ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
+                let ty = self.resolve_vars_if_possible(ty);
+                if ty.has_infer_types_or_consts() {
+                    assert!(self.is_tainted_by_errors());
+                    self.tcx.ty_error()
+                } else {
+                    self.tcx.erase_regions(ty)
+                }
+            };
+            InlineAsmCtxt::new_in_fn(self.tcx, self.param_env, get_operand_ty)
                 .check_asm(asm, self.tcx.hir().local_def_id_to_hir_id(enclosing_id));
         }
     }
@@ -440,7 +450,7 @@ fn report_arg_errors(
         call_expr: &hir::Expr<'tcx>,
     ) {
         // Next, let's construct the error
-        let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
+        let (error_span, full_call_span, ctor_of, is_method) = match &call_expr.kind {
             hir::ExprKind::Call(
                 hir::Expr { hir_id, span, kind: hir::ExprKind::Path(qpath), .. },
                 _,
@@ -448,12 +458,12 @@ fn report_arg_errors(
                 if let Res::Def(DefKind::Ctor(of, _), _) =
                     self.typeck_results.borrow().qpath_res(qpath, *hir_id)
                 {
-                    (call_span, *span, Some(of))
+                    (call_span, *span, Some(of), false)
                 } else {
-                    (call_span, *span, None)
+                    (call_span, *span, None, false)
                 }
             }
-            hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None),
+            hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None, false),
             hir::ExprKind::MethodCall(path_segment, _, span) => {
                 let ident_span = path_segment.ident.span;
                 let ident_span = if let Some(args) = path_segment.args {
@@ -461,9 +471,8 @@ fn report_arg_errors(
                 } else {
                     ident_span
                 };
-                (
-                    *span, ident_span, None, // methods are never ctors
-                )
+                // methods are never ctors
+                (*span, ident_span, None, true)
             }
             k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
         };
@@ -545,7 +554,9 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
             let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
             let can_coerce = self.can_coerce(arg_ty, coerced_ty);
             if !can_coerce {
-                return Compatibility::Incompatible(None);
+                return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts(
+                    ty::error::ExpectedFound::new(true, coerced_ty, arg_ty),
+                )));
             }
 
             // Using probe here, since we don't want this subtyping to affect inference.
@@ -577,7 +588,11 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
         // First, check if we just need to wrap some arguments in a tuple.
         if let Some((mismatch_idx, terr)) =
             compatibility_diagonal.iter().enumerate().find_map(|(i, c)| {
-                if let Compatibility::Incompatible(Some(terr)) = c { Some((i, terr)) } else { None }
+                if let Compatibility::Incompatible(Some(terr)) = c {
+                    Some((i, *terr))
+                } else {
+                    None
+                }
             })
         {
             // Is the first bad expected argument a tuple?
@@ -659,7 +674,7 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
                             Applicability::MachineApplicable,
                         );
                     };
-                    self.label_fn_like(&mut err, fn_def_id, callee_ty);
+                    self.label_fn_like(&mut err, fn_def_id, callee_ty, Some(mismatch_idx), is_method);
                     err.emit();
                     return;
                 }
@@ -701,16 +716,14 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
         }
 
         errors.drain_filter(|error| {
-                let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(error)) = error else { return false };
+                let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
                 let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
                 let (expected_ty, _) = formal_and_expected_inputs[*expected_idx];
                 let cause = &self.misc(provided_span);
                 let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
-                if let Some(e) = error {
-                    if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
-                        self.report_and_explain_type_error(trace, e).emit();
-                        return true;
-                    }
+                if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) {
+                    self.report_and_explain_type_error(trace, *e).emit();
+                    return true;
                 }
                 false
             });
@@ -733,7 +746,7 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
             let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
             let cause = &self.misc(provided_arg_span);
             let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
-            let mut err = self.report_and_explain_type_error(trace, err);
+            let mut err = self.report_and_explain_type_error(trace, *err);
             self.emit_coerce_suggestions(
                 &mut err,
                 &provided_args[*provided_idx],
@@ -749,7 +762,13 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
                 format!("arguments to this {} are incorrect", call_name),
             );
             // Call out where the function is defined
-            self.label_fn_like(&mut err, fn_def_id, callee_ty);
+            self.label_fn_like(
+                &mut err,
+                fn_def_id,
+                callee_ty,
+                Some(expected_idx.as_usize()),
+                is_method,
+            );
             err.emit();
             return;
         }
@@ -797,7 +816,7 @@ enum SuggestionText {
                 Error::Invalid(provided_idx, expected_idx, compatibility) => {
                     let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
                     let (provided_ty, provided_span) = provided_arg_tys[provided_idx];
-                    if let Compatibility::Incompatible(error) = &compatibility {
+                    if let Compatibility::Incompatible(error) = compatibility {
                         let cause = &self.misc(provided_span);
                         let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
                         if let Some(e) = error {
@@ -1031,7 +1050,7 @@ enum SuggestionText {
         }
 
         // Call out where the function is defined
-        self.label_fn_like(&mut err, fn_def_id, callee_ty);
+        self.label_fn_like(&mut err, fn_def_id, callee_ty, None, is_method);
 
         // And add a suggestion block for all of the parameters
         let suggestion_text = match suggestion_text {
@@ -1655,12 +1674,13 @@ fn unpeel_to_top<'a, 'tcx>(
                     ObligationCauseCode::ImplDerivedObligation(code) => {
                         code.derived.parent_trait_pred.self_ty().skip_binder().into()
                     }
-                    _ if let ty::PredicateKind::Trait(predicate) =
-                        error.obligation.predicate.kind().skip_binder() =>
-                    {
-                        predicate.self_ty().into()
-                    }
-                    _ => continue,
+                    _ => match error.obligation.predicate.kind().skip_binder() {
+                        ty::PredicateKind::Trait(predicate) => predicate.self_ty().into(),
+                        ty::PredicateKind::Projection(predicate) => {
+                            predicate.projection_ty.self_ty().into()
+                        }
+                        _ => continue,
+                    },
                 };
             let self_ = self.resolve_vars_if_possible(self_);
             let ty_matches_self = |ty: Ty<'tcx>| ty.walk().any(|arg| arg == self_);
@@ -1750,25 +1770,28 @@ fn point_at_type_arg_instead_of_call_if_possible(
         if let hir::ExprKind::Call(path, _) = &call_expr.kind {
             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()
+                    let self_ty = match error.obligation.predicate.kind().skip_binder() {
+                        ty::PredicateKind::Trait(predicate) => predicate.self_ty(),
+                        ty::PredicateKind::Projection(predicate) => {
+                            predicate.projection_ty.self_ty()
+                        }
+                        _ => continue,
+                    };
+                    // 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
+                            && let Some(ty) =
+                                self.typeck_results.borrow().node_type_opt(hir_ty.hir_id)
+                            && self.resolve_vars_if_possible(ty) == self_ty
                         {
-                            if let hir::GenericArg::Type(hir_ty) = &arg
-                                && let Some(ty) =
-                                    self.typeck_results.borrow().node_type_opt(hir_ty.hir_id)
-                                && self.resolve_vars_if_possible(ty) == predicate.self_ty()
-                            {
-                                error.obligation.cause.span = hir_ty.span;
-                                break;
-                            }
+                            error.obligation.cause.span = hir_ty.span;
+                            break;
                         }
                     }
                 }
@@ -1781,6 +1804,9 @@ fn label_fn_like(
         err: &mut Diagnostic,
         callable_def_id: Option<DefId>,
         callee_ty: Option<Ty<'tcx>>,
+        // A specific argument should be labeled, instead of all of them
+        expected_idx: Option<usize>,
+        is_method: bool,
     ) {
         let Some(mut def_id) = callable_def_id else {
             return;
@@ -1881,14 +1907,30 @@ fn label_fn_like(
                 .get_if_local(def_id)
                 .and_then(|node| node.body_id())
                 .into_iter()
-                .flat_map(|id| self.tcx.hir().body(id).params);
+                .flat_map(|id| self.tcx.hir().body(id).params)
+                .skip(if is_method { 1 } else { 0 });
 
-            for param in params {
+            for (_, param) in params
+                .into_iter()
+                .enumerate()
+                .filter(|(idx, _)| expected_idx.map_or(true, |expected_idx| expected_idx == *idx))
+            {
                 spans.push_span_label(param.span, "");
             }
 
             let def_kind = self.tcx.def_kind(def_id);
             err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
+        } else if let Some(hir::Node::Expr(e)) = self.tcx.hir().get_if_local(def_id)
+            && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind
+        {
+            let param = expected_idx
+                .and_then(|expected_idx| self.tcx.hir().body(*body).params.get(expected_idx));
+            let (kind, span) = if let Some(param) = param {
+                ("closure parameter", param.span)
+            } else {
+                ("closure", self.tcx.def_span(def_id))
+            };
+            err.span_note(span, &format!("{} defined here", kind));
         } else {
             let def_kind = self.tcx.def_kind(def_id);
             err.span_note(
index a2c23db162b037414956a99403093dc11062d827..3e96b3ffb0940e7b41228728ab0bf58704872dd5 100644 (file)
@@ -256,6 +256,8 @@ fn find_target_expression_from_destination(
                 | hir::Node::TypeBinding(..)
                 | hir::Node::TraitRef(..)
                 | hir::Node::Pat(..)
+                | hir::Node::PatField(..)
+                | hir::Node::ExprField(..)
                 | hir::Node::Arm(..)
                 | hir::Node::Local(..)
                 | hir::Node::Ctor(..)
index 3f2a0da8d65156b2f20f3ad24b1b1944de54b30b..05686be5d4b3dfb081f327b2ab2d615053ce4a5c 100644 (file)
@@ -69,6 +69,9 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
         // to note that it's safe to call, since
         // safe extern fns are otherwise unprecedented.
         sym::abort
+        | sym::assert_inhabited
+        | sym::assert_zero_valid
+        | sym::assert_uninit_valid
         | sym::size_of
         | sym::min_align_of
         | sym::needs_drop
index df94abbafb1bd7e9cb726c2935a074bd650c6a84..721ebba6514779066e486d8214ebe3ab2bd76aea 100644 (file)
@@ -9,7 +9,6 @@
 use rustc_span::{Span, Symbol, DUMMY_SP};
 use rustc_target::abi::{Pointer, VariantIdx};
 use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType};
-use rustc_trait_selection::infer::InferCtxtExt;
 
 use super::FnCtxt;
 
@@ -98,12 +97,36 @@ pub fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
         }
         err.emit();
     }
+}
+
+pub struct InlineAsmCtxt<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    get_operand_ty: Box<dyn Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a>,
+}
+
+impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
+    pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
+        InlineAsmCtxt {
+            tcx,
+            param_env: ty::ParamEnv::empty(),
+            get_operand_ty: Box::new(|e| bug!("asm operand in global asm: {e:?}")),
+        }
+    }
+
+    pub fn new_in_fn(
+        tcx: TyCtxt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        get_operand_ty: impl Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a,
+    ) -> Self {
+        InlineAsmCtxt { tcx, param_env, get_operand_ty: Box::new(get_operand_ty) }
+    }
 
     // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
     fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
         // Type still may have region variables, but `Sized` does not depend
         // on those, so just erase them before querying.
-        if self.tcx.erase_regions(ty).is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
+        if ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
             return true;
         }
         if let ty::Foreign(..) = ty.kind() {
@@ -111,36 +134,21 @@ fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
         }
         false
     }
-}
-
-pub struct InlineAsmCtxt<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    fcx: Option<&'a FnCtxt<'a, 'tcx>>,
-}
-
-impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
-    pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
-        InlineAsmCtxt { tcx, fcx: None }
-    }
-
-    pub fn new_in_fn(fcx: &'a FnCtxt<'a, 'tcx>) -> Self {
-        InlineAsmCtxt { tcx: fcx.tcx, fcx: Some(fcx) }
-    }
 
     fn check_asm_operand_type(
         &self,
         idx: usize,
         reg: InlineAsmRegOrRegClass,
-        expr: &hir::Expr<'tcx>,
+        expr: &'tcx hir::Expr<'tcx>,
         template: &[InlineAsmTemplatePiece],
         is_input: bool,
-        tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
+        tied_input: Option<(&'tcx hir::Expr<'tcx>, Option<InlineAsmType>)>,
         target_features: &FxHashSet<Symbol>,
     ) -> Option<InlineAsmType> {
-        let fcx = self.fcx.unwrap_or_else(|| span_bug!(expr.span, "asm operand for global asm"));
-        // Check the type against the allowed types for inline asm.
-        let ty = fcx.typeck_results.borrow().expr_ty_adjusted(expr);
-        let ty = fcx.resolve_vars_if_possible(ty);
+        let ty = (self.get_operand_ty)(expr);
+        if ty.has_infer_types_or_consts() {
+            bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty);
+        }
         let asm_ty_isize = match self.tcx.sess.target.pointer_width {
             16 => InlineAsmType::I16,
             32 => InlineAsmType::I32,
@@ -148,12 +156,6 @@ fn check_asm_operand_type(
             _ => unreachable!(),
         };
 
-        // Expect types to be fully resolved, no const or type variables.
-        if ty.has_infer_types_or_consts() {
-            assert!(fcx.is_tainted_by_errors());
-            return None;
-        }
-
         let asm_ty = match *ty.kind() {
             // `!` is allowed for input but not for output (issue #87802)
             ty::Never if is_input => return None,
@@ -167,7 +169,7 @@ fn check_asm_operand_type(
             ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
             ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
             ty::FnPtr(_) => Some(asm_ty_isize),
-            ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if fcx.is_thin_ptr_ty(ty) => {
+            ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
                 Some(asm_ty_isize)
             }
             ty::Adt(adt, substs) if adt.repr().simd() => {
@@ -219,7 +221,7 @@ fn check_asm_operand_type(
 
         // Check that the type implements Copy. The only case where this can
         // possibly fail is for SIMD types which don't #[derive(Copy)].
-        if !fcx.infcx.type_is_copy_modulo_regions(fcx.param_env, ty, DUMMY_SP) {
+        if !ty.is_copy_modulo_regions(self.tcx.at(expr.span), self.param_env) {
             let msg = "arguments for inline assembly must be copyable";
             let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
             err.note(&format!("`{ty}` does not implement the Copy trait"));
@@ -240,8 +242,7 @@ fn check_asm_operand_type(
                 let msg = "incompatible types for asm inout argument";
                 let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg);
 
-                let in_expr_ty = fcx.typeck_results.borrow().expr_ty_adjusted(in_expr);
-                let in_expr_ty = fcx.resolve_vars_if_possible(in_expr_ty);
+                let in_expr_ty = (self.get_operand_ty)(in_expr);
                 err.span_label(in_expr.span, &format!("type `{in_expr_ty}`"));
                 err.span_label(expr.span, &format!("type `{ty}`"));
                 err.note(
index a13c7152582077defba80f87f24df6a44adc8c4e..6dcc364bb50f7838df7687d5428d643313748e77 100644 (file)
@@ -927,7 +927,7 @@ fn emit_bad_pat_path(
                     ),
                 );
                 match self.tcx.hir().get(self.tcx.hir().get_parent_node(pat.hir_id)) {
-                    hir::Node::Pat(Pat { kind: hir::PatKind::Struct(..), .. }) => {
+                    hir::Node::PatField(..) => {
                         e.span_suggestion_verbose(
                             ident.span.shrink_to_hi(),
                             "bind the struct field to a different name instead",
index f549807c39c91c7626dd99f2e4dc1e5003809d92..ebf1f5061835fd041bcd1fddda76fcf20d5e35a2 100644 (file)
@@ -292,6 +292,17 @@ fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
         intravisit::walk_expr(self, e);
     }
 
+    fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
+        match &p.kind {
+            hir::GenericParamKind::Lifetime { .. } => {
+                // Nothing to write back here
+            }
+            hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => {
+                self.tcx().sess.delay_span_bug(p.span, format!("unexpected generic param: {p:?}"));
+            }
+        }
+    }
+
     fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) {
         self.visit_node_id(b.span, b.hir_id);
         intravisit::walk_block(self, b);
index 1563f3552c54133457088b77ce526b58e8fc8139..8c6fb6a77181d9b76044040d20d000674407f2dc 100644 (file)
@@ -65,7 +65,6 @@
 #![feature(is_sorted)]
 #![feature(iter_intersperse)]
 #![feature(label_break_value)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
index cc8da7bccff751b89aaacd76518ff88b88698ac8..80b067812ba7d71a0f0f36ae38a06664a516630a 100644 (file)
     #[rustc_allocator]
     #[rustc_allocator_nounwind]
     fn __rust_alloc(size: usize, align: usize) -> *mut u8;
-    #[cfg_attr(not(bootstrap), rustc_deallocator)]
+    #[rustc_deallocator]
     #[rustc_allocator_nounwind]
     fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
-    #[cfg_attr(not(bootstrap), rustc_reallocator)]
+    #[rustc_reallocator]
     #[rustc_allocator_nounwind]
     fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8;
-    #[cfg_attr(not(bootstrap), rustc_allocator_zeroed)]
+    #[rustc_allocator_zeroed]
     #[rustc_allocator_nounwind]
     fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
 }
index 887246c600144801dc4d7e7d48229e800cc7a5aa..6756eecd0e0f8ca6bc446b899595a56de3ef6b1a 100644 (file)
@@ -74,7 +74,7 @@
 ///         {
 ///             return null_mut();
 ///         };
-///         (self.arena.get() as *mut u8).add(allocated)
+///         self.arena.get().cast::<u8>().add(allocated)
 ///     }
 ///     unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
 /// }
index 372141e0933f560600fdcbe7ac79ec8400170513..9d3e9abf557792c9c490f969e7da5d798af8dce6 100644 (file)
@@ -119,6 +119,10 @@ pub trait Write {
     ///
     /// This function will return an instance of [`Error`] on error.
     ///
+    /// The purpose of std::fmt::Error is to abort the formatting operation when the underlying
+    /// destination encounters some error preventing it from accepting more text; it should
+    /// generally be propagated rather than handled, at least when implementing formatting traits.
+    ///
     /// # Examples
     ///
     /// ```
@@ -2562,7 +2566,7 @@ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
 
 macro_rules! maybe_tuple_doc {
     ($a:ident @ #[$meta:meta] $item:item) => {
-        #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+        #[doc(fake_variadic)]
         #[doc = "This trait is implemented for tuples up to twelve items long."]
         #[$meta]
         $item
index 5974562aced4ebee6c2742545792598c60d2f0cb..aa13435e6808d0de31fa8c0d8bc387c245296266 100644 (file)
@@ -900,7 +900,7 @@ fn hash<S: Hasher>(&self, state: &mut S) {
 
     macro_rules! maybe_tuple_doc {
         ($a:ident @ #[$meta:meta] $item:item) => {
-            #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+            #[doc(fake_variadic)]
             #[doc = "This trait is implemented for tuples up to twelve items long."]
             #[$meta]
             $item
index 2d44feb15f873b7ae34c2a4be9e7655c9dbecce5..15467e0191dbf432bb8f6439c145ec412b7c196b 100644 (file)
@@ -63,7 +63,7 @@
 use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
 
 #[stable(feature = "drop_in_place", since = "1.8.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
 #[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")]
 #[inline]
 pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
@@ -71,214 +71,6 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     unsafe { crate::ptr::drop_in_place(to_drop) }
 }
 
-// These have been renamed.
-#[cfg(bootstrap)]
-extern "rust-intrinsic" {
-    pub fn atomic_cxchg<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchg_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchg_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchg_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchg_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchg_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchg_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchg_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchg_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchgweak<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchgweak_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchgweak_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchgweak_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchgweak_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchgweak_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchgweak_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchgweak_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_cxchgweak_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    pub fn atomic_load<T: Copy>(src: *const T) -> T;
-    pub fn atomic_load_acq<T: Copy>(src: *const T) -> T;
-    pub fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
-    pub fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
-    pub fn atomic_store<T: Copy>(dst: *mut T, val: T);
-    pub fn atomic_store_rel<T: Copy>(dst: *mut T, val: T);
-    pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
-    pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
-    pub fn atomic_xchg<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xchg_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xchg_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xadd<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xadd_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xadd_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xsub<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xsub_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xsub_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_and<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_and_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_and_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_nand<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_nand_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_nand_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_or<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_or_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_or_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xor<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xor_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xor_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_max<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_max_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_max_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_min<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_min_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_min_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umin<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umin_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umin_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umax<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umax_acq<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umax_rel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
-    pub fn atomic_fence();
-    pub fn atomic_fence_acq();
-    pub fn atomic_fence_rel();
-    pub fn atomic_fence_acqrel();
-    pub fn atomic_singlethreadfence();
-    pub fn atomic_singlethreadfence_acq();
-    pub fn atomic_singlethreadfence_rel();
-    pub fn atomic_singlethreadfence_acqrel();
-}
-
-// These have been renamed.
-#[cfg(bootstrap)]
-mod atomics {
-    pub use super::atomic_cxchg as atomic_cxchg_seqcst_seqcst;
-    pub use super::atomic_cxchg_acq as atomic_cxchg_acquire_acquire;
-    pub use super::atomic_cxchg_acq_failrelaxed as atomic_cxchg_acquire_relaxed;
-    pub use super::atomic_cxchg_acqrel as atomic_cxchg_acqrel_acquire;
-    pub use super::atomic_cxchg_acqrel_failrelaxed as atomic_cxchg_acqrel_relaxed;
-    pub use super::atomic_cxchg_failacq as atomic_cxchg_seqcst_acquire;
-    pub use super::atomic_cxchg_failrelaxed as atomic_cxchg_seqcst_relaxed;
-    pub use super::atomic_cxchg_rel as atomic_cxchg_release_relaxed;
-    pub use super::atomic_cxchg_relaxed as atomic_cxchg_relaxed_relaxed;
-
-    pub use super::atomic_cxchgweak as atomic_cxchgweak_seqcst_seqcst;
-    pub use super::atomic_cxchgweak_acq as atomic_cxchgweak_acquire_acquire;
-    pub use super::atomic_cxchgweak_acq_failrelaxed as atomic_cxchgweak_acquire_relaxed;
-    pub use super::atomic_cxchgweak_acqrel as atomic_cxchgweak_acqrel_acquire;
-    pub use super::atomic_cxchgweak_acqrel_failrelaxed as atomic_cxchgweak_acqrel_relaxed;
-    pub use super::atomic_cxchgweak_failacq as atomic_cxchgweak_seqcst_acquire;
-    pub use super::atomic_cxchgweak_failrelaxed as atomic_cxchgweak_seqcst_relaxed;
-    pub use super::atomic_cxchgweak_rel as atomic_cxchgweak_release_relaxed;
-    pub use super::atomic_cxchgweak_relaxed as atomic_cxchgweak_relaxed_relaxed;
-
-    pub use super::atomic_load as atomic_load_seqcst;
-    pub use super::atomic_load_acq as atomic_load_acquire;
-    pub use super::atomic_load_relaxed;
-    pub use super::atomic_load_unordered;
-
-    pub use super::atomic_store as atomic_store_seqcst;
-    pub use super::atomic_store_rel as atomic_store_release;
-    pub use super::atomic_store_relaxed;
-    pub use super::atomic_store_unordered;
-
-    pub use super::atomic_xchg as atomic_xchg_seqcst;
-    pub use super::atomic_xchg_acq as atomic_xchg_acquire;
-    pub use super::atomic_xchg_acqrel;
-    pub use super::atomic_xchg_rel as atomic_xchg_release;
-    pub use super::atomic_xchg_relaxed;
-
-    pub use super::atomic_xadd as atomic_xadd_seqcst;
-    pub use super::atomic_xadd_acq as atomic_xadd_acquire;
-    pub use super::atomic_xadd_acqrel;
-    pub use super::atomic_xadd_rel as atomic_xadd_release;
-    pub use super::atomic_xadd_relaxed;
-
-    pub use super::atomic_xsub as atomic_xsub_seqcst;
-    pub use super::atomic_xsub_acq as atomic_xsub_acquire;
-    pub use super::atomic_xsub_acqrel;
-    pub use super::atomic_xsub_rel as atomic_xsub_release;
-    pub use super::atomic_xsub_relaxed;
-
-    pub use super::atomic_and as atomic_and_seqcst;
-    pub use super::atomic_and_acq as atomic_and_acquire;
-    pub use super::atomic_and_acqrel;
-    pub use super::atomic_and_rel as atomic_and_release;
-    pub use super::atomic_and_relaxed;
-
-    pub use super::atomic_nand as atomic_nand_seqcst;
-    pub use super::atomic_nand_acq as atomic_nand_acquire;
-    pub use super::atomic_nand_acqrel;
-    pub use super::atomic_nand_rel as atomic_nand_release;
-    pub use super::atomic_nand_relaxed;
-
-    pub use super::atomic_or as atomic_or_seqcst;
-    pub use super::atomic_or_acq as atomic_or_acquire;
-    pub use super::atomic_or_acqrel;
-    pub use super::atomic_or_rel as atomic_or_release;
-    pub use super::atomic_or_relaxed;
-
-    pub use super::atomic_xor as atomic_xor_seqcst;
-    pub use super::atomic_xor_acq as atomic_xor_acquire;
-    pub use super::atomic_xor_acqrel;
-    pub use super::atomic_xor_rel as atomic_xor_release;
-    pub use super::atomic_xor_relaxed;
-
-    pub use super::atomic_max as atomic_max_seqcst;
-    pub use super::atomic_max_acq as atomic_max_acquire;
-    pub use super::atomic_max_acqrel;
-    pub use super::atomic_max_rel as atomic_max_release;
-    pub use super::atomic_max_relaxed;
-
-    pub use super::atomic_min as atomic_min_seqcst;
-    pub use super::atomic_min_acq as atomic_min_acquire;
-    pub use super::atomic_min_acqrel;
-    pub use super::atomic_min_rel as atomic_min_release;
-    pub use super::atomic_min_relaxed;
-
-    pub use super::atomic_umin as atomic_umin_seqcst;
-    pub use super::atomic_umin_acq as atomic_umin_acquire;
-    pub use super::atomic_umin_acqrel;
-    pub use super::atomic_umin_rel as atomic_umin_release;
-    pub use super::atomic_umin_relaxed;
-
-    pub use super::atomic_umax as atomic_umax_seqcst;
-    pub use super::atomic_umax_acq as atomic_umax_acquire;
-    pub use super::atomic_umax_acqrel;
-    pub use super::atomic_umax_rel as atomic_umax_release;
-    pub use super::atomic_umax_relaxed;
-
-    pub use super::atomic_fence as atomic_fence_seqcst;
-    pub use super::atomic_fence_acq as atomic_fence_acquire;
-    pub use super::atomic_fence_acqrel;
-    pub use super::atomic_fence_rel as atomic_fence_release;
-
-    pub use super::atomic_singlethreadfence as atomic_singlethreadfence_seqcst;
-    pub use super::atomic_singlethreadfence_acq as atomic_singlethreadfence_acquire;
-    pub use super::atomic_singlethreadfence_acqrel;
-    pub use super::atomic_singlethreadfence_rel as atomic_singlethreadfence_release;
-}
-
-#[cfg(bootstrap)]
-pub use atomics::*;
-
-#[cfg(not(bootstrap))]
 extern "rust-intrinsic" {
     // N.B., these intrinsics take raw pointers because they mutate aliased
     // memory, which is not valid for either `&` or `&mut`.
@@ -951,7 +743,6 @@ mod atomics {
 //
 // These are the aliases for the old names.
 // To be removed when stdarch and panic_unwind have been updated.
-#[cfg(not(bootstrap))]
 mod atomics {
     pub use super::atomic_cxchg_acqrel_acquire as atomic_cxchg_acqrel;
     pub use super::atomic_cxchg_acqrel_relaxed as atomic_cxchg_acqrel_failrelaxed;
@@ -965,7 +756,6 @@ mod atomics {
     pub use super::atomic_store_seqcst as atomic_store;
 }
 
-#[cfg(not(bootstrap))]
 pub use atomics::*;
 
 extern "rust-intrinsic" {
@@ -1463,7 +1253,7 @@ mod atomics {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+    #[rustc_allowed_through_unstable_modules]
     #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
     #[rustc_diagnostic_item = "transmute"]
     pub fn transmute<T, U>(e: T) -> U;
@@ -2300,12 +2090,10 @@ mod atomics {
 
     /// `ptr` must point to a vtable.
     /// The intrinsic will return the size stored in that vtable.
-    #[cfg(not(bootstrap))]
     pub fn vtable_size(ptr: *const ()) -> usize;
 
     /// `ptr` must point to a vtable.
     /// The intrinsic will return the alignment stored in that vtable.
-    #[cfg(not(bootstrap))]
     pub fn vtable_align(ptr: *const ()) -> usize;
 }
 
@@ -2452,7 +2240,7 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
 /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
 #[doc(alias = "memcpy")]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
 #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
 #[inline]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -2539,7 +2327,7 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
 /// ```
 #[doc(alias = "memmove")]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
 #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
 #[inline]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -2607,7 +2395,7 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
 /// ```
 #[doc(alias = "memset")]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
 #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
 #[inline]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs
new file mode 100644 (file)
index 0000000..9b479a9
--- /dev/null
@@ -0,0 +1,182 @@
+use crate::array;
+use crate::iter::{ByRefSized, FusedIterator, Iterator};
+use crate::ops::{ControlFlow, NeverShortCircuit, Try};
+
+/// An iterator over `N` elements of the iterator at a time.
+///
+/// The chunks do not overlap. If `N` does not divide the length of the
+/// iterator, then the last up to `N-1` elements will be omitted.
+///
+/// This `struct` is created by the [`array_chunks`][Iterator::array_chunks]
+/// method on [`Iterator`]. See its documentation for more.
+#[derive(Debug, Clone)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+pub struct ArrayChunks<I: Iterator, const N: usize> {
+    iter: I,
+    remainder: Option<array::IntoIter<I::Item, N>>,
+}
+
+impl<I, const N: usize> ArrayChunks<I, N>
+where
+    I: Iterator,
+{
+    #[track_caller]
+    pub(in crate::iter) fn new(iter: I) -> Self {
+        assert!(N != 0, "chunk size must be non-zero");
+        Self { iter, remainder: None }
+    }
+
+    /// Returns an iterator over the remaining elements of the original iterator
+    /// that are not going to be returned by this iterator. The returned
+    /// iterator will yield at most `N-1` elements.
+    #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+    #[inline]
+    pub fn into_remainder(self) -> Option<array::IntoIter<I::Item, N>> {
+        self.remainder
+    }
+}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> Iterator for ArrayChunks<I, N>
+where
+    I: Iterator,
+{
+    type Item = [I::Item; N];
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        self.try_for_each(ControlFlow::Break).break_value()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (lower, upper) = self.iter.size_hint();
+
+        (lower / N, upper.map(|n| n / N))
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.iter.count() / N
+    }
+
+    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
+    where
+        Self: Sized,
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        let mut acc = init;
+        loop {
+            match self.iter.next_chunk() {
+                Ok(chunk) => acc = f(acc, chunk)?,
+                Err(remainder) => {
+                    // Make sure to not override `self.remainder` with an empty array
+                    // when `next` is called after `ArrayChunks` exhaustion.
+                    self.remainder.get_or_insert(remainder);
+
+                    break try { acc };
+                }
+            }
+        }
+    }
+
+    fn fold<B, F>(mut self, init: B, f: F) -> B
+    where
+        Self: Sized,
+        F: FnMut(B, Self::Item) -> B,
+    {
+        self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0
+    }
+}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> DoubleEndedIterator for ArrayChunks<I, N>
+where
+    I: DoubleEndedIterator + ExactSizeIterator,
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.try_rfold((), |(), x| ControlFlow::Break(x)).break_value()
+    }
+
+    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
+    where
+        Self: Sized,
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        // We are iterating from the back we need to first handle the remainder.
+        self.next_back_remainder();
+
+        let mut acc = init;
+        let mut iter = ByRefSized(&mut self.iter).rev();
+
+        // NB remainder is handled by `next_back_remainder`, so
+        // `next_chunk` can't return `Err` with non-empty remainder
+        // (assuming correct `I as ExactSizeIterator` impl).
+        while let Ok(mut chunk) = iter.next_chunk() {
+            // FIXME: do not do double reverse
+            //        (we could instead add `next_chunk_back` for example)
+            chunk.reverse();
+            acc = f(acc, chunk)?
+        }
+
+        try { acc }
+    }
+
+    fn rfold<B, F>(mut self, init: B, f: F) -> B
+    where
+        Self: Sized,
+        F: FnMut(B, Self::Item) -> B,
+    {
+        self.try_rfold(init, NeverShortCircuit::wrap_mut_2(f)).0
+    }
+}
+
+impl<I, const N: usize> ArrayChunks<I, N>
+where
+    I: DoubleEndedIterator + ExactSizeIterator,
+{
+    /// Updates `self.remainder` such that `self.iter.len` is divisible by `N`.
+    fn next_back_remainder(&mut self) {
+        // Make sure to not override `self.remainder` with an empty array
+        // when `next_back` is called after `ArrayChunks` exhaustion.
+        if self.remainder.is_some() {
+            return;
+        }
+
+        // We use the `ExactSizeIterator` implementation of the underlying
+        // iterator to know how many remaining elements there are.
+        let rem = self.iter.len() % N;
+
+        // Take the last `rem` elements out of `self.iter`.
+        let mut remainder =
+            // SAFETY: `unwrap_err` always succeeds because x % N < N for all x.
+            unsafe { self.iter.by_ref().rev().take(rem).next_chunk().unwrap_err_unchecked() };
+
+        // We used `.rev()` above, so we need to re-reverse the reminder
+        remainder.as_mut_slice().reverse();
+        self.remainder = Some(remainder);
+    }
+}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> FusedIterator for ArrayChunks<I, N> where I: FusedIterator {}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> ExactSizeIterator for ArrayChunks<I, N>
+where
+    I: ExactSizeIterator,
+{
+    #[inline]
+    fn len(&self) -> usize {
+        self.iter.len() / N
+    }
+
+    #[inline]
+    fn is_empty(&self) -> bool {
+        self.iter.len() < N
+    }
+}
index 916a26e242466ee5675b2e8591781c3a23ee327e..bf4fabad32a373e333c4f06443a3df6f0d5f0c1c 100644 (file)
@@ -1,6 +1,7 @@
 use crate::iter::{InPlaceIterable, Iterator};
 use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, NeverShortCircuit, Residual, Try};
 
+mod array_chunks;
 mod by_ref_sized;
 mod chain;
 mod cloned;
@@ -32,6 +33,9 @@
     scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip,
 };
 
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+pub use self::array_chunks::ArrayChunks;
+
 #[unstable(feature = "std_internals", issue = "none")]
 pub use self::by_ref_sized::ByRefSized;
 
index 2c283100f071fca4c0966702053b886ea1efb485..dbf0ae9eca3eb7492b7afbc9d71dbf87ec2b0f49 100644 (file)
@@ -33,21 +33,32 @@ impl<I> Iterator for Skip<I>
     #[inline]
     fn next(&mut self) -> Option<I::Item> {
         if unlikely(self.n > 0) {
-            self.iter.nth(crate::mem::take(&mut self.n) - 1)?;
+            self.iter.nth(crate::mem::take(&mut self.n))
+        } else {
+            self.iter.next()
         }
-        self.iter.next()
     }
 
     #[inline]
     fn nth(&mut self, n: usize) -> Option<I::Item> {
-        // Can't just add n + self.n due to overflow.
         if self.n > 0 {
-            let to_skip = self.n;
-            self.n = 0;
-            // nth(n) skips n+1
-            self.iter.nth(to_skip - 1)?;
+            let skip: usize = crate::mem::take(&mut self.n);
+            // Checked add to handle overflow case.
+            let n = match skip.checked_add(n) {
+                Some(nth) => nth,
+                None => {
+                    // In case of overflow, load skip value, before loading `n`.
+                    // Because the amount of elements to iterate is beyond `usize::MAX`, this
+                    // is split into two `nth` calls where the `skip` `nth` call is discarded.
+                    self.iter.nth(skip - 1)?;
+                    n
+                }
+            };
+            // Load nth element including skip.
+            self.iter.nth(n)
+        } else {
+            self.iter.nth(n)
         }
-        self.iter.nth(n)
     }
 
     #[inline]
index d5c6aed5b6c8ab48ee5368a2da0acefa79e3e035..9514466bd0c050d9969a64a6d161fdd9310fd498 100644 (file)
 
 #[stable(feature = "iter_zip", since = "1.59.0")]
 pub use self::adapters::zip;
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+pub use self::adapters::ArrayChunks;
 #[unstable(feature = "std_internals", issue = "none")]
 pub use self::adapters::ByRefSized;
 #[stable(feature = "iter_cloned", since = "1.1.0")]
index 275412b57b55f00f8df05253bf17efeda20e02f5..b2d08f4b0f67bf456692e0c34fdf954ef357c1c0 100644 (file)
@@ -5,7 +5,7 @@
 use super::super::try_process;
 use super::super::ByRefSized;
 use super::super::TrustedRandomAccessNoCoerce;
-use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
+use super::super::{ArrayChunks, Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
 use super::super::{FlatMap, Flatten};
 use super::super::{FromIterator, Intersperse, IntersperseWith, Product, Sum, Zip};
 use super::super::{
@@ -3316,6 +3316,49 @@ fn cycle(self) -> Cycle<Self>
         Cycle::new(self)
     }
 
+    /// Returns an iterator over `N` elements of the iterator at a time.
+    ///
+    /// The chunks do not overlap. If `N` does not divide the length of the
+    /// iterator, then the last up to `N-1` elements will be omitted and can be
+    /// retrieved from the [`.into_remainder()`][ArrayChunks::into_remainder]
+    /// function of the iterator.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `N` is 0.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(iter_array_chunks)]
+    ///
+    /// let mut iter = "lorem".chars().array_chunks();
+    /// assert_eq!(iter.next(), Some(['l', 'o']));
+    /// assert_eq!(iter.next(), Some(['r', 'e']));
+    /// assert_eq!(iter.next(), None);
+    /// assert_eq!(iter.into_remainder().unwrap().as_slice(), &['m']);
+    /// ```
+    ///
+    /// ```
+    /// #![feature(iter_array_chunks)]
+    ///
+    /// let data = [1, 1, 2, -2, 6, 0, 3, 1];
+    /// //          ^-----^  ^------^
+    /// for [x, y, z] in data.iter().array_chunks() {
+    ///     assert_eq!(x + y + z, 4);
+    /// }
+    /// ```
+    #[track_caller]
+    #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+    fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
+    where
+        Self: Sized,
+    {
+        ArrayChunks::new(self)
+    }
+
     /// Sums the elements of an iterator.
     ///
     /// Takes each element, adds them together, and returns the result.
index b59a5b89d839fb76bce65e51c70a3f4123a3fe8f..b4fabedad7829e76e475b9abfd841318baa947f8 100644 (file)
@@ -4,7 +4,7 @@
 /// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`,
 /// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
 #[unstable(feature = "transmutability", issue = "99571")]
-#[cfg_attr(not(bootstrap), lang = "transmute_trait")]
+#[lang = "transmute_trait"]
 #[rustc_on_unimplemented(
     message = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`.",
     label = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`."
index b8e5461640c0581ea4a242fb7724aea2140c01da..1c14b9341cac8e435a0cd8746f41e712d3ac8893 100644 (file)
@@ -996,7 +996,7 @@ impl<T> (T,) {}
 // Fake impl that's only really used for docs.
 #[cfg(doc)]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
 /// This trait is implemented on arbitrary-length tuples.
 impl<T: Clone> Clone for (T,) {
     fn clone(&self) -> Self {
@@ -1007,7 +1007,7 @@ fn clone(&self) -> Self {
 // Fake impl that's only really used for docs.
 #[cfg(doc)]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
 /// This trait is implemented on arbitrary-length tuples.
 impl<T: Copy> Copy for (T,) {
     // empty
@@ -1484,13 +1484,12 @@ mod prim_fn {}
 // Required to make auto trait impls render.
 // See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
 #[doc(hidden)]
-#[cfg(not(bootstrap))]
 impl<Ret, T> fn(T) -> Ret {}
 
 // Fake impl that's only really used for docs.
 #[cfg(doc)]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
 /// This trait is implemented on function pointers with any number of arguments.
 impl<Ret, T> Clone for fn(T) -> Ret {
     fn clone(&self) -> Self {
@@ -1501,7 +1500,7 @@ fn clone(&self) -> Self {
 // Fake impl that's only really used for docs.
 #[cfg(doc)]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
 /// This trait is implemented on function pointers with any number of arguments.
 impl<Ret, T> Copy for fn(T) -> Ret {
     // empty
index c0f609a01b5c85f8b794262fce70d3cd2ffa375a..c25b159c533a19ae0f951745301db71fbc18ac77 100644 (file)
@@ -1267,20 +1267,21 @@ pub unsafe fn read_volatile(self) -> T
     /// Accessing adjacent `u8` as `u16`
     ///
     /// ```
-    /// # fn foo(n: usize) {
-    /// # use std::mem::align_of;
+    /// use std::mem::align_of;
+    ///
     /// # unsafe {
-    /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
-    /// let ptr = x.as_ptr().add(n) as *const u8;
+    /// let x = [5_u8, 6, 7, 8, 9];
+    /// let ptr = x.as_ptr();
     /// let offset = ptr.align_offset(align_of::<u16>());
-    /// if offset < x.len() - n - 1 {
-    ///     let u16_ptr = ptr.add(offset) as *const u16;
-    ///     assert_ne!(*u16_ptr, 500);
+    ///
+    /// if offset < x.len() - 1 {
+    ///     let u16_ptr = ptr.add(offset).cast::<u16>();
+    ///     assert!(*u16_ptr == u16::from_ne_bytes([5, 6]) || *u16_ptr == u16::from_ne_bytes([6, 7]));
     /// } else {
     ///     // while the pointer can be aligned via `offset`, it would point
     ///     // outside the allocation
     /// }
-    /// # } }
+    /// # }
     /// ```
     #[stable(feature = "align_offset", since = "1.36.0")]
     #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
index cd5edee0460ad4a19b41f99ec55d56d31fa712fc..8865c834c88d6f517ad8512743fce4bfbf2bcce6 100644 (file)
@@ -180,7 +180,6 @@ pub struct DynMetadata<Dyn: ?Sized> {
     phantom: crate::marker::PhantomData<Dyn>,
 }
 
-#[cfg(not(bootstrap))]
 extern "C" {
     /// Opaque type for accessing vtables.
     ///
@@ -189,17 +188,6 @@ pub struct DynMetadata<Dyn: ?Sized> {
     type VTable;
 }
 
-/// The common prefix of all vtables. It is followed by function pointers for trait methods.
-///
-/// Private implementation detail of `DynMetadata::size_of` etc.
-#[repr(C)]
-#[cfg(bootstrap)]
-struct VTable {
-    drop_in_place: fn(*mut ()),
-    size_of: usize,
-    align_of: usize,
-}
-
 impl<Dyn: ?Sized> DynMetadata<Dyn> {
     /// Returns the size of the type associated with this vtable.
     #[inline]
@@ -207,9 +195,6 @@ pub fn size_of(self) -> usize {
         // Note that "size stored in vtable" is *not* the same as "result of size_of_val_raw".
         // Consider a reference like `&(i32, dyn Send)`: the vtable will only store the size of the
         // `Send` part!
-        #[cfg(bootstrap)]
-        return self.vtable_ptr.size_of;
-        #[cfg(not(bootstrap))]
         // SAFETY: DynMetadata always contains a valid vtable pointer
         return unsafe {
             crate::intrinsics::vtable_size(self.vtable_ptr as *const VTable as *const ())
@@ -219,9 +204,6 @@ pub fn size_of(self) -> usize {
     /// Returns the alignment of the type associated with this vtable.
     #[inline]
     pub fn align_of(self) -> usize {
-        #[cfg(bootstrap)]
-        return self.vtable_ptr.align_of;
-        #[cfg(not(bootstrap))]
         // SAFETY: DynMetadata always contains a valid vtable pointer
         return unsafe {
             crate::intrinsics::vtable_align(self.vtable_ptr as *const VTable as *const ())
index 40e28e636d8514394b088d4fb89c4763cdca9798..203531f66aa367e47ea00c1127124a27665b82ae 100644 (file)
@@ -603,6 +603,7 @@ pub const fn invalid_mut<T>(addr: usize) -> *mut T {
 #[must_use]
 #[inline]
 #[unstable(feature = "strict_provenance", issue = "95228")]
+#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub fn from_exposed_addr<T>(addr: usize) -> *const T
 where
     T: Sized,
@@ -639,6 +640,7 @@ pub fn from_exposed_addr<T>(addr: usize) -> *const T
 #[must_use]
 #[inline]
 #[unstable(feature = "strict_provenance", issue = "95228")]
+#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub fn from_exposed_addr_mut<T>(addr: usize) -> *mut T
 where
     T: Sized,
@@ -1834,7 +1836,7 @@ macro_rules! maybe_fnptr_doc {
         $item
     };
     ($a:ident @ #[$meta:meta] $item:item) => {
-        #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+        #[doc(fake_variadic)]
         #[doc = "This trait is implemented for function pointers with up to twelve arguments."]
         #[$meta]
         $item
index 7059d0008c4c4d1a3de189b5c94154c5c6def2e3..fff06b458c7c132a43580491672863369bb4b5f5 100644 (file)
@@ -1545,20 +1545,23 @@ pub unsafe fn replace(self, src: T) -> T
     /// Accessing adjacent `u8` as `u16`
     ///
     /// ```
-    /// # fn foo(n: usize) {
-    /// # use std::mem::align_of;
+    /// use std::mem::align_of;
+    ///
     /// # unsafe {
-    /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
-    /// let ptr = x.as_ptr().add(n) as *const u8;
+    /// let mut x = [5_u8, 6, 7, 8, 9];
+    /// let ptr = x.as_mut_ptr();
     /// let offset = ptr.align_offset(align_of::<u16>());
-    /// if offset < x.len() - n - 1 {
-    ///     let u16_ptr = ptr.add(offset) as *const u16;
-    ///     assert_ne!(*u16_ptr, 500);
+    ///
+    /// if offset < x.len() - 1 {
+    ///     let u16_ptr = ptr.add(offset).cast::<u16>();
+    ///     *u16_ptr = 0;
+    ///
+    ///     assert!(x == [0, 0, 7, 8, 9] || x == [5, 0, 0, 8, 9]);
     /// } else {
     ///     // while the pointer can be aligned via `offset`, it would point
     ///     // outside the allocation
     /// }
-    /// # } }
+    /// # }
     /// ```
     #[stable(feature = "align_offset", since = "1.36.0")]
     #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
index f1e659309674c6cda48ca011f2ecb0ae1b921ade..f43b780ec9a900a18f202d2e8e3cf55a574894d1 100644 (file)
@@ -92,7 +92,7 @@ pub(super) fn new(slice: &'a [T]) -> Self {
             assume(!ptr.is_null());
 
             let end = if mem::size_of::<T>() == 0 {
-                (ptr as *const u8).wrapping_add(slice.len()) as *const T
+                ptr.wrapping_byte_add(slice.len())
             } else {
                 ptr.add(slice.len())
             };
@@ -228,7 +228,7 @@ pub(super) fn new(slice: &'a mut [T]) -> Self {
             assume(!ptr.is_null());
 
             let end = if mem::size_of::<T>() == 0 {
-                (ptr as *mut u8).wrapping_add(slice.len()) as *mut T
+                ptr.wrapping_byte_add(slice.len())
             } else {
                 ptr.add(slice.len())
             };
index e6ca6ef82673e1cc515b3445bd8f73de5fc11b6e..e79d47c9f98cdf0c234c3dafed3359104043ede5 100644 (file)
@@ -4101,7 +4101,6 @@ pub fn flatten_mut(&mut self) -> &mut [T] {
     }
 }
 
-#[cfg(not(bootstrap))]
 #[cfg(not(test))]
 impl [f32] {
     /// Sorts the slice of floats.
@@ -4131,7 +4130,6 @@ pub fn sort_floats(&mut self) {
     }
 }
 
-#[cfg(not(bootstrap))]
 #[cfg(not(test))]
 impl [f64] {
     /// Sorts the slice of floats.
index 5e2e0c4d8cc1b24cc33b2f91d48d4ea50fe92415..40ca9abd6bdc9a5ed9b059e47d709f1d63f5ea2c 100644 (file)
@@ -1584,16 +1584,8 @@ pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {
     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
-        #[cfg(not(bootstrap))]
         // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_add(self.p.get(), core::ptr::invalid_mut(val), order).cast()
-        }
-        #[cfg(bootstrap)]
-        // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_add(self.p.get().cast::<usize>(), val, order) as *mut T
-        }
+        unsafe { atomic_add(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
     }
 
     /// Offsets the pointer's address by subtracting `val` *bytes*, returning the
@@ -1628,16 +1620,8 @@ pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
-        #[cfg(not(bootstrap))]
         // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_sub(self.p.get(), core::ptr::invalid_mut(val), order).cast()
-        }
-        #[cfg(bootstrap)]
-        // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_sub(self.p.get().cast::<usize>(), val, order) as *mut T
-        }
+        unsafe { atomic_sub(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
     }
 
     /// Performs a bitwise "or" operation on the address of the current pointer,
@@ -1687,16 +1671,8 @@ pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
-        #[cfg(not(bootstrap))]
-        // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_or(self.p.get(), core::ptr::invalid_mut(val), order).cast()
-        }
-        #[cfg(bootstrap)]
         // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_or(self.p.get().cast::<usize>(), val, order) as *mut T
-        }
+        unsafe { atomic_or(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
     }
 
     /// Performs a bitwise "and" operation on the address of the current
@@ -1745,16 +1721,8 @@ pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
-        #[cfg(not(bootstrap))]
-        // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_and(self.p.get(), core::ptr::invalid_mut(val), order).cast()
-        }
-        #[cfg(bootstrap)]
         // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_and(self.p.get().cast::<usize>(), val, order) as *mut T
-        }
+        unsafe { atomic_and(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
     }
 
     /// Performs a bitwise "xor" operation on the address of the current
@@ -1801,16 +1769,8 @@ pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
-        #[cfg(not(bootstrap))]
-        // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast()
-        }
-        #[cfg(bootstrap)]
         // SAFETY: data races are prevented by atomic intrinsics.
-        unsafe {
-            atomic_xor(self.p.get().cast::<usize>(), val, order) as *mut T
-        }
+        unsafe { atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
     }
 }
 
@@ -3073,30 +3033,22 @@ unsafe fn atomic_compare_exchange<T: Copy>(
     let (val, ok) = unsafe {
         match (success, failure) {
             (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
             (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),
             (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
             (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
             (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),
             (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),
-            #[cfg(not(bootstrap))]
             (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
             (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),
             (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),
             (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),
             (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
             (_, Release) => panic!("there is no such thing as a release failure ordering"),
-            #[cfg(bootstrap)]
-            _ => panic!("a failure ordering can't be stronger than a success ordering"),
         }
     };
     if ok { Ok(val) } else { Err(val) }
@@ -3116,30 +3068,22 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
     let (val, ok) = unsafe {
         match (success, failure) {
             (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),
             (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new),
             (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),
             (Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),
-            #[cfg(not(bootstrap))]
             (Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),
             (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new),
             (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new),
-            #[cfg(not(bootstrap))]
             (AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),
             (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new),
             (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new),
             (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new),
             (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
             (_, Release) => panic!("there is no such thing as a release failure ordering"),
-            #[cfg(bootstrap)]
-            _ => panic!("a failure ordering can't be stronger than a success ordering"),
         }
     };
     if ok { Ok(val) } else { Err(val) }
index d189e6400f1e87951c5ca8eb9166f192af9be3b1..aa8a2425bf41624c86a5c597f76b62601d0be1d5 100644 (file)
@@ -107,7 +107,7 @@ fn default() -> ($($T,)+) {
 // Otherwise, it hides the docs entirely.
 macro_rules! maybe_tuple_doc {
     ($a:ident @ #[$meta:meta] $item:item) => {
-        #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+        #[doc(fake_variadic)]
         #[doc = "This trait is implemented for tuples up to twelve items long."]
         #[$meta]
         $item
index 152fed803ecdb751167ccbb31a3155958920523a..d874f08317f6142c27d86d010b39569d42b5fab5 100644 (file)
@@ -3,7 +3,7 @@
 
 const fn unaligned_ptr() -> *const u16 {
     // Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16
-    unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 }
+    unsafe { DATA.as_ptr().byte_add(1) }
 }
 
 #[test]
@@ -67,7 +67,7 @@ const fn write_aligned() -> i32 {
     const fn write_unaligned() -> [u16; 2] {
         let mut two_aligned = [0u16; 2];
         unsafe {
-            let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
+            let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1);
             ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45]));
         }
         two_aligned
@@ -91,7 +91,7 @@ const fn aligned() -> i32 {
     const fn write_unaligned() -> [u16; 2] {
         let mut two_aligned = [0u16; 2];
         unsafe {
-            let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
+            let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1);
             unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45]));
         }
         two_aligned
diff --git a/library/core/tests/iter/adapters/array_chunks.rs b/library/core/tests/iter/adapters/array_chunks.rs
new file mode 100644 (file)
index 0000000..4e9d89e
--- /dev/null
@@ -0,0 +1,179 @@
+use core::cell::Cell;
+use core::iter::{self, Iterator};
+
+use super::*;
+
+#[test]
+fn test_iterator_array_chunks_infer() {
+    let xs = [1, 1, 2, -2, 6, 0, 3, 1];
+    for [a, b, c] in xs.iter().copied().array_chunks() {
+        assert_eq!(a + b + c, 4);
+    }
+}
+
+#[test]
+fn test_iterator_array_chunks_clone_and_drop() {
+    let count = Cell::new(0);
+    let mut it = (0..5).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+    assert_eq!(it.by_ref().count(), 1);
+    assert_eq!(count.get(), 3);
+    let mut it2 = it.clone();
+    assert_eq!(count.get(), 3);
+    assert_eq!(it.into_remainder().unwrap().len(), 2);
+    assert_eq!(count.get(), 5);
+    assert!(it2.next().is_none());
+    assert_eq!(it2.into_remainder().unwrap().len(), 2);
+    assert_eq!(count.get(), 7);
+}
+
+#[test]
+fn test_iterator_array_chunks_remainder() {
+    let mut it = (0..11).array_chunks::<4>();
+    assert_eq!(it.next(), Some([0, 1, 2, 3]));
+    assert_eq!(it.next(), Some([4, 5, 6, 7]));
+    assert_eq!(it.next(), None);
+    assert_eq!(it.into_remainder().unwrap().as_slice(), &[8, 9, 10]);
+}
+
+#[test]
+fn test_iterator_array_chunks_size_hint() {
+    let it = (0..6).array_chunks::<1>();
+    assert_eq!(it.size_hint(), (6, Some(6)));
+
+    let it = (0..6).array_chunks::<3>();
+    assert_eq!(it.size_hint(), (2, Some(2)));
+
+    let it = (0..6).array_chunks::<5>();
+    assert_eq!(it.size_hint(), (1, Some(1)));
+
+    let it = (0..6).array_chunks::<7>();
+    assert_eq!(it.size_hint(), (0, Some(0)));
+
+    let it = (1..).array_chunks::<2>();
+    assert_eq!(it.size_hint(), (usize::MAX / 2, None));
+
+    let it = (1..).filter(|x| x % 2 != 0).array_chunks::<2>();
+    assert_eq!(it.size_hint(), (0, None));
+}
+
+#[test]
+fn test_iterator_array_chunks_count() {
+    let it = (0..6).array_chunks::<1>();
+    assert_eq!(it.count(), 6);
+
+    let it = (0..6).array_chunks::<3>();
+    assert_eq!(it.count(), 2);
+
+    let it = (0..6).array_chunks::<5>();
+    assert_eq!(it.count(), 1);
+
+    let it = (0..6).array_chunks::<7>();
+    assert_eq!(it.count(), 0);
+
+    let it = (0..6).filter(|x| x % 2 == 0).array_chunks::<2>();
+    assert_eq!(it.count(), 1);
+
+    let it = iter::empty::<i32>().array_chunks::<2>();
+    assert_eq!(it.count(), 0);
+
+    let it = [(); usize::MAX].iter().array_chunks::<2>();
+    assert_eq!(it.count(), usize::MAX / 2);
+}
+
+#[test]
+fn test_iterator_array_chunks_next_and_next_back() {
+    let mut it = (0..11).array_chunks::<3>();
+    assert_eq!(it.next(), Some([0, 1, 2]));
+    assert_eq!(it.next_back(), Some([6, 7, 8]));
+    assert_eq!(it.next(), Some([3, 4, 5]));
+    assert_eq!(it.next_back(), None);
+    assert_eq!(it.next(), None);
+    assert_eq!(it.next_back(), None);
+    assert_eq!(it.next(), None);
+    assert_eq!(it.into_remainder().unwrap().as_slice(), &[9, 10]);
+}
+
+#[test]
+fn test_iterator_array_chunks_rev_remainder() {
+    let mut it = (0..11).array_chunks::<4>();
+    {
+        let mut it = it.by_ref().rev();
+        assert_eq!(it.next(), Some([4, 5, 6, 7]));
+        assert_eq!(it.next(), Some([0, 1, 2, 3]));
+        assert_eq!(it.next(), None);
+        assert_eq!(it.next(), None);
+    }
+    assert_eq!(it.into_remainder().unwrap().as_slice(), &[8, 9, 10]);
+}
+
+#[test]
+fn test_iterator_array_chunks_try_fold() {
+    let count = Cell::new(0);
+    let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+    let result: Result<_, ()> = it.by_ref().try_fold(0, |acc, _item| Ok(acc + 1));
+    assert_eq!(result, Ok(3));
+    assert_eq!(count.get(), 9);
+    drop(it);
+    assert_eq!(count.get(), 10);
+
+    let count = Cell::new(0);
+    let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+    let result = it.by_ref().try_fold(0, |acc, _item| if acc < 2 { Ok(acc + 1) } else { Err(acc) });
+    assert_eq!(result, Err(2));
+    assert_eq!(count.get(), 9);
+    drop(it);
+    assert_eq!(count.get(), 9);
+}
+
+#[test]
+fn test_iterator_array_chunks_fold() {
+    let result = (1..11).array_chunks::<3>().fold(0, |acc, [a, b, c]| {
+        assert_eq!(acc + 1, a);
+        assert_eq!(acc + 2, b);
+        assert_eq!(acc + 3, c);
+        acc + 3
+    });
+    assert_eq!(result, 9);
+
+    let count = Cell::new(0);
+    let result =
+        (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().fold(0, |acc, _item| acc + 1);
+    assert_eq!(result, 3);
+    assert_eq!(count.get(), 10);
+}
+
+#[test]
+fn test_iterator_array_chunks_try_rfold() {
+    let count = Cell::new(0);
+    let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+    let result: Result<_, ()> = it.try_rfold(0, |acc, _item| Ok(acc + 1));
+    assert_eq!(result, Ok(3));
+    assert_eq!(count.get(), 9);
+    drop(it);
+    assert_eq!(count.get(), 10);
+
+    let count = Cell::new(0);
+    let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+    let result = it.try_rfold(0, |acc, _item| if acc < 2 { Ok(acc + 1) } else { Err(acc) });
+    assert_eq!(result, Err(2));
+    assert_eq!(count.get(), 9);
+    drop(it);
+    assert_eq!(count.get(), 10);
+}
+
+#[test]
+fn test_iterator_array_chunks_rfold() {
+    let result = (1..11).array_chunks::<3>().rfold(0, |acc, [a, b, c]| {
+        assert_eq!(10 - (acc + 1), c);
+        assert_eq!(10 - (acc + 2), b);
+        assert_eq!(10 - (acc + 3), a);
+        acc + 3
+    });
+    assert_eq!(result, 9);
+
+    let count = Cell::new(0);
+    let result =
+        (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().rfold(0, |acc, _item| acc + 1);
+    assert_eq!(result, 3);
+    assert_eq!(count.get(), 10);
+}
index 567d9fe49cade270aa3edda0b38e27ea6fef252a..96539c0c394e2e683720fc0d8b44aa5e688e40b0 100644 (file)
@@ -1,3 +1,4 @@
+mod array_chunks;
 mod chain;
 mod cloned;
 mod copied;
@@ -183,3 +184,25 @@ fn clone(&self) -> Self {
         ret
     }
 }
+
+#[derive(Debug, Clone)]
+struct CountDrop<'a> {
+    dropped: bool,
+    count: &'a Cell<usize>,
+}
+
+impl<'a> CountDrop<'a> {
+    pub fn new(count: &'a Cell<usize>) -> Self {
+        Self { dropped: false, count }
+    }
+}
+
+impl Drop for CountDrop<'_> {
+    fn drop(&mut self) {
+        if self.dropped {
+            panic!("double drop");
+        }
+        self.dropped = true;
+        self.count.set(self.count.get() + 1);
+    }
+}
index 65f235e86aab9a99d1389704630c38142065527b..754641834e803a6871ce5b4f13086f3e6ebdd2e4 100644 (file)
@@ -201,3 +201,34 @@ fn test_skip_non_fused() {
     // advance it further. `Unfuse` tests that this doesn't happen by panicking in that scenario.
     let _ = non_fused.skip(20).next();
 }
+
+#[test]
+fn test_skip_non_fused_nth_overflow() {
+    let non_fused = Unfuse::new(0..10);
+
+    // Ensures that calling skip and `nth` where the sum would overflow does not fail for non-fused
+    // iterators.
+    let _ = non_fused.skip(20).nth(usize::MAX);
+}
+
+#[test]
+fn test_skip_overflow_wrapping() {
+    // Test to ensure even on overflowing on `skip+nth` the correct amount of elements are yielded.
+    struct WrappingIterator(usize);
+
+    impl Iterator for WrappingIterator {
+        type Item = usize;
+
+        fn next(&mut self) -> core::option::Option<Self::Item> {
+            <Self as Iterator>::nth(self, 0)
+        }
+
+        fn nth(&mut self, nth: usize) -> core::option::Option<Self::Item> {
+            self.0 = self.0.wrapping_add(nth.wrapping_add(1));
+            Some(self.0)
+        }
+    }
+
+    let wrap = WrappingIterator(0);
+    assert_eq!(wrap.skip(20).nth(usize::MAX), Some(20));
+}
index db94368f6e0cc9ea09eda10aee9d98726b36d69d..09f1500f564cf6ce1fb9e3c54b85e2788c39c939 100644 (file)
@@ -14,6 +14,7 @@
 #![feature(const_maybe_uninit_assume_init_read)]
 #![feature(const_nonnull_new)]
 #![feature(const_num_from_num)]
+#![feature(const_pointer_byte_offsets)]
 #![feature(const_ptr_as_ref)]
 #![feature(const_ptr_read)]
 #![feature(const_ptr_write)]
@@ -61,6 +62,7 @@
 #![feature(slice_partition_dedup)]
 #![feature(int_log)]
 #![feature(iter_advance_by)]
+#![feature(iter_array_chunks)]
 #![feature(iter_collect_into)]
 #![feature(iter_partition_in_place)]
 #![feature(iter_intersperse)]
@@ -74,6 +76,7 @@
 #![feature(never_type)]
 #![feature(unwrap_infallible)]
 #![feature(result_into_ok_or_err)]
+#![feature(pointer_byte_offsets)]
 #![feature(portable_simd)]
 #![feature(ptr_metadata)]
 #![feature(once_cell)]
index ebe0ccbdc0b2d4211b047bef1ba739d640c8f067..475a1d9fd9920a5378ba88f5af1c097c7c02b57b 100644 (file)
 // Tell the compiler to link to either panic_abort or panic_unwind
 #![needs_panic_runtime]
 // Ensure that std can be linked against panic_abort despite compiled with `-C panic=unwind`
-#![cfg_attr(not(bootstrap), deny(ffi_unwind_calls))]
+#![deny(ffi_unwind_calls)]
 // std may use features in a platform-specific way
 #![allow(unused_features)]
 #![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))]
 #![feature(intra_doc_pointers)]
 #![feature(label_break_value)]
 #![feature(lang_items)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(linkage)]
 #![feature(link_cfg)]
index 081915ed148b36be114ec2154b30022dab8c658c..1b3d110426febb3c1fe6869aaf96265efcb35b8f 100644 (file)
@@ -14,7 +14,7 @@
 use crate::sys_common::{AsInner, IntoInner};
 
 /// Raw file descriptors.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub type RawFd = raw::c_int;
 
@@ -23,7 +23,7 @@
 /// This is only available on unix and WASI platforms and must be imported in
 /// order to call the method. Windows platforms have a corresponding
 /// `AsRawHandle` and `AsRawSocket` set of traits.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait AsRawFd {
     /// Extracts the raw file descriptor.
@@ -59,7 +59,7 @@ pub trait AsRawFd {
 
 /// A trait to express the ability to construct an object from a raw file
 /// descriptor.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
 #[stable(feature = "from_raw_os", since = "1.1.0")]
 pub trait FromRawFd {
     /// Constructs a new instance of `Self` from the given raw file
@@ -103,7 +103,7 @@ pub trait FromRawFd {
 
 /// A trait to express the ability to consume an object and acquire ownership of
 /// its raw file descriptor.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
 #[stable(feature = "into_raw_os", since = "1.4.0")]
 pub trait IntoRawFd {
     /// Consumes this object, returning the raw underlying file descriptor.
index b8e5461640c0581ea4a242fb7724aea2140c01da..1c14b9341cac8e435a0cd8746f41e712d3ac8893 100644 (file)
@@ -996,7 +996,7 @@ impl<T> (T,) {}
 // Fake impl that's only really used for docs.
 #[cfg(doc)]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
 /// This trait is implemented on arbitrary-length tuples.
 impl<T: Clone> Clone for (T,) {
     fn clone(&self) -> Self {
@@ -1007,7 +1007,7 @@ fn clone(&self) -> Self {
 // Fake impl that's only really used for docs.
 #[cfg(doc)]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
 /// This trait is implemented on arbitrary-length tuples.
 impl<T: Copy> Copy for (T,) {
     // empty
@@ -1484,13 +1484,12 @@ mod prim_fn {}
 // Required to make auto trait impls render.
 // See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
 #[doc(hidden)]
-#[cfg(not(bootstrap))]
 impl<Ret, T> fn(T) -> Ret {}
 
 // Fake impl that's only really used for docs.
 #[cfg(doc)]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
 /// This trait is implemented on function pointers with any number of arguments.
 impl<Ret, T> Clone for fn(T) -> Ret {
     fn clone(&self) -> Self {
@@ -1501,7 +1500,7 @@ fn clone(&self) -> Self {
 // Fake impl that's only really used for docs.
 #[cfg(doc)]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
 /// This trait is implemented on function pointers with any number of arguments.
 impl<Ret, T> Copy for fn(T) -> Ret {
     // empty
index ea24fedd0eb3dbe6d7a6bb701a677afcab612383..66fa1efbf103f26115a00c5e78bbf8edb433a1f3 100644 (file)
@@ -115,7 +115,7 @@ unsafe fn from_raw_sized(ptr: *mut u8, size: usize) -> NonNull<Self> {
     /// * the pointer is null.
     /// * the pointed-to range is not in user memory.
     unsafe fn check_ptr(ptr: *const Self) {
-        let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) };
+        let is_aligned = |p: *const u8| -> bool { 0 == p.addr() & (Self::align_of() - 1) };
 
         assert!(is_aligned(ptr as *const u8));
         assert!(is_user_range(ptr as _, mem::size_of_val(unsafe { &*ptr })));
index b5cc8038ca44f817ddb6c971224aa5e29fed4625..7778033eaa98c6d1bd5e460b174a54e49f0ef4cb 100644 (file)
@@ -544,11 +544,11 @@ impl Default for FileTimes {
     fn default() -> Self {
         // Redox doesn't appear to support `UTIME_OMIT`, so we stub it out here, and always return
         // an error in `set_times`.
-        // ESP-IDF does not support `futimens` at all and the behavior for that OS is therefore
+        // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
         // the same as for Redox.
-        #[cfg(any(target_os = "redox", target_os = "espidf"))]
+        #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))]
         let omit = libc::timespec { tv_sec: 0, tv_nsec: 0 };
-        #[cfg(not(any(target_os = "redox", target_os = "espidf")))]
+        #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
         let omit = libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ };
         Self([omit; 2])
     }
@@ -687,7 +687,11 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
 impl Drop for Dir {
     fn drop(&mut self) {
         let r = unsafe { libc::closedir(self.0) };
-        debug_assert_eq!(r, 0);
+        assert!(
+            r == 0 || crate::io::Error::last_os_error().kind() == crate::io::ErrorKind::Interrupted,
+            "unexpected error during closedir: {:?}",
+            crate::io::Error::last_os_error()
+        );
     }
 }
 
@@ -1079,9 +1083,9 @@ pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
 
     pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
         cfg_if::cfg_if! {
-            if #[cfg(any(target_os = "redox", target_os = "espidf"))] {
+            if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
                 // Redox doesn't appear to support `UTIME_OMIT`.
-                // ESP-IDF does not support `futimens` at all and the behavior for that OS is therefore
+                // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
                 // the same as for Redox.
                 drop(times);
                 Err(io::const_io_error!(
index abf27e7db78c7c0e30467e56289ede3c5f87e873..4741c0c6736e37f1a28c6a1b9468df1eceeabe84 100644 (file)
@@ -172,7 +172,7 @@ pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool {
         let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 };
         let stable_now = Instant::now();
         let r = libc::gettimeofday(&mut sys_now, ptr::null_mut());
-        debug_assert_eq!(r, 0);
+        assert_eq!(r, 0, "unexpected error: {:?}", crate::io::Error::last_os_error());
 
         let nsec = dur.subsec_nanos() as libc::c_long + (sys_now.tv_usec * 1000) as libc::c_long;
         let extra = (nsec / 1_000_000_000) as libc::time_t;
index 8d5d0a2f5ccd165987274b961b30887804b34045..d715ae45401e654d88c251a0db98e2c1e6038196 100644 (file)
@@ -1,15 +1,16 @@
 use crate::alloc::{GlobalAlloc, Layout, System};
+use crate::ptr::null_mut;
 
 #[stable(feature = "alloc_system_type", since = "1.28.0")]
 unsafe impl GlobalAlloc for System {
     #[inline]
     unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
-        0 as *mut u8
+        null_mut()
     }
 
     #[inline]
     unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 {
-        0 as *mut u8
+        null_mut()
     }
 
     #[inline]
@@ -17,6 +18,6 @@ unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
 
     #[inline]
     unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 {
-        0 as *mut u8
+        null_mut()
     }
 }
index 968738a418080d3e28eae59de99fec9a3dba327a..6f32b858f09666a2a22a4dadbf1c8e94d70c3b39 100644 (file)
@@ -1,4 +1,5 @@
 use super::{Key, StaticKey};
+use core::ptr;
 
 fn assert_sync<T: Sync>() {}
 fn assert_send<T: Send>() {}
@@ -12,8 +13,8 @@ fn smoke() {
     let k2 = Key::new(None);
     assert!(k1.get().is_null());
     assert!(k2.get().is_null());
-    k1.set(1 as *mut _);
-    k2.set(2 as *mut _);
+    k1.set(ptr::invalid_mut(1));
+    k2.set(ptr::invalid_mut(2));
     assert_eq!(k1.get() as usize, 1);
     assert_eq!(k2.get() as usize, 2);
 }
@@ -26,8 +27,8 @@ fn statik() {
     unsafe {
         assert!(K1.get().is_null());
         assert!(K2.get().is_null());
-        K1.set(1 as *mut _);
-        K2.set(2 as *mut _);
+        K1.set(ptr::invalid_mut(1));
+        K2.set(ptr::invalid_mut(2));
         assert_eq!(K1.get() as usize, 1);
         assert_eq!(K2.get() as usize, 2);
     }
index 44c8a50fd860a0a121df1ef5d00d2b8bbb7b45c2..479669647c12843c743b19ebabd9b6743e6919f2 100644 (file)
 use crate::str;
 use crate::sync::Arc;
 use crate::sys::thread as imp;
-use crate::sys_common::mutex;
 use crate::sys_common::thread;
 use crate::sys_common::thread_info;
 use crate::sys_common::thread_parker::Parker;
@@ -1033,24 +1032,48 @@ pub fn park_timeout(dur: Duration) {
 impl ThreadId {
     // Generate a new unique thread ID.
     fn new() -> ThreadId {
-        // It is UB to attempt to acquire this mutex reentrantly!
-        static GUARD: mutex::StaticMutex = mutex::StaticMutex::new();
-        static mut COUNTER: u64 = 1;
-
-        unsafe {
-            let guard = GUARD.lock();
-
-            // If we somehow use up all our bits, panic so that we're not
-            // covering up subtle bugs of IDs being reused.
-            if COUNTER == u64::MAX {
-                drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
-                panic!("failed to generate unique thread ID: bitspace exhausted");
-            }
-
-            let id = COUNTER;
-            COUNTER += 1;
+        #[cold]
+        fn exhausted() -> ! {
+            panic!("failed to generate unique thread ID: bitspace exhausted")
+        }
 
-            ThreadId(NonZeroU64::new(id).unwrap())
+        cfg_if::cfg_if! {
+            if #[cfg(target_has_atomic = "64")] {
+                use crate::sync::atomic::{AtomicU64, Ordering::Relaxed};
+
+                static COUNTER: AtomicU64 = AtomicU64::new(0);
+
+                let mut last = COUNTER.load(Relaxed);
+                loop {
+                    let Some(id) = last.checked_add(1) else {
+                        exhausted();
+                    };
+
+                    match COUNTER.compare_exchange_weak(last, id, Relaxed, Relaxed) {
+                        Ok(_) => return ThreadId(NonZeroU64::new(id).unwrap()),
+                        Err(id) => last = id,
+                    }
+                }
+            } else {
+                use crate::sys_common::mutex::StaticMutex;
+
+                // It is UB to attempt to acquire this mutex reentrantly!
+                static GUARD: StaticMutex = StaticMutex::new();
+                static mut COUNTER: u64 = 0;
+
+                unsafe {
+                    let guard = GUARD.lock();
+
+                    let Some(id) = COUNTER.checked_add(1) else {
+                        drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
+                        exhausted();
+                    };
+
+                    COUNTER = id;
+                    drop(guard);
+                    ThreadId(NonZeroU64::new(id).unwrap())
+                }
+            }
         }
     }
 
index dd2b9d59366eab0b5bfc38dfe20a116a8381afca..c3aabb16a9b9af131c70095d4ecc6e667efe5a07 100644 (file)
@@ -658,7 +658,12 @@ fn run(self, builder: &Builder<'_>) {
 
         // With LLD, we can use ICF (identical code folding) to reduce the executable size
         // of librustc_driver/rustc and to improve i-cache utilization.
-        if builder.config.use_lld {
+        //
+        // -Wl,[link options] doesn't work on MSVC. However, /OPT:ICF (technically /OPT:REF,ICF)
+        // is already on by default in MSVC optimized builds, which is interpreted as --icf=all:
+        // https://github.com/llvm/llvm-project/blob/3329cec2f79185bafd678f310fafadba2a8c76d2/lld/COFF/Driver.cpp#L1746
+        // https://github.com/rust-lang/rust/blob/f22819bcce4abaff7d1246a56eec493418f9f4ee/compiler/rustc_codegen_ssa/src/back/linker.rs#L827
+        if builder.config.use_lld && !compiler.host.contains("msvc") {
             cargo.rustflag("-Clink-args=-Wl,--icf=all");
         }
 
index 4325a237c69da6ec828a9fc9bedbf66ca25fc897..c4983accc68db9f7f677cf262f7f5be0cfeaea97 100644 (file)
@@ -1445,7 +1445,11 @@ pub fn llvm_libunwind(&self, target: TargetSelection) -> LlvmLibunwind {
             .get(&target)
             .and_then(|t| t.llvm_libunwind)
             .or(self.llvm_libunwind_default)
-            .unwrap_or(LlvmLibunwind::No)
+            .unwrap_or(if target.contains("fuchsia") {
+                LlvmLibunwind::InTree
+            } else {
+                LlvmLibunwind::No
+            })
     }
 
     pub fn submodules(&self, rust_info: &GitInfo) -> bool {
index 39d9ce1621ba2a751ae1007632f75a0d0012fa4b..1edb513f0b62da6cc9ee440d4c2d7d72f1b9721d 100644 (file)
@@ -80,6 +80,7 @@ pub struct Flags {
     pub llvm_profile_generate: bool,
 }
 
+#[derive(Debug)]
 #[cfg_attr(test, derive(Clone))]
 pub enum Subcommand {
     Build {
index 1e0f7e9acf4f2bcbc6eb6c16fe79a516115ad6c1..9a08a7be0f5f7198a5efe0c2add00948d3536e76 100644 (file)
@@ -80,7 +80,7 @@ TESTS_IN_MINGW_2 := \
        src/test/ui
 
 ci-mingw-subset-1:
-       $(Q)$(CFG_SRC_DIR)/x.sh test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %)
+       $(Q)$(CFG_SRC_DIR)/x test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %)
 ci-mingw-subset-2:
        $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2)
 
index a5a39a5a3cfc6355cc784d15ac65cb82944bfbf0..eb7da1bda73cb19d98fde4ca406a28883acb9a29 100644 (file)
@@ -11,7 +11,7 @@
     io::{self, Write},
 };
 
-#[derive(Clone, Copy, Eq, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum Profile {
     Compiler,
     Codegen,
index 8de9045c3baa73e768223e97192fafc79b4eba30..14d0ffd75005fb5216aa13b9804f7fe1cc8a1f94 100644 (file)
@@ -44,7 +44,7 @@ ENV RUST_CONFIGURE_ARGS \
       --enable-llvm-link-shared \
       --set rust.thin-lto-import-instr-limit=10
 
-# NOTE: intentionally uses all of `x.py`, `x.sh`, and `x.ps1` to make sure they all work on Linux.
+# NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux.
 ENV SCRIPT ../x.py --stage 2 test --exclude src/tools/tidy && \
            # Run the `mir-opt` tests again but this time for a 32-bit target.
            # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
@@ -52,7 +52,7 @@ ENV SCRIPT ../x.py --stage 2 test --exclude src/tools/tidy && \
            # the PR is approved and tested for merging.
            # It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
            # despite having different output on 32-bit vs 64-bit targets.
-           ../x.sh --stage 2 test src/test/mir-opt \
+           ../x --stage 2 test src/test/mir-opt \
                              --host='' --target=i686-unknown-linux-gnu && \
            # Run the UI test suite again, but in `--pass=check` mode
            #
index 61bd1b425bc35e420ce3e0506e35795dc77ed80d..c526e4d1fa82258045939a6abbf778834ee50555 100644 (file)
@@ -53,12 +53,6 @@ In `config.toml`, add:
 ```toml
 [build]
 target = ["<host_platform>", "aarch64-fuchsia", "x86_64-fuchsia"]
-
-[target.x86_64-fuchsia]
-llvm-libunwind = "in-tree"
-
-[target.aarch64-fuchsia]
-llvm-libunwind = "in-tree"
 ```
 
 Additionally, the following environment variables must be configured (for
index a705e2384959f1b8ad56db2d1a2ce3d2e44d9fc7..ce06a79a21c3f58a770606027708e84b6552afa0 100644 (file)
@@ -57,7 +57,7 @@ def check_generic_bound(bound):
     if "trait_bound" in bound:
         for param in bound["trait_bound"]["generic_params"]:
             check_generic_param(param)
-        check_type(bound["trait_bound"]["trait"])
+        check_path(bound["trait_bound"]["trait"])
 
 
 def check_decl(decl):
@@ -66,35 +66,35 @@ def check_decl(decl):
     if decl["output"]:
         check_type(decl["output"])
 
+def check_path(path):
+    args = path["args"]
+    if args:
+        if "angle_bracketed" in args:
+            for arg in args["angle_bracketed"]["args"]:
+                if "type" in arg:
+                    check_type(arg["type"])
+                elif "const" in arg:
+                    check_type(arg["const"]["type"])
+            for binding in args["angle_bracketed"]["bindings"]:
+                if "equality" in binding["binding"]:
+                    term = binding["binding"]["equality"]
+                    if "type" in term: check_type(term["type"])
+                    elif "const" in term: check_type(term["const"])
+                elif "constraint" in binding["binding"]:
+                    for bound in binding["binding"]["constraint"]:
+                        check_generic_bound(bound)
+        elif "parenthesized" in args:
+            for input_ty in args["parenthesized"]["inputs"]:
+                check_type(input_ty)
+            if args["parenthesized"]["output"]:
+                check_type(args["parenthesized"]["output"])
+    if not valid_id(path["id"]):
+        print("Type contained an invalid ID:", path["id"])
+        sys.exit(1)
 
 def check_type(ty):
     if ty["kind"] == "resolved_path":
-        for bound in ty["inner"]["param_names"]:
-            check_generic_bound(bound)
-        args = ty["inner"]["args"]
-        if args:
-            if "angle_bracketed" in args:
-                for arg in args["angle_bracketed"]["args"]:
-                    if "type" in arg:
-                        check_type(arg["type"])
-                    elif "const" in arg:
-                        check_type(arg["const"]["type"])
-                for binding in args["angle_bracketed"]["bindings"]:
-                    if "equality" in binding["binding"]:
-                        term = binding["binding"]["equality"]
-                        if "type" in term: check_type(term["type"])
-                        elif "const" in term: check_type(term["const"])
-                    elif "constraint" in binding["binding"]:
-                        for bound in binding["binding"]["constraint"]:
-                            check_generic_bound(bound)
-            elif "parenthesized" in args:
-                for input_ty in args["parenthesized"]["inputs"]:
-                    check_type(input_ty)
-                if args["parenthesized"]["output"]:
-                    check_type(args["parenthesized"]["output"])
-        if not valid_id(ty["inner"]["id"]):
-            print("Type contained an invalid ID:", ty["inner"]["id"])
-            sys.exit(1)
+        check_path(ty["inner"])
     elif ty["kind"] == "tuple":
         for ty in ty["inner"]:
             check_type(ty)
@@ -111,7 +111,7 @@ def check_type(ty):
         check_decl(ty["inner"]["decl"])
     elif ty["kind"] == "qualified_path":
         check_type(ty["inner"]["self_type"])
-        check_type(ty["inner"]["trait"])
+        check_path(ty["inner"]["trait"])
 
 
 work_list = set([crate["root"]])
@@ -174,7 +174,7 @@ while work_list:
     elif item["kind"] == "impl":
         check_generics(item["inner"]["generics"])
         if item["inner"]["trait"]:
-            check_type(item["inner"]["trait"])
+            check_path(item["inner"]["trait"])
         if item["inner"]["blanket_impl"]:
             check_type(item["inner"]["blanket_impl"])
         check_type(item["inner"]["for"])
index d02ac9d9c0ab7adb8d3092e6209250e95e87db38..baf95627c702820ea56bac0fea38841e73383ed6 100644 (file)
@@ -41,15 +41,15 @@ There are a number of supported commands:
   `PATH` is relative to the output directory. It can be given as `-`
   which repeats the most recently used `PATH`.
 
-* `@has PATH PATTERN` and `@matches PATH PATTERN` checks for
-  the occurrence of the given pattern `PATTERN` in the specified file.
+* `@hasraw PATH PATTERN` and `@matchesraw PATH PATTERN` checks
+  for the occurrence of the given pattern `PATTERN` in the specified file.
   Only one occurrence of the pattern is enough.
 
-  For `@has`, `PATTERN` is a whitespace-normalized (every consecutive
+  For `@hasraw`, `PATTERN` is a whitespace-normalized (every consecutive
   whitespace being replaced by one single space character) string.
   The entire file is also whitespace-normalized including newlines.
 
-  For `@matches`, `PATTERN` is a Python-supported regular expression.
+  For `@matchesraw`, `PATTERN` is a Python-supported regular expression.
   The file remains intact but the regexp is matched without the `MULTILINE`
   and `IGNORECASE` options. You can still use a prefix `(?m)` or `(?i)`
   to override them, and `\A` and `\Z` for definitely matching
@@ -542,19 +542,23 @@ ERR_COUNT = 0
 def check_command(c, cache):
     try:
         cerr = ""
-        if c.cmd == 'has' or c.cmd == 'matches':  # string test
-            regexp = (c.cmd == 'matches')
-            if len(c.args) == 1 and not regexp:  # @has <path> = file existence
+        if c.cmd in ['has', 'hasraw', 'matches', 'matchesraw']:  # string test
+            regexp = c.cmd.startswith('matches')
+
+            # @has <path> = file existence
+            if len(c.args) == 1 and not regexp and 'raw' not in c.cmd:
                 try:
                     cache.get_file(c.args[0])
                     ret = True
                 except FailedCheck as err:
                     cerr = str(err)
                     ret = False
-            elif len(c.args) == 2:  # @has/matches <path> <pat> = string test
+            # @hasraw/matchesraw <path> <pat> = string test
+            elif len(c.args) == 2 and 'raw' in c.cmd:
                 cerr = "`PATTERN` did not match"
                 ret = check_string(cache.get_file(c.args[0]), c.args[1], regexp)
-            elif len(c.args) == 3:  # @has/matches <path> <pat> <match> = XML tree test
+            # @has/matches <path> <pat> <match> = XML tree test
+            elif len(c.args) == 3 and 'raw' not in c.cmd:
                 cerr = "`XPATH PATTERN` did not match"
                 ret = get_nb_matching_elements(cache, c, regexp, True) != 0
             else:
index 558536fa613a5abae81809ef20ead310cb1850e8..277e57aaf6fc5ea4cd93efe9e1cdddf8a37f19f4 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
   <Type Name="str">
     <DisplayString>{(char*)data_ptr,[length]s8}</DisplayString>
     </Expand>
   </Type>
 
-  <!-- Directly tagged enums. $T1 is the type name -->
-  <Type Name="enum$&lt;*&gt;">
-    <Intrinsic Name="tag" Expression="discriminant" />
-    <DisplayString Condition="tag() == 0">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 1" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 2" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 3" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 4" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 5" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 6" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 7" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 8" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 9" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 10" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 11" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 12" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 13" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 14" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 15" Optional="true">{tag(),en}</DisplayString>
+  <!--
+    This is the visualizer for all enums. It takes care of selecting the active variant.
+    See `compiler\rustc_codegen_llvm\src\debuginfo\metadata\enums\cpp_like.rs` for more information.
+  -->
+  <Type Name="enum2$&lt;*&gt;">
+    <!-- NOTE: That tag ranges can wrap around, in which case `end` is less than `begin` and we
+               have to do a different check -->
+    <Intrinsic Name="in_range" Expression="(begin &lt;= end) ? ((x &gt;= begin) &amp;&amp; (x &lt;= end)) : ((x &gt;= begin) || (x &lt;= end))">
+      <Parameter Name="x" Type="unsigned __int64" />
+      <Parameter Name="begin" Type="unsigned __int64" />
+      <Parameter Name="end" Type="unsigned __int64" />
+    </Intrinsic>
 
-    <Expand>
-      <Synthetic Name="[variant]">
-        <DisplayString>{tag(),en}</DisplayString>
-      </Synthetic>
-      <ExpandedItem Condition="tag() == 0">variant0</ExpandedItem>
-      <ExpandedItem Condition="tag() == 1" Optional="true">variant1</ExpandedItem>
-      <ExpandedItem Condition="tag() == 2" Optional="true">variant2</ExpandedItem>
-      <ExpandedItem Condition="tag() == 3" Optional="true">variant3</ExpandedItem>
-      <ExpandedItem Condition="tag() == 4" Optional="true">variant4</ExpandedItem>
-      <ExpandedItem Condition="tag() == 5" Optional="true">variant5</ExpandedItem>
-      <ExpandedItem Condition="tag() == 6" Optional="true">variant6</ExpandedItem>
-      <ExpandedItem Condition="tag() == 7" Optional="true">variant7</ExpandedItem>
-      <ExpandedItem Condition="tag() == 8" Optional="true">variant8</ExpandedItem>
-      <ExpandedItem Condition="tag() == 9" Optional="true">variant9</ExpandedItem>
-      <ExpandedItem Condition="tag() == 10" Optional="true">variant10</ExpandedItem>
-      <ExpandedItem Condition="tag() == 11" Optional="true">variant11</ExpandedItem>
-      <ExpandedItem Condition="tag() == 12" Optional="true">variant12</ExpandedItem>
-      <ExpandedItem Condition="tag() == 13" Optional="true">variant13</ExpandedItem>
-      <ExpandedItem Condition="tag() == 14" Optional="true">variant14</ExpandedItem>
-      <ExpandedItem Condition="tag() == 15" Optional="true">variant15</ExpandedItem>
-    </Expand>
-  </Type>
+    <Intrinsic Name="eq128" Expression="(x_hi == y_hi) &amp;&amp; (x_lo == y_lo)">
+      <Parameter Name="x_hi" Type="unsigned __int64" />
+      <Parameter Name="x_lo" Type="unsigned __int64" />
+      <Parameter Name="y_hi" Type="unsigned __int64" />
+      <Parameter Name="y_lo" Type="unsigned __int64" />
+    </Intrinsic>
 
-  <!-- Single variant enums. $T1 is the name of the enum, $T2 is the name of the variant -->
-  <Type Name="enum$&lt;*, *&gt;">
-    <DisplayString>{"$T2",sb}</DisplayString>
-    <Expand>
-      <Synthetic Name="[variant]">
-        <DisplayString>{"$T2",sb}</DisplayString>
-      </Synthetic>
-      <ExpandedItem>$T2</ExpandedItem>
-    </Expand>
-  </Type>
+    <Intrinsic Name="lt128" Expression="(x_hi &lt; y_hi) || ((x_hi == y_hi) &amp;&amp; (x_lo &lt; y_lo))">
+      <Parameter Name="x_hi" Type="unsigned __int64" />
+      <Parameter Name="x_lo" Type="unsigned __int64" />
+      <Parameter Name="y_hi" Type="unsigned __int64" />
+      <Parameter Name="y_lo" Type="unsigned __int64" />
+    </Intrinsic>
 
-  <!-- Niche-layout enums. $T1 is the name of the enum, $T2 is the low value of the dataful
-       variant tag, $T3 is the high value of the dataful variant tag, $T4 is the name of
-       the dataful variant -->
-  <Type Name="enum$&lt;*, *, *, *&gt;">
-    <Intrinsic Name="tag" Expression="discriminant" />
-    <Intrinsic Name="is_dataful" Expression="tag() &gt;= $T2 &amp;&amp; tag() &lt;= $T3" />
-    <DisplayString Condition="is_dataful()">{"$T4",sb}({dataful_variant})</DisplayString>
-    <DisplayString Condition="!is_dataful()">{discriminant,en}</DisplayString>
-    <Expand>
-      <ExpandedItem Condition="is_dataful()">dataful_variant</ExpandedItem>
-      <Synthetic Condition="is_dataful()" Name="[variant]">
-        <DisplayString>{"$T4",sb}</DisplayString>
-      </Synthetic>
-      <Synthetic Condition="!is_dataful()" Name="[variant]">
-        <DisplayString>{discriminant,en}</DisplayString>
-      </Synthetic>
+    <Intrinsic Name="lt_or_eq128" Expression="((x_hi == y_hi) &amp;&amp; (x_lo == y_lo)) || lt128(x_hi, x_lo, y_hi, y_lo)">
+      <Parameter Name="x_hi" Type="unsigned __int64" />
+      <Parameter Name="x_lo" Type="unsigned __int64" />
+      <Parameter Name="y_hi" Type="unsigned __int64" />
+      <Parameter Name="y_lo" Type="unsigned __int64" />
+    </Intrinsic>
+
+    <!-- NOTE: That tag ranges can wrap around, in which case `end` is less than `begin` and we
+               have to do a different check -->
+    <Intrinsic Name="in_range128" Expression="(lt_or_eq128(begin_hi, begin_lo, end_hi, end_lo)) ?
+                                              (lt_or_eq128(begin_hi, begin_lo, x_hi, x_lo) &amp;&amp; lt_or_eq128(x_hi, x_lo, end_hi, end_lo)) :
+                                              (lt_or_eq128(begin_hi, begin_lo, x_hi, x_lo) || lt_or_eq128(x_hi, x_lo, end_hi, end_lo))">
+      <Parameter Name="x_hi" Type="unsigned __int64" />
+      <Parameter Name="x_lo" Type="unsigned __int64" />
+      <Parameter Name="begin_hi" Type="unsigned __int64" />
+      <Parameter Name="begin_lo" Type="unsigned __int64" />
+      <Parameter Name="end_hi" Type="unsigned __int64" />
+      <Parameter Name="end_lo" Type="unsigned __int64" />
+    </Intrinsic>
+
+    <DisplayString Condition="tag == variant0.DISCR_EXACT" Optional="true">{variant0.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant1.DISCR_EXACT" Optional="true">{variant1.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant2.DISCR_EXACT" Optional="true">{variant2.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant3.DISCR_EXACT" Optional="true">{variant3.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant4.DISCR_EXACT" Optional="true">{variant4.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant5.DISCR_EXACT" Optional="true">{variant5.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant6.DISCR_EXACT" Optional="true">{variant6.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant7.DISCR_EXACT" Optional="true">{variant7.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant8.DISCR_EXACT" Optional="true">{variant8.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant9.DISCR_EXACT" Optional="true">{variant9.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant10.DISCR_EXACT" Optional="true">{variant10.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant11.DISCR_EXACT" Optional="true">{variant11.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant12.DISCR_EXACT" Optional="true">{variant12.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant13.DISCR_EXACT" Optional="true">{variant13.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant14.DISCR_EXACT" Optional="true">{variant14.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant15.DISCR_EXACT" Optional="true">{variant15.NAME,en}</DisplayString>
+
+    <DisplayString Condition="in_range(tag, variant0.DISCR_BEGIN, variant0.DISCR_END)" Optional="true">{variant0.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant1.DISCR_BEGIN, variant1.DISCR_END)" Optional="true">{variant1.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant2.DISCR_BEGIN, variant2.DISCR_END)" Optional="true">{variant2.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant3.DISCR_BEGIN, variant3.DISCR_END)" Optional="true">{variant3.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant4.DISCR_BEGIN, variant4.DISCR_END)" Optional="true">{variant4.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant5.DISCR_BEGIN, variant5.DISCR_END)" Optional="true">{variant5.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant6.DISCR_BEGIN, variant6.DISCR_END)" Optional="true">{variant6.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant7.DISCR_BEGIN, variant7.DISCR_END)" Optional="true">{variant7.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant8.DISCR_BEGIN, variant8.DISCR_END)" Optional="true">{variant8.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant9.DISCR_BEGIN, variant9.DISCR_END)" Optional="true">{variant9.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant10.DISCR_BEGIN, variant10.DISCR_END)" Optional="true">{variant10.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant11.DISCR_BEGIN, variant11.DISCR_END)" Optional="true">{variant11.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant12.DISCR_BEGIN, variant12.DISCR_END)" Optional="true">{variant12.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant13.DISCR_BEGIN, variant13.DISCR_END)" Optional="true">{variant13.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant14.DISCR_BEGIN, variant14.DISCR_END)" Optional="true">{variant14.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant15.DISCR_BEGIN, variant15.DISCR_END)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant0.DISCR128_EXACT_HI, variant0.DISCR128_EXACT_LO)" Optional="true">{variant0.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant1.DISCR128_EXACT_HI, variant1.DISCR128_EXACT_LO)" Optional="true">{variant1.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant2.DISCR128_EXACT_HI, variant2.DISCR128_EXACT_LO)" Optional="true">{variant2.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant3.DISCR128_EXACT_HI, variant3.DISCR128_EXACT_LO)" Optional="true">{variant3.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant4.DISCR128_EXACT_HI, variant4.DISCR128_EXACT_LO)" Optional="true">{variant4.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant5.DISCR128_EXACT_HI, variant5.DISCR128_EXACT_LO)" Optional="true">{variant5.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant6.DISCR128_EXACT_HI, variant6.DISCR128_EXACT_LO)" Optional="true">{variant6.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant7.DISCR128_EXACT_HI, variant7.DISCR128_EXACT_LO)" Optional="true">{variant7.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant8.DISCR128_EXACT_HI, variant8.DISCR128_EXACT_LO)" Optional="true">{variant8.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant9.DISCR128_EXACT_HI, variant9.DISCR128_EXACT_LO)" Optional="true">{variant9.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant10.DISCR128_EXACT_HI, variant10.DISCR128_EXACT_LO)" Optional="true">{variant10.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant11.DISCR128_EXACT_HI, variant11.DISCR128_EXACT_LO)" Optional="true">{variant11.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant12.DISCR128_EXACT_HI, variant12.DISCR128_EXACT_LO)" Optional="true">{variant12.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant13.DISCR128_EXACT_HI, variant13.DISCR128_EXACT_LO)" Optional="true">{variant13.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant14.DISCR128_EXACT_HI, variant14.DISCR128_EXACT_LO)" Optional="true">{variant14.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant15.DISCR128_EXACT_HI, variant15.DISCR128_EXACT_LO)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant0.DISCR128_BEGIN_HI, variant0.DISCR128_BEGIN_LO, variant0.DISCR128_END_HI, variant0.DISCR128_END_LO)" Optional="true">{variant0.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant1.DISCR128_BEGIN_HI, variant1.DISCR128_BEGIN_LO, variant1.DISCR128_END_HI, variant1.DISCR128_END_LO)" Optional="true">{variant1.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant2.DISCR128_BEGIN_HI, variant2.DISCR128_BEGIN_LO, variant2.DISCR128_END_HI, variant2.DISCR128_END_LO)" Optional="true">{variant2.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant3.DISCR128_BEGIN_HI, variant3.DISCR128_BEGIN_LO, variant3.DISCR128_END_HI, variant3.DISCR128_END_LO)" Optional="true">{variant3.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant4.DISCR128_BEGIN_HI, variant4.DISCR128_BEGIN_LO, variant4.DISCR128_END_HI, variant4.DISCR128_END_LO)" Optional="true">{variant4.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant5.DISCR128_BEGIN_HI, variant5.DISCR128_BEGIN_LO, variant5.DISCR128_END_HI, variant5.DISCR128_END_LO)" Optional="true">{variant5.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant6.DISCR128_BEGIN_HI, variant6.DISCR128_BEGIN_LO, variant6.DISCR128_END_HI, variant6.DISCR128_END_LO)" Optional="true">{variant6.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant7.DISCR128_BEGIN_HI, variant7.DISCR128_BEGIN_LO, variant7.DISCR128_END_HI, variant7.DISCR128_END_LO)" Optional="true">{variant7.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant8.DISCR128_BEGIN_HI, variant8.DISCR128_BEGIN_LO, variant8.DISCR128_END_HI, variant8.DISCR128_END_LO)" Optional="true">{variant8.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant9.DISCR128_BEGIN_HI, variant9.DISCR128_BEGIN_LO, variant9.DISCR128_END_HI, variant9.DISCR128_END_LO)" Optional="true">{variant9.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant10.DISCR128_BEGIN_HI, variant10.DISCR128_BEGIN_LO, variant10.DISCR128_END_HI, variant10.DISCR128_END_LO)" Optional="true">{variant10.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant11.DISCR128_BEGIN_HI, variant11.DISCR128_BEGIN_LO, variant11.DISCR128_END_HI, variant11.DISCR128_END_LO)" Optional="true">{variant11.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant12.DISCR128_BEGIN_HI, variant12.DISCR128_BEGIN_LO, variant12.DISCR128_END_HI, variant12.DISCR128_END_LO)" Optional="true">{variant12.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant13.DISCR128_BEGIN_HI, variant13.DISCR128_BEGIN_LO, variant13.DISCR128_END_HI, variant13.DISCR128_END_LO)" Optional="true">{variant13.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant14.DISCR128_BEGIN_HI, variant14.DISCR128_BEGIN_LO, variant14.DISCR128_END_HI, variant14.DISCR128_END_LO)" Optional="true">{variant14.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant15.DISCR128_BEGIN_HI, variant15.DISCR128_BEGIN_LO, variant15.DISCR128_END_HI, variant15.DISCR128_END_LO)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+    <Expand HideRawView="true">
+      <ExpandedItem Condition="tag == variant0.DISCR_EXACT" Optional="true">variant0.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant1.DISCR_EXACT" Optional="true">variant1.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant2.DISCR_EXACT" Optional="true">variant2.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant3.DISCR_EXACT" Optional="true">variant3.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant4.DISCR_EXACT" Optional="true">variant4.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant5.DISCR_EXACT" Optional="true">variant5.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant6.DISCR_EXACT" Optional="true">variant6.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant7.DISCR_EXACT" Optional="true">variant7.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant8.DISCR_EXACT" Optional="true">variant8.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant9.DISCR_EXACT" Optional="true">variant9.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant10.DISCR_EXACT" Optional="true">variant10.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant11.DISCR_EXACT" Optional="true">variant11.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant12.DISCR_EXACT" Optional="true">variant12.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant13.DISCR_EXACT" Optional="true">variant13.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant14.DISCR_EXACT" Optional="true">variant14.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant15.DISCR_EXACT" Optional="true">variant15.value</ExpandedItem>
+
+      <ExpandedItem Condition="in_range(tag, variant0.DISCR_BEGIN, variant0.DISCR_END)" Optional="true">variant0.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant1.DISCR_BEGIN, variant1.DISCR_END)" Optional="true">variant1.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant2.DISCR_BEGIN, variant2.DISCR_END)" Optional="true">variant2.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant3.DISCR_BEGIN, variant3.DISCR_END)" Optional="true">variant3.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant4.DISCR_BEGIN, variant4.DISCR_END)" Optional="true">variant4.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant5.DISCR_BEGIN, variant5.DISCR_END)" Optional="true">variant5.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant6.DISCR_BEGIN, variant6.DISCR_END)" Optional="true">variant6.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant7.DISCR_BEGIN, variant7.DISCR_END)" Optional="true">variant7.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant8.DISCR_BEGIN, variant8.DISCR_END)" Optional="true">variant8.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant9.DISCR_BEGIN, variant9.DISCR_END)" Optional="true">variant9.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant10.DISCR_BEGIN, variant10.DISCR_END)" Optional="true">variant10.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant11.DISCR_BEGIN, variant11.DISCR_END)" Optional="true">variant11.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant12.DISCR_BEGIN, variant12.DISCR_END)" Optional="true">variant12.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant13.DISCR_BEGIN, variant13.DISCR_END)" Optional="true">variant13.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant14.DISCR_BEGIN, variant14.DISCR_END)" Optional="true">variant14.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant15.DISCR_BEGIN, variant15.DISCR_END)" Optional="true">variant15.value</ExpandedItem>
+
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant0.DISCR128_EXACT_HI, variant0.DISCR128_EXACT_LO)" Optional="true">variant0.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant1.DISCR128_EXACT_HI, variant1.DISCR128_EXACT_LO)" Optional="true">variant1.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant2.DISCR128_EXACT_HI, variant2.DISCR128_EXACT_LO)" Optional="true">variant2.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant3.DISCR128_EXACT_HI, variant3.DISCR128_EXACT_LO)" Optional="true">variant3.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant4.DISCR128_EXACT_HI, variant4.DISCR128_EXACT_LO)" Optional="true">variant4.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant5.DISCR128_EXACT_HI, variant5.DISCR128_EXACT_LO)" Optional="true">variant5.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant6.DISCR128_EXACT_HI, variant6.DISCR128_EXACT_LO)" Optional="true">variant6.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant7.DISCR128_EXACT_HI, variant7.DISCR128_EXACT_LO)" Optional="true">variant7.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant8.DISCR128_EXACT_HI, variant8.DISCR128_EXACT_LO)" Optional="true">variant8.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant9.DISCR128_EXACT_HI, variant9.DISCR128_EXACT_LO)" Optional="true">variant9.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant10.DISCR128_EXACT_HI, variant10.DISCR128_EXACT_LO)" Optional="true">variant10.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant11.DISCR128_EXACT_HI, variant11.DISCR128_EXACT_LO)" Optional="true">variant11.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant12.DISCR128_EXACT_HI, variant12.DISCR128_EXACT_LO)" Optional="true">variant12.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant13.DISCR128_EXACT_HI, variant13.DISCR128_EXACT_LO)" Optional="true">variant13.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant14.DISCR128_EXACT_HI, variant14.DISCR128_EXACT_LO)" Optional="true">variant14.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant15.DISCR128_EXACT_HI, variant15.DISCR128_EXACT_LO)" Optional="true">variant15.value</ExpandedItem>
+
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant0.DISCR128_BEGIN_HI, variant0.DISCR128_BEGIN_LO, variant0.DISCR128_END_HI, variant0.DISCR128_END_LO)" Optional="true">variant0.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant1.DISCR128_BEGIN_HI, variant1.DISCR128_BEGIN_LO, variant1.DISCR128_END_HI, variant1.DISCR128_END_LO)" Optional="true">variant1.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant2.DISCR128_BEGIN_HI, variant2.DISCR128_BEGIN_LO, variant2.DISCR128_END_HI, variant2.DISCR128_END_LO)" Optional="true">variant2.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant3.DISCR128_BEGIN_HI, variant3.DISCR128_BEGIN_LO, variant3.DISCR128_END_HI, variant3.DISCR128_END_LO)" Optional="true">variant3.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant4.DISCR128_BEGIN_HI, variant4.DISCR128_BEGIN_LO, variant4.DISCR128_END_HI, variant4.DISCR128_END_LO)" Optional="true">variant4.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant5.DISCR128_BEGIN_HI, variant5.DISCR128_BEGIN_LO, variant5.DISCR128_END_HI, variant5.DISCR128_END_LO)" Optional="true">variant5.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant6.DISCR128_BEGIN_HI, variant6.DISCR128_BEGIN_LO, variant6.DISCR128_END_HI, variant6.DISCR128_END_LO)" Optional="true">variant6.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant7.DISCR128_BEGIN_HI, variant7.DISCR128_BEGIN_LO, variant7.DISCR128_END_HI, variant7.DISCR128_END_LO)" Optional="true">variant7.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant8.DISCR128_BEGIN_HI, variant8.DISCR128_BEGIN_LO, variant8.DISCR128_END_HI, variant8.DISCR128_END_LO)" Optional="true">variant8.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant9.DISCR128_BEGIN_HI, variant9.DISCR128_BEGIN_LO, variant9.DISCR128_END_HI, variant9.DISCR128_END_LO)" Optional="true">variant9.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant10.DISCR128_BEGIN_HI, variant10.DISCR128_BEGIN_LO, variant10.DISCR128_END_HI, variant10.DISCR128_END_LO)" Optional="true">variant10.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant11.DISCR128_BEGIN_HI, variant11.DISCR128_BEGIN_LO, variant11.DISCR128_END_HI, variant11.DISCR128_END_LO)" Optional="true">variant11.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant12.DISCR128_BEGIN_HI, variant12.DISCR128_BEGIN_LO, variant12.DISCR128_END_HI, variant12.DISCR128_END_LO)" Optional="true">variant12.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant13.DISCR128_BEGIN_HI, variant13.DISCR128_BEGIN_LO, variant13.DISCR128_END_HI, variant13.DISCR128_END_LO)" Optional="true">variant13.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant14.DISCR128_BEGIN_HI, variant14.DISCR128_BEGIN_LO, variant14.DISCR128_END_HI, variant14.DISCR128_END_LO)" Optional="true">variant14.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant15.DISCR128_BEGIN_HI, variant15.DISCR128_BEGIN_LO, variant15.DISCR128_END_HI, variant15.DISCR128_END_LO)" Optional="true">variant15.value</ExpandedItem>
     </Expand>
   </Type>
 </AutoVisualizer>
index 912418fa7d1eb0eeecf041d7beb117f15891d13d..bf6c02b91461a973f77f6cdce891719ff3423e11 100644 (file)
       </ArrayItems>
     </Expand>
   </Type>
-
-  <Type Name="alloc::borrow::Cow&lt;*&gt;">
-    <DisplayString Condition="RUST$ENUM$DISR == 0x0">Borrowed({__0})</DisplayString>
-    <DisplayString Condition="RUST$ENUM$DISR == 0x1">Owned({__0})</DisplayString>
-    <Expand>
-      <Item Name="[value]" ExcludeView="simple">__0</Item>
-    </Expand>
-  </Type>
 </AutoVisualizer>
index 6e24638548979bfc71895839f23a335b712e636b..971617a8400366d732e86d9d614870289b295234 100644 (file)
 pub(crate) use self::types::*;
 pub(crate) use self::utils::{get_auto_trait_and_blanket_impls, krate, register_res};
 
-pub(crate) trait Clean<'tcx, T> {
-    fn clean(&self, cx: &mut DocContext<'tcx>) -> T;
-}
-
 pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
     let mut items: Vec<Item> = vec![];
     let mut inserted = FxHashSet::default();
@@ -1322,14 +1318,17 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
             let trait_def = cx.tcx.associated_item(p.res.def_id()).container_id(cx.tcx);
             let trait_ = self::Path {
                 res: Res::Def(DefKind::Trait, trait_def),
-                segments: trait_segments.iter().map(|x| x.clean(cx)).collect(),
+                segments: trait_segments.iter().map(|x| clean_path_segment(x, cx)).collect(),
             };
             register_res(cx, trait_.res);
             let self_def_id = DefId::local(qself.hir_id.owner.local_def_index);
             let self_type = clean_ty(qself, cx);
             let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type);
             Type::QPath {
-                assoc: Box::new(p.segments.last().expect("segments were empty").clean(cx)),
+                assoc: Box::new(clean_path_segment(
+                    p.segments.last().expect("segments were empty"),
+                    cx,
+                )),
                 should_show_cast,
                 self_type: Box::new(self_type),
                 trait_,
@@ -1349,7 +1348,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
             let self_type = clean_ty(qself, cx);
             let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
             Type::QPath {
-                assoc: Box::new(segment.clean(cx)),
+                assoc: Box::new(clean_path_segment(segment, cx)),
                 should_show_cast,
                 self_type: Box::new(self_type),
                 trait_,
@@ -1507,7 +1506,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
                 if !lifetime.is_elided() { Some(clean_lifetime(*lifetime, cx)) } else { None };
             DynTrait(bounds, lifetime)
         }
-        TyKind::BareFn(barefn) => BareFunction(Box::new(barefn.clean(cx))),
+        TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
         // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
         TyKind::Infer | TyKind::Err => Infer,
         TyKind::Typeof(..) => panic!("unimplemented type {:?}", ty.kind),
@@ -1823,7 +1822,10 @@ fn clean_variant_data<'tcx>(
 }
 
 fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path {
-    Path { res: path.res, segments: path.segments.iter().map(|x| x.clean(cx)).collect() }
+    Path {
+        res: path.res,
+        segments: path.segments.iter().map(|x| clean_path_segment(x, cx)).collect(),
+    }
 }
 
 fn clean_generic_args<'tcx>(
@@ -1861,28 +1863,30 @@ fn clean_generic_args<'tcx>(
     }
 }
 
-impl<'tcx> Clean<'tcx, PathSegment> for hir::PathSegment<'tcx> {
-    fn clean(&self, cx: &mut DocContext<'tcx>) -> PathSegment {
-        PathSegment { name: self.ident.name, args: clean_generic_args(self.args(), cx) }
-    }
+fn clean_path_segment<'tcx>(
+    path: &hir::PathSegment<'tcx>,
+    cx: &mut DocContext<'tcx>,
+) -> PathSegment {
+    PathSegment { name: path.ident.name, args: clean_generic_args(path.args(), cx) }
 }
 
-impl<'tcx> Clean<'tcx, BareFunctionDecl> for hir::BareFnTy<'tcx> {
-    fn clean(&self, cx: &mut DocContext<'tcx>) -> BareFunctionDecl {
-        let (generic_params, decl) = enter_impl_trait(cx, |cx| {
-            // NOTE: generics must be cleaned before args
-            let generic_params = self
-                .generic_params
-                .iter()
-                .filter(|p| !is_elided_lifetime(p))
-                .map(|x| clean_generic_param(cx, None, x))
-                .collect();
-            let args = clean_args_from_types_and_names(cx, self.decl.inputs, self.param_names);
-            let decl = clean_fn_decl_with_args(cx, self.decl, args);
-            (generic_params, decl)
-        });
-        BareFunctionDecl { unsafety: self.unsafety, abi: self.abi, decl, generic_params }
-    }
+fn clean_bare_fn_ty<'tcx>(
+    bare_fn: &hir::BareFnTy<'tcx>,
+    cx: &mut DocContext<'tcx>,
+) -> BareFunctionDecl {
+    let (generic_params, decl) = enter_impl_trait(cx, |cx| {
+        // NOTE: generics must be cleaned before args
+        let generic_params = bare_fn
+            .generic_params
+            .iter()
+            .filter(|p| !is_elided_lifetime(p))
+            .map(|x| clean_generic_param(cx, None, x))
+            .collect();
+        let args = clean_args_from_types_and_names(cx, bare_fn.decl.inputs, bare_fn.param_names);
+        let decl = clean_fn_decl_with_args(cx, bare_fn.decl, args);
+        (generic_params, decl)
+    });
+    BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params }
 }
 
 fn clean_maybe_renamed_item<'tcx>(
@@ -1917,7 +1921,7 @@ fn clean_maybe_renamed_item<'tcx>(
                 }))
             }
             ItemKind::Enum(ref def, generics) => EnumItem(Enum {
-                variants: def.variants.iter().map(|v| v.clean(cx)).collect(),
+                variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(),
                 generics: clean_generics(generics, cx),
             }),
             ItemKind::TraitAlias(generics, bounds) => TraitAliasItem(TraitAlias {
@@ -1970,14 +1974,12 @@ fn clean_maybe_renamed_item<'tcx>(
     })
 }
 
-impl<'tcx> Clean<'tcx, Item> for hir::Variant<'tcx> {
-    fn clean(&self, cx: &mut DocContext<'tcx>) -> Item {
-        let kind = VariantItem(clean_variant_data(&self.data, cx));
-        let what_rustc_thinks =
-            Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx);
-        // don't show `pub` for variants, which are always public
-        Item { visibility: Inherited, ..what_rustc_thinks }
-    }
+fn clean_variant<'tcx>(variant: &hir::Variant<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
+    let kind = VariantItem(clean_variant_data(&variant.data, cx));
+    let what_rustc_thinks =
+        Item::from_hir_id_and_parts(variant.id, Some(variant.ident.name), kind, cx);
+    // don't show `pub` for variants, which are always public
+    Item { visibility: Inherited, ..what_rustc_thinks }
 }
 
 fn clean_impl<'tcx>(
index 91d5758077c94fd98b7f9d1c22425af573274dab..1a4786c9b0664a056fa0243142e70d1c577e5fb5 100644 (file)
@@ -415,29 +415,28 @@ pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
             .unwrap_or(false)
     }
 
-    pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Span {
+    pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Option<Span> {
         let kind = match &*self.kind {
             ItemKind::StrippedItem(k) => k,
             _ => &*self.kind,
         };
         match kind {
-            ItemKind::ModuleItem(Module { span, .. }) => *span,
-            ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => Span::dummy(),
+            ItemKind::ModuleItem(Module { span, .. }) => Some(*span),
+            ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => None,
             ItemKind::ImplItem(box Impl { kind: ImplKind::Blanket(_), .. }) => {
                 if let ItemId::Blanket { impl_id, .. } = self.item_id {
-                    rustc_span(impl_id, tcx)
+                    Some(rustc_span(impl_id, tcx))
                 } else {
                     panic!("blanket impl item has non-blanket ID")
                 }
             }
-            _ => {
-                self.item_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy)
-            }
+            _ => self.item_id.as_def_id().map(|did| rustc_span(did, tcx)),
         }
     }
 
     pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span {
-        crate::passes::span_of_attrs(&self.attrs).unwrap_or_else(|| self.span(tcx).inner())
+        crate::passes::span_of_attrs(&self.attrs)
+            .unwrap_or_else(|| self.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner()))
     }
 
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
@@ -2109,14 +2108,6 @@ pub(crate) fn inner(&self) -> rustc_span::Span {
         self.0
     }
 
-    pub(crate) fn dummy() -> Self {
-        Self(rustc_span::DUMMY_SP)
-    }
-
-    pub(crate) fn is_dummy(&self) -> bool {
-        self.0.is_dummy()
-    }
-
     pub(crate) fn filename(&self, sess: &Session) -> FileName {
         sess.source_map().span_to_filename(self.0)
     }
index 5a6720a8dd95643c07f6c02894daccbf1697e192..9d8ee52a3faf861d3609f615427a6475eb7b996f 100644 (file)
@@ -111,6 +111,70 @@ fn write_header(out: &mut Buffer, class: &str, extra_content: Option<Buffer>) {
     write!(out, "<code>");
 }
 
+/// Write all the pending elements sharing a same (or at mergeable) `Class`.
+///
+/// If there is a "parent" (if a `EnterSpan` event was encountered) and the parent can be merged
+/// with the elements' class, then we simply write the elements since the `ExitSpan` event will
+/// close the tag.
+///
+/// Otherwise, if there is only one pending element, we let the `string` function handle both
+/// opening and closing the tag, otherwise we do it into this function.
+fn write_pending_elems(
+    out: &mut Buffer,
+    href_context: &Option<HrefContext<'_, '_, '_>>,
+    pending_elems: &mut Vec<(&str, Option<Class>)>,
+    current_class: &mut Option<Class>,
+    closing_tags: &[(&str, Class)],
+) {
+    if pending_elems.is_empty() {
+        return;
+    }
+    let mut done = false;
+    if let Some((_, parent_class)) = closing_tags.last() {
+        if can_merge(*current_class, Some(*parent_class), "") {
+            for (text, class) in pending_elems.iter() {
+                string(out, Escape(text), *class, &href_context, false);
+            }
+            done = true;
+        }
+    }
+    if !done {
+        // We only want to "open" the tag ourselves if we have more than one pending and if the current
+        // parent tag is not the same as our pending content.
+        let open_tag_ourselves = pending_elems.len() > 1;
+        let close_tag = if open_tag_ourselves {
+            enter_span(out, current_class.unwrap(), &href_context)
+        } else {
+            ""
+        };
+        for (text, class) in pending_elems.iter() {
+            string(out, Escape(text), *class, &href_context, !open_tag_ourselves);
+        }
+        if open_tag_ourselves {
+            exit_span(out, close_tag);
+        }
+    }
+    pending_elems.clear();
+    *current_class = None;
+}
+
+/// Check if two `Class` can be merged together. In the following rules, "unclassified" means `None`
+/// basically (since it's `Option<Class>`). The following rules apply:
+///
+/// * If two `Class` have the same variant, then they can be merged.
+/// * If the other `Class` is unclassified and only contains white characters (backline,
+///   whitespace, etc), it can be merged.
+/// * `Class::Ident` is considered the same as unclassified (because it doesn't have an associated
+///    CSS class).
+fn can_merge(class1: Option<Class>, class2: Option<Class>, text: &str) -> bool {
+    match (class1, class2) {
+        (Some(c1), Some(c2)) => c1.is_equal_to(c2),
+        (Some(Class::Ident(_)), None) | (None, Some(Class::Ident(_))) => true,
+        (Some(_), None) | (None, Some(_)) => text.trim().is_empty(),
+        _ => false,
+    }
+}
+
 /// Convert the given `src` source code into HTML by adding classes for highlighting.
 ///
 /// This code is used to render code blocks (in the documentation) as well as the source code pages.
@@ -130,7 +194,15 @@ fn write_code(
 ) {
     // This replace allows to fix how the code source with DOS backline characters is displayed.
     let src = src.replace("\r\n", "\n");
-    let mut closing_tags: Vec<&'static str> = Vec::new();
+    // It contains the closing tag and the associated `Class`.
+    let mut closing_tags: Vec<(&'static str, Class)> = Vec::new();
+    // The following two variables are used to group HTML elements with same `class` attributes
+    // to reduce the DOM size.
+    let mut current_class: Option<Class> = None;
+    // We need to keep the `Class` for each element because it could contain a `Span` which is
+    // used to generate links.
+    let mut pending_elems: Vec<(&str, Option<Class>)> = Vec::new();
+
     Classifier::new(
         &src,
         href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP),
@@ -138,15 +210,48 @@ fn write_code(
     )
     .highlight(&mut |highlight| {
         match highlight {
-            Highlight::Token { text, class } => string(out, Escape(text), class, &href_context),
+            Highlight::Token { text, class } => {
+                // If the two `Class` are different, time to flush the current content and start
+                // a new one.
+                if !can_merge(current_class, class, text) {
+                    write_pending_elems(
+                        out,
+                        &href_context,
+                        &mut pending_elems,
+                        &mut current_class,
+                        &closing_tags,
+                    );
+                    current_class = class.map(Class::dummy);
+                } else if current_class.is_none() {
+                    current_class = class.map(Class::dummy);
+                }
+                pending_elems.push((text, class));
+            }
             Highlight::EnterSpan { class } => {
-                closing_tags.push(enter_span(out, class, &href_context))
+                // We flush everything just in case...
+                write_pending_elems(
+                    out,
+                    &href_context,
+                    &mut pending_elems,
+                    &mut current_class,
+                    &closing_tags,
+                );
+                closing_tags.push((enter_span(out, class, &href_context), class))
             }
             Highlight::ExitSpan => {
-                exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan"))
+                // We flush everything just in case...
+                write_pending_elems(
+                    out,
+                    &href_context,
+                    &mut pending_elems,
+                    &mut current_class,
+                    &closing_tags,
+                );
+                exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan").0)
             }
         };
     });
+    write_pending_elems(out, &href_context, &mut pending_elems, &mut current_class, &closing_tags);
 }
 
 fn write_footer(out: &mut Buffer, playground_button: Option<&str>) {
@@ -160,15 +265,15 @@ enum Class {
     DocComment,
     Attribute,
     KeyWord,
-    // Keywords that do pointer/reference stuff.
+    /// Keywords that do pointer/reference stuff.
     RefKeyWord,
     Self_(Span),
-    Op,
     Macro(Span),
     MacroNonTerminal,
     String,
     Number,
     Bool,
+    /// `Ident` isn't rendered in the HTML but we still need it for the `Span` it contains.
     Ident(Span),
     Lifetime,
     PreludeTy,
@@ -178,6 +283,31 @@ enum Class {
 }
 
 impl Class {
+    /// It is only looking at the variant, not the variant content.
+    ///
+    /// It is used mostly to group multiple similar HTML elements into one `<span>` instead of
+    /// multiple ones.
+    fn is_equal_to(self, other: Self) -> bool {
+        match (self, other) {
+            (Self::Self_(_), Self::Self_(_))
+            | (Self::Macro(_), Self::Macro(_))
+            | (Self::Ident(_), Self::Ident(_))
+            | (Self::Decoration(_), Self::Decoration(_)) => true,
+            (x, y) => x == y,
+        }
+    }
+
+    /// If `self` contains a `Span`, it'll be replaced with `DUMMY_SP` to prevent creating links
+    /// on "empty content" (because of the attributes merge).
+    fn dummy(self) -> Self {
+        match self {
+            Self::Self_(_) => Self::Self_(DUMMY_SP),
+            Self::Macro(_) => Self::Macro(DUMMY_SP),
+            Self::Ident(_) => Self::Ident(DUMMY_SP),
+            s => s,
+        }
+    }
+
     /// Returns the css class expected by rustdoc for each `Class`.
     fn as_html(self) -> &'static str {
         match self {
@@ -187,13 +317,12 @@ fn as_html(self) -> &'static str {
             Class::KeyWord => "kw",
             Class::RefKeyWord => "kw-2",
             Class::Self_(_) => "self",
-            Class::Op => "op",
             Class::Macro(_) => "macro",
             Class::MacroNonTerminal => "macro-nonterminal",
             Class::String => "string",
             Class::Number => "number",
             Class::Bool => "bool-val",
-            Class::Ident(_) => "ident",
+            Class::Ident(_) => "",
             Class::Lifetime => "lifetime",
             Class::PreludeTy => "prelude-ty",
             Class::PreludeVal => "prelude-val",
@@ -212,7 +341,6 @@ fn get_span(self) -> Option<Span> {
             | Self::Attribute
             | Self::KeyWord
             | Self::RefKeyWord
-            | Self::Op
             | Self::MacroNonTerminal
             | Self::String
             | Self::Number
@@ -516,7 +644,7 @@ fn advance(
             // or a reference or pointer type. Unless, of course, it looks like
             // a logical and or a multiplication operator: `&&` or `* `.
             TokenKind::Star => match self.tokens.peek() {
-                Some((TokenKind::Whitespace, _)) => Class::Op,
+                Some((TokenKind::Whitespace, _)) => return no_highlight(sink),
                 Some((TokenKind::Ident, "mut")) => {
                     self.next();
                     sink(Highlight::Token { text: "*mut", class: Some(Class::RefKeyWord) });
@@ -532,15 +660,15 @@ fn advance(
             TokenKind::And => match self.tokens.peek() {
                 Some((TokenKind::And, _)) => {
                     self.next();
-                    sink(Highlight::Token { text: "&&", class: Some(Class::Op) });
+                    sink(Highlight::Token { text: "&&", class: None });
                     return;
                 }
                 Some((TokenKind::Eq, _)) => {
                     self.next();
-                    sink(Highlight::Token { text: "&=", class: Some(Class::Op) });
+                    sink(Highlight::Token { text: "&=", class: None });
                     return;
                 }
-                Some((TokenKind::Whitespace, _)) => Class::Op,
+                Some((TokenKind::Whitespace, _)) => return no_highlight(sink),
                 Some((TokenKind::Ident, "mut")) => {
                     self.next();
                     sink(Highlight::Token { text: "&mut", class: Some(Class::RefKeyWord) });
@@ -553,7 +681,7 @@ fn advance(
             TokenKind::Eq => match lookahead {
                 Some(TokenKind::Eq) => {
                     self.next();
-                    sink(Highlight::Token { text: "==", class: Some(Class::Op) });
+                    sink(Highlight::Token { text: "==", class: None });
                     return;
                 }
                 Some(TokenKind::Gt) => {
@@ -561,7 +689,7 @@ fn advance(
                     sink(Highlight::Token { text: "=>", class: None });
                     return;
                 }
-                _ => Class::Op,
+                _ => return no_highlight(sink),
             },
             TokenKind::Minus if lookahead == Some(TokenKind::Gt) => {
                 self.next();
@@ -578,7 +706,7 @@ fn advance(
             | TokenKind::Percent
             | TokenKind::Bang
             | TokenKind::Lt
-            | TokenKind::Gt => Class::Op,
+            | TokenKind::Gt => return no_highlight(sink),
 
             // Miscellaneous, no highlighting.
             TokenKind::Dot
@@ -633,7 +761,7 @@ fn advance(
             TokenKind::CloseBracket => {
                 if self.in_attribute {
                     self.in_attribute = false;
-                    sink(Highlight::Token { text: "]", class: None });
+                    sink(Highlight::Token { text: "]", class: Some(Class::Attribute) });
                     sink(Highlight::ExitSpan);
                     return;
                 }
@@ -704,7 +832,7 @@ fn enter_span(
     klass: Class,
     href_context: &Option<HrefContext<'_, '_, '_>>,
 ) -> &'static str {
-    string_without_closing_tag(out, "", Some(klass), href_context).expect(
+    string_without_closing_tag(out, "", Some(klass), href_context, true).expect(
         "internal error: enter_span was called with Some(klass) but did not return a \
             closing HTML tag",
     )
@@ -736,8 +864,10 @@ fn string<T: Display>(
     text: T,
     klass: Option<Class>,
     href_context: &Option<HrefContext<'_, '_, '_>>,
+    open_tag: bool,
 ) {
-    if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context) {
+    if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context, open_tag)
+    {
         out.write_str(closing_tag);
     }
 }
@@ -756,6 +886,7 @@ fn string_without_closing_tag<T: Display>(
     text: T,
     klass: Option<Class>,
     href_context: &Option<HrefContext<'_, '_, '_>>,
+    open_tag: bool,
 ) -> Option<&'static str> {
     let Some(klass) = klass
     else {
@@ -764,6 +895,10 @@ fn string_without_closing_tag<T: Display>(
     };
     let Some(def_span) = klass.get_span()
     else {
+        if !open_tag {
+            write!(out, "{}", text);
+            return None;
+        }
         write!(out, "<span class=\"{}\">{}", klass.as_html(), text);
         return Some("</span>");
     };
@@ -787,6 +922,7 @@ fn string_without_closing_tag<T: Display>(
             path
         });
     }
+
     if let Some(href_context) = href_context {
         if let Some(href) =
             href_context.context.shared.span_correspondance_map.get(&def_span).and_then(|href| {
@@ -815,12 +951,33 @@ fn string_without_closing_tag<T: Display>(
                 }
             })
         {
-            write!(out, "<a class=\"{}\" href=\"{}\">{}", klass.as_html(), href, text_s);
+            if !open_tag {
+                // We're already inside an element which has the same klass, no need to give it
+                // again.
+                write!(out, "<a href=\"{}\">{}", href, text_s);
+            } else {
+                let klass_s = klass.as_html();
+                if klass_s.is_empty() {
+                    write!(out, "<a href=\"{}\">{}", href, text_s);
+                } else {
+                    write!(out, "<a class=\"{}\" href=\"{}\">{}", klass_s, href, text_s);
+                }
+            }
             return Some("</a>");
         }
     }
-    write!(out, "<span class=\"{}\">{}", klass.as_html(), text_s);
-    Some("</span>")
+    if !open_tag {
+        write!(out, "{}", text_s);
+        return None;
+    }
+    let klass_s = klass.as_html();
+    if klass_s.is_empty() {
+        write!(out, "{}", text_s);
+        Some("")
+    } else {
+        write!(out, "<span class=\"{}\">{}", klass_s, text_s);
+        Some("</span>")
+    }
 }
 
 #[cfg(test)]
index 45f567880c9d9af7efa06de44e76901cdea480ed..2184897872153b6fb7573a0292ffb3c6973738d8 100644 (file)
@@ -1,2 +1,2 @@
-<span class="example"><span class="kw">let</span> <span class="ident">x</span> <span class="op">=</span> <span class="number">1</span>;</span>
-<span class="kw">let</span> <span class="ident">y</span> <span class="op">=</span> <span class="number">2</span>;
\ No newline at end of file
+<span class="example"><span class="kw">let </span>x = <span class="number">1</span>;</span>
+<span class="kw">let </span>y = <span class="number">2</span>;
\ No newline at end of file
index 1c8dbffe78c22d5be893faab966293ae177716a3..30b50ca7c662c23a5e6b2ba69d2fcc9e41b0c45b 100644 (file)
@@ -1,3 +1,3 @@
-<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">foo</span>() {
+<span class="kw">pub fn </span>foo() {
 <span class="macro">println!</span>(<span class="string">&quot;foo&quot;</span>);
 }
index abc2db1790c535ff2ec97fd972dc19afce84315d..9f73e03f95e41440025db3435d6df38b159d849c 100644 (file)
@@ -1,4 +1,4 @@
-<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::a::foo</span>;
-<span class="kw">use</span> <span class="ident"><span class="self">self</span>::whatever</span>;
-<span class="kw">let</span> <span class="ident">x</span> <span class="op">=</span> <span class="ident"><span class="kw">super</span>::b::foo</span>;
-<span class="kw">let</span> <span class="ident">y</span> <span class="op">=</span> <span class="ident"><span class="self">Self</span>::whatever</span>;
\ No newline at end of file
+<span class="kw">use </span><span class="kw">crate</span>::a::foo;
+<span class="kw">use </span><span class="self">self</span>::whatever;
+<span class="kw">let </span>x = <span class="kw">super</span>::b::foo;
+<span class="kw">let </span>y = <span class="self">Self</span>::whatever;
\ No newline at end of file
index b117a12e39f4a45bf1e0938ce9f4eb51e1d13e1c..ae2650528eb723c742f598f3e5cd77ff0128fb23 100644 (file)
@@ -8,30 +8,30 @@
 .lifetime { color: #B76514; }
 .question-mark { color: #ff9011; }
 </style>
-<pre><code><span class="attribute">#![<span class="ident">crate_type</span> <span class="op">=</span> <span class="string">&quot;lib&quot;</span>]</span>
+<pre><code><span class="attribute">#![crate_type = <span class="string">&quot;lib&quot;</span>]</span>
 
-<span class="kw">use</span> <span class="ident">std::path</span>::{<span class="ident">Path</span>, <span class="ident">PathBuf</span>};
+<span class="kw">use </span>std::path::{Path, PathBuf};
 
-<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">target_os</span> <span class="op">=</span> <span class="string">&quot;linux&quot;</span>)]</span>
-<span class="kw">fn</span> <span class="ident">main</span>() -&gt; () {
-    <span class="kw">let</span> <span class="ident">foo</span> <span class="op">=</span> <span class="bool-val">true</span> <span class="op">&amp;&amp;</span> <span class="bool-val">false</span> <span class="op">|</span><span class="op">|</span> <span class="bool-val">true</span>;
-    <span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">*const</span> () <span class="op">=</span> <span class="number">0</span>;
-    <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="ident">foo</span>;
-    <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="op">&amp;&amp;</span><span class="ident">foo</span>;
-    <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="kw-2">*</span><span class="ident">foo</span>;
-    <span class="macro">mac!</span>(<span class="ident">foo</span>, <span class="kw-2">&amp;mut</span> <span class="ident">bar</span>);
-    <span class="macro">assert!</span>(<span class="self">self</span>.<span class="ident">length</span> <span class="op">&lt;</span> <span class="ident">N</span> <span class="op">&amp;&amp;</span> <span class="ident">index</span> <span class="op">&lt;</span><span class="op">=</span> <span class="self">self</span>.<span class="ident">length</span>);
-    <span class="ident">::std::env::var</span>(<span class="string">&quot;gateau&quot;</span>).<span class="ident">is_ok</span>();
-    <span class="attribute">#[<span class="ident">rustfmt::skip</span>]</span>
-    <span class="kw">let</span> <span class="ident">s</span>:<span class="ident">std::path::PathBuf</span> <span class="op">=</span> <span class="ident">std::path::PathBuf::new</span>();
-    <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">s</span> <span class="op">=</span> <span class="ident">String::new</span>();
+<span class="attribute">#[cfg(target_os = <span class="string">&quot;linux&quot;</span>)]</span>
+<span class="kw">fn </span>main() -&gt; () {
+    <span class="kw">let </span>foo = <span class="bool-val">true </span>&amp;&amp; <span class="bool-val">false </span>|| <span class="bool-val">true</span>;
+    <span class="kw">let _</span>: <span class="kw-2">*const </span>() = <span class="number">0</span>;
+    <span class="kw">let _ </span>= <span class="kw-2">&amp;</span>foo;
+    <span class="kw">let _ </span>= &amp;&amp;foo;
+    <span class="kw">let _ </span>= <span class="kw-2">*</span>foo;
+    <span class="macro">mac!</span>(foo, <span class="kw-2">&amp;mut </span>bar);
+    <span class="macro">assert!</span>(<span class="self">self</span>.length &lt; N &amp;&amp; index &lt;= <span class="self">self</span>.length);
+    ::std::env::var(<span class="string">&quot;gateau&quot;</span>).is_ok();
+    <span class="attribute">#[rustfmt::skip]</span>
+    <span class="kw">let </span>s:std::path::PathBuf = std::path::PathBuf::new();
+    <span class="kw">let </span><span class="kw-2">mut </span>s = String::new();
 
-    <span class="kw">match</span> <span class="kw-2">&amp;</span><span class="ident">s</span> {
-        <span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">x</span> =&gt; {}
+    <span class="kw">match </span><span class="kw-2">&amp;</span>s {
+        <span class="kw-2">ref mut </span>x =&gt; {}
     }
 }
 
-<span class="macro">macro_rules!</span> <span class="ident">bar</span> {
-    (<span class="macro-nonterminal">$</span><span class="macro-nonterminal">foo</span>:<span class="ident">tt</span>) =&gt; {};
+<span class="macro">macro_rules!</span> bar {
+    (<span class="macro-nonterminal">$foo</span>:tt) =&gt; {};
 }
 </code></pre>
index c0acf31a05d08ff7e6536efb43fb63b114076b65..9f8915282642dd8bf78d41f9a67b99c09a5dd151 100644 (file)
@@ -1,8 +1,8 @@
-<span class="kw">union</span> <span class="ident">Foo</span> {
-    <span class="ident">i</span>: <span class="ident">i8</span>,
-    <span class="ident">u</span>: <span class="ident">i8</span>,
+<span class="kw">union </span>Foo {
+    i: i8,
+    u: i8,
 }
 
-<span class="kw">fn</span> <span class="ident">main</span>() {
-    <span class="kw">let</span> <span class="ident">union</span> <span class="op">=</span> <span class="number">0</span>;
+<span class="kw">fn </span>main() {
+    <span class="kw">let </span>union = <span class="number">0</span>;
 }
index 2ed7a6f1bb144511d97aefabba047ff5423bff80..6f029c66c0b7dfa9e1752ceb7a796298e67c78f8 100644 (file)
@@ -301,13 +301,10 @@ fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<NameDoc
     /// may happen, for example, with externally inlined items where the source
     /// of their crate documentation isn't known.
     pub(super) fn src_href(&self, item: &clean::Item) -> Option<String> {
-        self.href_from_span(item.span(self.tcx()), true)
+        self.href_from_span(item.span(self.tcx())?, true)
     }
 
     pub(crate) fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option<String> {
-        if span.is_dummy() {
-            return None;
-        }
         let mut root = self.root_path();
         let mut path = String::new();
         let cnum = span.cnum(self.sess());
index 09c54969ef1228e7281901ba6dc629af0563fed4..5ed5299e09bc0e537210c1588f0d42005f556f48 100644 (file)
@@ -2677,7 +2677,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
         let contents = match fs::read_to_string(&path) {
             Ok(contents) => contents,
             Err(err) => {
-                let span = item.span(tcx).inner();
+                let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner());
                 tcx.sess
                     .span_err(span, &format!("failed to read file {}: {}", path.display(), err));
                 return false;
index f508808a8b6f5c3fae86e527563c80522d11f516..f37c54e42983f09dfb369718a473cfdb1a8a12a4 100644 (file)
@@ -53,6 +53,7 @@ impl LocalSourcesCollector<'_, '_> {
     fn add_local_source(&mut self, item: &clean::Item) {
         let sess = self.tcx.sess;
         let span = item.span(self.tcx);
+        let Some(span) = span else { return };
         // skip all synthetic "files"
         if !is_real_and_local(span, sess) {
             return;
@@ -109,6 +110,7 @@ fn visit_item(&mut self, item: &clean::Item) {
 
         let tcx = self.cx.tcx();
         let span = item.span(tcx);
+        let Some(span) = span else { return };
         let sess = tcx.sess;
 
         // If we're not rendering sources, there's nothing to do.
index 39a4dae3348c15032d1871d09fd9d0f5d349f6c3..4dfb64abbebe8d8edf090e23cb0003e86a4ceb95 100644 (file)
@@ -238,7 +238,7 @@ details.rustdoc-toggle > summary::before {
 pre.rust .number, pre.rust .string { color: #b8cc52; }
 pre.rust .kw, pre.rust .kw-2, pre.rust .prelude-ty,
 pre.rust .bool-val, pre.rust .prelude-val,
-pre.rust .op, pre.rust .lifetime { color: #ff7733; }
+pre.rust .lifetime { color: #ff7733; }
 pre.rust .macro, pre.rust .macro-nonterminal { color: #a37acc; }
 pre.rust .question-mark {
        color: #ff9011;
@@ -250,9 +250,6 @@ pre.rust .self {
 pre.rust .attribute {
        color: #e6e1cf;
 }
-pre.rust .attribute .ident, pre.rust .attribute .op {
-       color: #e6e1cf;
-}
 
 .example-wrap > pre.line-number {
        color: #5c67736e;
@@ -398,8 +395,7 @@ pre.rust .comment {}
 .block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,
 .content .fnname {}
 pre.rust .kw {}
-pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,
-pre.rust .attribute .ident {}
+pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute {}
 .content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype {}
 pre.rust .doccomment {}
 .stab.deprecated {}
index 6188e0ac0a9d3c04cadc39a26d431850d11d2117..39f83c998082700c1a66db52569266fec9c30298 100644 (file)
@@ -202,7 +202,7 @@ pre.rust .kw { color: #ab8ac1; }
 pre.rust .kw-2, pre.rust .prelude-ty { color: #769acb; }
 pre.rust .number, pre.rust .string { color: #83a300; }
 pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
-pre.rust .attribute, pre.rust .attribute .ident { color: #ee6868; }
+pre.rust .attribute { color: #ee6868; }
 pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
 pre.rust .lifetime { color: #d97f26; }
 pre.rust .question-mark {
index fba790b619371e4b23fd7605a6d063b289501c21..5698088c790bba5e87a773428668f5fab2d4a79b 100644 (file)
@@ -184,7 +184,7 @@ pre.rust .kw { color: #8959A8; }
 pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
 pre.rust .number, pre.rust .string { color: #718C00; }
 pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
-pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
+pre.rust .attribute { color: #C82829; }
 pre.rust .comment { color: #8E908C; }
 pre.rust .doccomment { color: #4D4D4C; }
 pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
index 4c21fd553289bd2a6066e8d01e86cf82b5483dbb..5f3793ead42baf7d6aa98cb10fa89eb7368854ab 100644 (file)
@@ -59,7 +59,7 @@ pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
             id: from_item_id_with_name(item_id, self.tcx, name),
             crate_id: item_id.krate().as_u32(),
             name: name.map(|sym| sym.to_string()),
-            span: self.convert_span(span),
+            span: span.and_then(|span| self.convert_span(span)),
             visibility: self.convert_visibility(visibility),
             docs,
             attrs,
@@ -428,10 +428,8 @@ fn from_tcx(bound: clean::GenericBound, tcx: TyCtxt<'_>) -> Self {
         use clean::GenericBound::*;
         match bound {
             TraitBound(clean::PolyTrait { trait_, generic_params }, modifier) => {
-                // FIXME: should `trait_` be a clean::Path equivalent in JSON?
-                let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
                 GenericBound::TraitBound {
-                    trait_,
+                    trait_: trait_.into_tcx(tcx),
                     generic_params: generic_params.into_tcx(tcx),
                     modifier: from_trait_bound_modifier(modifier),
                 }
@@ -460,12 +458,7 @@ fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
         };
 
         match ty {
-            clean::Type::Path { path } => Type::ResolvedPath {
-                name: path.whole_name(),
-                id: from_item_id(path.def_id().into(), tcx),
-                args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
-                param_names: Vec::new(),
-            },
+            clean::Type::Path { path } => Type::ResolvedPath(path.into_tcx(tcx)),
             clean::Type::DynTrait(bounds, lt) => Type::DynTrait(DynTrait {
                 lifetime: lt.map(convert_lifetime),
                 traits: bounds.into_tcx(tcx),
@@ -487,16 +480,22 @@ fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
                 mutable: mutability == ast::Mutability::Mut,
                 type_: Box::new((*type_).into_tcx(tcx)),
             },
-            QPath { assoc, self_type, trait_, .. } => {
-                // FIXME: should `trait_` be a clean::Path equivalent in JSON?
-                let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
-                Type::QualifiedPath {
-                    name: assoc.name.to_string(),
-                    args: Box::new(assoc.args.clone().into_tcx(tcx)),
-                    self_type: Box::new((*self_type).into_tcx(tcx)),
-                    trait_: Box::new(trait_),
-                }
-            }
+            QPath { assoc, self_type, trait_, .. } => Type::QualifiedPath {
+                name: assoc.name.to_string(),
+                args: Box::new(assoc.args.clone().into_tcx(tcx)),
+                self_type: Box::new((*self_type).into_tcx(tcx)),
+                trait_: trait_.into_tcx(tcx),
+            },
+        }
+    }
+}
+
+impl FromWithTcx<clean::Path> for Path {
+    fn from_tcx(path: clean::Path, tcx: TyCtxt<'_>) -> Path {
+        Path {
+            name: path.whole_name(),
+            id: from_item_id(path.def_id().into(), tcx),
+            args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
         }
     }
 }
@@ -565,10 +564,7 @@ fn from_tcx(
         clean::PolyTrait { trait_, generic_params }: clean::PolyTrait,
         tcx: TyCtxt<'_>,
     ) -> Self {
-        PolyTrait {
-            trait_: clean::Type::Path { path: trait_ }.into_tcx(tcx),
-            generic_params: generic_params.into_tcx(tcx),
-        }
+        PolyTrait { trait_: trait_.into_tcx(tcx), generic_params: generic_params.into_tcx(tcx) }
     }
 }
 
@@ -576,8 +572,6 @@ 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, polarity, kind } = impl_;
-        // FIXME: should `trait_` be a clean::Path equivalent in JSON?
-        let trait_ = trait_.map(|path| clean::Type::Path { path }.into_tcx(tcx));
         // FIXME: use something like ImplKind in JSON?
         let (synthetic, blanket_impl) = match kind {
             clean::ImplKind::Normal | clean::ImplKind::FakeVaradic => (false, None),
@@ -595,7 +589,7 @@ fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
                 .into_iter()
                 .map(|x| x.to_string())
                 .collect(),
-            trait_,
+            trait_: trait_.map(|path| path.into_tcx(tcx)),
             for_: for_.into_tcx(tcx),
             items: ids(items, tcx),
             negative: negative_polarity,
index 0fe720e70cf0fe37dec340cc3810e6ffb7df3e33..8aede1e77a27497d8112101ededd6f4a0c95ce69 100644 (file)
@@ -8,7 +8,6 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(drain_filter)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(test)]
 #![feature(never_type)]
index 4c6e3eb040d270cc061b8e49f01909b80ca91f8d..48835abf9525b46b0e69be8cbbc51430b577761c 100644 (file)
@@ -215,7 +215,6 @@ fn visit_item(&mut self, i: &clean::Item) {
                     None,
                 );
 
-                let filename = i.span(self.ctx.tcx).filename(self.ctx.sess());
                 let has_doc_example = tests.found_tests != 0;
                 // The `expect_def_id()` should be okay because `local_def_id_to_hir_id`
                 // would presumably panic if a fake `DefIndex` were passed.
@@ -261,13 +260,16 @@ fn visit_item(&mut self, i: &clean::Item) {
                 let should_have_docs = !should_be_ignored
                     && (level != lint::Level::Allow || matches!(source, LintLevelSource::Default));
 
-                debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename);
-                self.items.entry(filename).or_default().count_item(
-                    has_docs,
-                    has_doc_example,
-                    should_have_doc_example(self.ctx, i),
-                    should_have_docs,
-                );
+                if let Some(span) = i.span(self.ctx.tcx) {
+                    let filename = span.filename(self.ctx.sess());
+                    debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename);
+                    self.items.entry(filename).or_default().count_item(
+                        has_docs,
+                        has_doc_example,
+                        should_have_doc_example(self.ctx, i),
+                        should_have_docs,
+                    );
+                }
             }
         }
 
index 3f069e8393f7e9667bfea7a05834ea86f21e0ee8..83ed3752a824cd541aa608be7c46fb97b1d234c3 100644 (file)
@@ -88,7 +88,17 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
             }
 
             // handled in the `strip-priv-imports` pass
-            clean::ExternCrateItem { .. } | clean::ImportItem(..) => {}
+            clean::ExternCrateItem { .. } => {}
+            clean::ImportItem(ref imp) => {
+                // Because json doesn't inline imports from private modules, we need to mark
+                // the imported item as retained so it's impls won't be stripped.i
+                //
+                // FIXME: Is it necessary to check for json output here: See
+                // https://github.com/rust-lang/rust/pull/100325#discussion_r941495215
+                if let Some(did) = imp.source.did && self.is_json_output {
+                    self.retained.insert(did.into());
+                }
+            }
 
             clean::ImplItem(..) => {}
 
index ecdecadd2efb560833a9dc7d0bb466b4b36c9bc1..7dcad66b1f992b8df236aa0c59e23d7f275f622c 100644 (file)
@@ -9,7 +9,7 @@
 use serde::{Deserialize, Serialize};
 
 /// rustdoc format-version.
-pub const FORMAT_VERSION: u32 = 17;
+pub const FORMAT_VERSION: u32 = 18;
 
 /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
 /// about the language items in the local crate, as well as info about external items to allow
@@ -133,7 +133,7 @@ pub struct DynTrait {
 /// A trait and potential HRTBs
 pub struct PolyTrait {
     #[serde(rename = "trait")]
-    pub trait_: Type,
+    pub trait_: Path,
     /// Used for Higher-Rank Trait Bounds (HRTBs)
     /// ```text
     /// dyn for<'a> Fn() -> &'a i32"
@@ -447,7 +447,7 @@ pub enum WherePredicate {
 pub enum GenericBound {
     TraitBound {
         #[serde(rename = "trait")]
-        trait_: Type,
+        trait_: Path,
         /// Used for Higher-Rank Trait Bounds (HRTBs)
         /// ```text
         /// where F: for<'a, 'b> Fn(&'a u8, &'b u8)
@@ -481,12 +481,7 @@ pub enum Term {
 #[serde(tag = "kind", content = "inner")]
 pub enum Type {
     /// Structs, enums, and traits
-    ResolvedPath {
-        name: String,
-        id: Id,
-        args: Option<Box<GenericArgs>>,
-        param_names: Vec<GenericBound>,
-    },
+    ResolvedPath(Path),
     DynTrait(DynTrait),
     /// Parameterized types
     Generic(String),
@@ -527,10 +522,24 @@ pub enum Type {
         args: Box<GenericArgs>,
         self_type: Box<Type>,
         #[serde(rename = "trait")]
-        trait_: Box<Type>,
+        trait_: Path,
     },
 }
 
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+pub struct Path {
+    pub name: String,
+    pub id: Id,
+    /// Generic arguments to the type
+    /// ```test
+    /// std::borrow::Cow<'static, str>
+    ///                 ^^^^^^^^^^^^^^
+    ///                 |
+    ///                 this part
+    /// ```
+    pub args: Option<Box<GenericArgs>>,
+}
+
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 pub struct FunctionPointer {
     pub decl: FnDecl,
@@ -574,7 +583,7 @@ pub struct Impl {
     pub generics: Generics,
     pub provided_trait_methods: Vec<String>,
     #[serde(rename = "trait")]
-    pub trait_: Option<Type>,
+    pub trait_: Option<Path>,
     #[serde(rename = "for")]
     pub for_: Type,
     pub items: Vec<Id>,
index aa80d08e084cfab13a2cb06dd4af8e2bac825775..36bb348ae58132a5936397df4ff1b771b7707985 100644 (file)
     "tool is executed."
   ],
   "compiler": {
-    "date": "2022-07-16",
+    "date": "2022-08-09",
     "version": "beta"
   },
   "rustfmt": {
-    "date": "2022-07-21",
+    "date": "2022-08-09",
     "version": "nightly"
   },
   "checksums_sha256": {
-    "dist/2022-07-16/cargo-beta-aarch64-apple-darwin.tar.gz": "d114c9c7d39fa092e291d39eeed2cac5ec67a9d7f1e392014f83629dffd500f6",
-    "dist/2022-07-16/cargo-beta-aarch64-apple-darwin.tar.xz": "d3d0090e4afb944da8ae9b6b5441486e03066e83de69a2a9606a51444e601196",
-    "dist/2022-07-16/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "99d64f68bdbeff55552efe0860a2170db6c0cda155a7a955322d4ccfced2a2e7",
-    "dist/2022-07-16/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "209b0514a99341bdcaf62ad4785b807383aff2572105f143e89fc89f67bea0d4",
-    "dist/2022-07-16/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "6dc3c9f6739418e14d5d505b1f215c12768d9db2cc26912cae09ec75d6a5b336",
-    "dist/2022-07-16/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "741f7d7a55fcab360d6e0d91e0f83bf8ee6aaf19b0e880a7c3e91af22a4d7ca9",
-    "dist/2022-07-16/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "15185b7f4b806cf8dd5e785625df73efa27a5653e8c38476040372f372a11b1f",
-    "dist/2022-07-16/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "0122b5d493383d97d39d6593bd9cc709a1809f29f1713d3553ae242b78047e34",
-    "dist/2022-07-16/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "e3e2b281ff1233f6596b27db8b593252867d7f26c1ce91b779a164234d2cfd86",
-    "dist/2022-07-16/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "0c71da4b8daeab00da01bca07eef363c5a17a03c1eaf48014d3508c7f228e24b",
-    "dist/2022-07-16/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "6bce124d863189178f06cf430466c18d9ba0cd0e42851e18bb38254d00bdad64",
-    "dist/2022-07-16/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "0ae2a35e0e4f2946dd78420b11f17a54a370e15e12367ba29b63e3f087fb0c71",
-    "dist/2022-07-16/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "eee82cd57578eade5cbc07cf3d48be243a4789e6fba6d7db5772038f87e243f9",
-    "dist/2022-07-16/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "e27b8fe73df64a2733002007503995d9f914d16f852d5e643ac539408086435d",
-    "dist/2022-07-16/cargo-beta-i686-pc-windows-gnu.tar.gz": "0aa99ee73efa4940ffd6789f98d3774bf33a3a54c579759b1f9f0e92cb403134",
-    "dist/2022-07-16/cargo-beta-i686-pc-windows-gnu.tar.xz": "244a98bc858d800a1a36018d7b9fbb77471842b9a130301f9dc19e427c336fb2",
-    "dist/2022-07-16/cargo-beta-i686-pc-windows-msvc.tar.gz": "6b19412e037eb918b05e993ab1c62d96da8cbf92b0a9fc1480a76ad2dc331f0f",
-    "dist/2022-07-16/cargo-beta-i686-pc-windows-msvc.tar.xz": "0420980cc9381249bb187c274f42472997e6283acf95bebf1f93b50d5c138942",
-    "dist/2022-07-16/cargo-beta-i686-unknown-linux-gnu.tar.gz": "95d0e17823ee02ebc3d73982e54b96a110afbf97656ed581da0e71e2635cfb51",
-    "dist/2022-07-16/cargo-beta-i686-unknown-linux-gnu.tar.xz": "75a65a917ad25c1927c9c8306e76d13989f1ea42c6ca063269685e33811e1fb1",
-    "dist/2022-07-16/cargo-beta-mips-unknown-linux-gnu.tar.gz": "ac12e969fc6a892621ce9ffa2108a21381033800526d3b0dc6c1dd343b10af09",
-    "dist/2022-07-16/cargo-beta-mips-unknown-linux-gnu.tar.xz": "3be48fe74c14e48c084fe395b9eef153d97fca57dfc12b5a07f2de143c5df4fc",
-    "dist/2022-07-16/cargo-beta-mips64-unknown-linux-gnuabi64.tar.gz": "1727662c7307c3fec52663d356ccc147dd0c2608cd5607f83057a3f2f315e578",
-    "dist/2022-07-16/cargo-beta-mips64-unknown-linux-gnuabi64.tar.xz": "47b32153e287a972d6b7278a7d9b2339d16e8d9a938a42221536d12762d0df92",
-    "dist/2022-07-16/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "14d56231996a7c20e91c204658412142b8288668109d46f3ed9771186937fff5",
-    "dist/2022-07-16/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "83410621415f07b345d6989fd146303594c811449fd5e3c7609158a9404ba236",
-    "dist/2022-07-16/cargo-beta-mipsel-unknown-linux-gnu.tar.gz": "5362caf0bd6af50fc4bd89864beddcc909d1d53d0ce2b4049eca4b9019b9d922",
-    "dist/2022-07-16/cargo-beta-mipsel-unknown-linux-gnu.tar.xz": "6b5007890a41aead77f919ad7ff0fc29c32e460ab3402837ea0e6ded21f2e4c0",
-    "dist/2022-07-16/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "e4c914ef7b6e97aeb437d0fb2100f0fe621519ef8f6bdee98a4b3e731d5626d6",
-    "dist/2022-07-16/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "33a77edf6f85fc2ea790a10c3108811c0ccb22a0c4c0d1e3a6c3ba27c43ab6d9",
-    "dist/2022-07-16/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "85969807dc0d2999fe4dffdb0f8290bfeaf65646cf333924a933adaa4b045d05",
-    "dist/2022-07-16/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "b36b74e1032d6f83da8b18847df80d52fdf3375b2d45140020452e35c2b9af00",
-    "dist/2022-07-16/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "203402c33bb81ed9c176ee7579fde97671b2f32ad5e7fb3200cd1b77f434d52b",
-    "dist/2022-07-16/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "1bf1daa9660d4fe96e7b9d35fde4995e0e12efcdcb0247cb574495d20de080a1",
-    "dist/2022-07-16/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "a5aec71139c49fb950c03bb4b6af19bac0eec2d6ba2520e49c2d1a08eeae36ee",
-    "dist/2022-07-16/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f0c5b7813073502316e25b71ab41eb600baffd8e51d6ad8134bf14aee53820ac",
-    "dist/2022-07-16/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "b64be7c8c471c9b4a2d9380ecf7d23431b1ea255bd080635ba58380a820cbe23",
-    "dist/2022-07-16/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "a0a6f204ce1f38482939caeb2efe645b60760e8b4c7a68ee4edcf51fc93409d7",
-    "dist/2022-07-16/cargo-beta-x86_64-apple-darwin.tar.gz": "9ab770b4d43ca4020c40b2c234867b67d99794945bb274382f69f9d1e4b0d042",
-    "dist/2022-07-16/cargo-beta-x86_64-apple-darwin.tar.xz": "66201509e2d1eb5b447f85b019467a2193fb9d3eaa12df025aff6746a47f49a7",
-    "dist/2022-07-16/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "295bfb182c85aad35fa5c25691acb03c037a28a8178b9b049df88d40176e418b",
-    "dist/2022-07-16/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "c1d4578521feb07b04c38b5431eb93830d518bbee47bb458e8f745a7bbd4b312",
-    "dist/2022-07-16/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "7eda4ebd7d8ade6e62772604bd6fe1a64f7123da1002c22810a752906893429d",
-    "dist/2022-07-16/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "7eb53b58d63c3f11faf58c819da9bf828f47b579904f9cc801a97b044bb7814c",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-freebsd.tar.gz": "cce8a7f5d0e561ab9ede68e535b601396a7a46c2737d01b9c9f008b6cf4b510f",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-freebsd.tar.xz": "c1989f0a6bb75c8ae4fb56fac60c880a62e92dbb225fa86b5383242573e62e9a",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-illumos.tar.gz": "eb5a4e9bd6a2216e4b72afb5bc542d49583a23a3bb3146ef2c02aa9f15887d24",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-illumos.tar.xz": "42c5330ba2ce1b8e4045e7b8671ad1254bc2d6119bc34996467c5956108897f9",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "35fcf80d8cb8bcc5ab413128575bc6a843c145b4b748df2de9cc9697d535fb6b",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "4070423142b86fac1ad312ea74880456343fbfe2f5f73e465993b21f4f019b93",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "4d3adc8d1cc15d45a4e7498965b92b9313cce8fa9a8f1391000d4dbe0258603a",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "2a39a68b74b7a62fb89f4ccbd202679fed65b425c1678451ac268b94c8294228",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-netbsd.tar.gz": "8508973b3595a0b0a65050d761c108119251a57ba3013d4942f65d0f4f634a7a",
-    "dist/2022-07-16/cargo-beta-x86_64-unknown-netbsd.tar.xz": "4309d7b2c2c26e454fee473e0345947b7447b6e107f795ce9d4cedfca3baa199",
-    "dist/2022-07-16/rust-std-beta-aarch64-apple-darwin.tar.gz": "2168776e63da0bb2b6d09e90510f0d481c68d4aaaa1e1cfc79317add45a01d5a",
-    "dist/2022-07-16/rust-std-beta-aarch64-apple-darwin.tar.xz": "bb9a83c1b5468e740a9b444052afe91a3d8d3223acdf1626e4302475f864acdd",
-    "dist/2022-07-16/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "44f00f44ee97a5f05b156a0be66151fefb79452b94b5d764564702194fb84ba1",
-    "dist/2022-07-16/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "b06f7599e3024cea98f90ea4a9dc0fac9d458dcce63aecc2497e2ec15a00eda8",
-    "dist/2022-07-16/rust-std-beta-aarch64-apple-ios.tar.gz": "35d7c8d11aac14f2e4ce3a1e236a8e59642a6be1e474be7d741c0e38ffcb9d5d",
-    "dist/2022-07-16/rust-std-beta-aarch64-apple-ios.tar.xz": "7fef57b2788303b10b267c228b80f6347c437a10dd2b77bea71e7280a11db008",
-    "dist/2022-07-16/rust-std-beta-aarch64-fuchsia.tar.gz": "d83d4186e499853f337513b5603c4cdf287012bc121a33537eb514b2d47e8963",
-    "dist/2022-07-16/rust-std-beta-aarch64-fuchsia.tar.xz": "92d3caab76907cea85fe78c10f902661ea0887c6689888f6eb9fffa2f443339f",
-    "dist/2022-07-16/rust-std-beta-aarch64-linux-android.tar.gz": "82ca00fd9913e2d55bc0ecf06313a2f9004f71c40c44f01b3d7d9cd8d1799fb0",
-    "dist/2022-07-16/rust-std-beta-aarch64-linux-android.tar.xz": "dc7c287887bba704fe988e7f5f7d080aff576de7a214f1dc63ded4fc784eba0b",
-    "dist/2022-07-16/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "fe47ed76b388f7b01d5e3d1d51918beb0f04ca7e015353479f7eff78e49b9794",
-    "dist/2022-07-16/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "0bcece81cf9b81c5ace02459f945b97be181f81704cade21687460f1db00343a",
-    "dist/2022-07-16/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "9f28057d4828f7a07eeefd8eb03c9e807babd86e67443099491421f7c5afa67f",
-    "dist/2022-07-16/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "b21f0deee74041385b7018979e7db1dfd071530f064b1bc500f9281cfafc38cc",
-    "dist/2022-07-16/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "588d6952722ec461de5d0c10c5f01c6d6735740a74b8162e2e2ebb848f9175d4",
-    "dist/2022-07-16/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "c6731bcd0e4e15d79dcdc6f974b5a4f7a379692ad2183c0bfd56e6619d9f0fe1",
-    "dist/2022-07-16/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "588585fd26813de3ae2a8a49c6e6fea5f0f7311911a54c015372010883cf5938",
-    "dist/2022-07-16/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "a5e820bbbf113250c4f814dd0f4aaa9b20b1a7d61613b7157993d25fb0ff3518",
-    "dist/2022-07-16/rust-std-beta-aarch64-unknown-none.tar.gz": "69ec1ef2f456a8cd294ec3f7c485f45401e6f200df9f525419726cf9da60dc60",
-    "dist/2022-07-16/rust-std-beta-aarch64-unknown-none.tar.xz": "b13d0099a55a928dfbfe07d80426e9bd53b6e35cfc6b634ad2ee02174ce42f7a",
-    "dist/2022-07-16/rust-std-beta-arm-linux-androideabi.tar.gz": "a90a4cc72263b96ada453dd3c8443d076ec150ed910ad30f26f825cd668516e9",
-    "dist/2022-07-16/rust-std-beta-arm-linux-androideabi.tar.xz": "0d7c8c13a18888cd7e9613c7d88ef227d9b2034739d0d16507aca28403328b42",
-    "dist/2022-07-16/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "9fcd72dfd5568a3e7023c416720ba4d5e42aa6d425c7ce6feb2ebf1b650d7591",
-    "dist/2022-07-16/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "43efd4e1ca95f54fef097f14483a4f4d96d499c38c5ad3d3a290e02f7c4c4637",
-    "dist/2022-07-16/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "7d2c708aaeb01014856ee7d2c6c4c85883f17fd00fca912aabb93d84170e3e61",
-    "dist/2022-07-16/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "97d3c092fd702dc7df0df83722046371b4d418aabc60fbbf0807ddddf3e7dcda",
-    "dist/2022-07-16/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "74e8fe4152eb12ee8b9d4fd4e3cfe5d506329c94ab515319fb2aaf013bacea5f",
-    "dist/2022-07-16/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "a207d79cf57f3e13b6f85761373a00fa8afde8f513e14a3e0c0a70f40d89e890",
-    "dist/2022-07-16/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "4660ec4d1fe1960e70b54bce58cae6775b8df86c3ecbc96f4df0067dcd90a3cf",
-    "dist/2022-07-16/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "c86a999f7affd8f4d2e0d509cf3e2229a3cd40768ef86b1ac36b5dccbbe56bdf",
-    "dist/2022-07-16/rust-std-beta-armebv7r-none-eabi.tar.gz": "5ecc032c10a8f8d3e1e40256ca7c7e03cc98ae35d56105f70df94a4519412dbb",
-    "dist/2022-07-16/rust-std-beta-armebv7r-none-eabi.tar.xz": "8e2c1c97083aa141d3b31476903a6325fd11f0ae5350909eb0295b8be19eb1f8",
-    "dist/2022-07-16/rust-std-beta-armebv7r-none-eabihf.tar.gz": "e111491ee2412c8d770b0a93fe402566e46c2faa855c71f24da77a989f36ea2a",
-    "dist/2022-07-16/rust-std-beta-armebv7r-none-eabihf.tar.xz": "7c814fece60ece924f5dffff6ee6f1605965841f4b864cd271c5c4f3b3c18042",
-    "dist/2022-07-16/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "0d4e93aa2f04f1d255d319653b3f4c02bd3557cc8227e6be4e0f1769aeadd2a8",
-    "dist/2022-07-16/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "d60246292f63abeb9eb35ddf93901ea9f75cba358a67589595aa1cfc9d35e6aa",
-    "dist/2022-07-16/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "085e236212a908e0e363d78dd3ce8c676cd2dbc8e817601486502389ba8d0734",
-    "dist/2022-07-16/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "654e655cb257dbed0490ec0c75e0cc0b7e35512d4f6f9f5dddc10bab0cd02098",
-    "dist/2022-07-16/rust-std-beta-armv7-linux-androideabi.tar.gz": "10fb120b0269a65f554a592e05ec26703b0888dbeaf06c15b43522b730c943cd",
-    "dist/2022-07-16/rust-std-beta-armv7-linux-androideabi.tar.xz": "470eec8bd47f66409e28eac2b86b5c6c0644531c91135637f667f54edb7fd6a9",
-    "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "520e83ebeb2dd29fea43087399af6227fe90b5a571572322301cc6d9b76f5027",
-    "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "a7527bcd5ee6017de7fde1a6f1d98db831e7bddf5a64b54ce12cadafaa3d560b",
-    "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "bb0ac318b0a5dd972356f4e94789b68caae1a14e5996493a3bed1a579bb1145d",
-    "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "cc1e65bf50246be9d9578487580038a7015f3a61444dc53afb7c4f2afc8181f8",
-    "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "7ff2051b2324f51bf0b3fe7581e1b5e02c4e2fb4075950c36716e8ba783b1b42",
-    "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "d4e32fcf2da983adc8db7043175cded76e56894f136766c5d9afe08ef6f0e766",
-    "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "6f7b86e7b51ba9d8187c61ff0d7a6d28fe65201bc94b94bd5a845490fbcff3e4",
-    "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "3ac410ea3f641b578ec1183856306b1eb4e0d02ba58534df114ab45a91fafd1d",
-    "dist/2022-07-16/rust-std-beta-armv7a-none-eabi.tar.gz": "abe93aa78a72eda2735d2f78cc98ea9b7a50752320d83b70464bac86a4a765ee",
-    "dist/2022-07-16/rust-std-beta-armv7a-none-eabi.tar.xz": "059560de23b47a43800319fc968a5dd34d44ab61f486a8f33a075798c66f0528",
-    "dist/2022-07-16/rust-std-beta-armv7r-none-eabi.tar.gz": "b08a4b0b56d86182e735d5dc6f47083a4f8a0101b4a712e02f14c9f3d1720001",
-    "dist/2022-07-16/rust-std-beta-armv7r-none-eabi.tar.xz": "d65cb28ea5f5cb7e5649a85a591609b5f49c0e3b0d02c1ff8d2b1dc10ea3b4a3",
-    "dist/2022-07-16/rust-std-beta-armv7r-none-eabihf.tar.gz": "cb13a879797483d7a7fd2073be2af0c83f98c4226e81ea0333670eddffc4f77e",
-    "dist/2022-07-16/rust-std-beta-armv7r-none-eabihf.tar.xz": "4965ee9c27d6104f572bcfd19944e19a3f70d58a5d0d215059f2cc52f7bc9c1e",
-    "dist/2022-07-16/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "e8437c9df42118b8607723c1e4f04a7b7a302e9894dc52ab8c212f07964ac994",
-    "dist/2022-07-16/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "b05f10cee7b5c8aeea44689c11ddfe6f266a8779dfb0fa9df51c7c784f9f31a6",
-    "dist/2022-07-16/rust-std-beta-i586-pc-windows-msvc.tar.gz": "65f66e8690c742b13c3371c1af4219d701b66f61e4fd984b1d67bb89d6468566",
-    "dist/2022-07-16/rust-std-beta-i586-pc-windows-msvc.tar.xz": "cabea5fef3004aee4c3108a47fba945f434bd29b4c55250236ec009405e41b36",
-    "dist/2022-07-16/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "8349e67b9760f9c257c745c4d87015bd623e1cf073703429f64400f7dc9c1210",
-    "dist/2022-07-16/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "ee6473059771a8f49ce5ca8f36913a9ef31be3def32c63c5a31f50a896aa565e",
-    "dist/2022-07-16/rust-std-beta-i586-unknown-linux-musl.tar.gz": "7edb1155a5fab3c123e0a847c0397b6c347cd7b4a6a15996d93f45281c2d8eb1",
-    "dist/2022-07-16/rust-std-beta-i586-unknown-linux-musl.tar.xz": "49360ce15d751ef01403459fe3eaa30061160a79e4454eee7f5c63fc65a3666d",
-    "dist/2022-07-16/rust-std-beta-i686-linux-android.tar.gz": "5d62f8e1b15b44998f7b039b7e6ab7deff85ba13130a11309b2541c70834538a",
-    "dist/2022-07-16/rust-std-beta-i686-linux-android.tar.xz": "4b2e1b2835919299113d28eca09b1e12471054786156da0cb63bc0620d6afe00",
-    "dist/2022-07-16/rust-std-beta-i686-pc-windows-gnu.tar.gz": "39a9c3f2392240b29f52ed525f57d548537e7cc7a57438bd84f7efbd85b49811",
-    "dist/2022-07-16/rust-std-beta-i686-pc-windows-gnu.tar.xz": "d8ae971791693c23260b73c8faf94570a1bddbcecfa9c339fbd23682c8cd2bb5",
-    "dist/2022-07-16/rust-std-beta-i686-pc-windows-msvc.tar.gz": "e57020d959cbe2e7331808f425e8d95e5204f4e9c33cdd301c6809aa06ba6d90",
-    "dist/2022-07-16/rust-std-beta-i686-pc-windows-msvc.tar.xz": "35b4504603903e7c753487585fcc75237f4f8a0ee933c52941abaf2c6913e0f0",
-    "dist/2022-07-16/rust-std-beta-i686-unknown-freebsd.tar.gz": "dd5c6dd4fe4bfb1acdda726ac9f6fa0944f745be946ed175a8e3c62c0d4c46f7",
-    "dist/2022-07-16/rust-std-beta-i686-unknown-freebsd.tar.xz": "95a9f3bcce8780522d678822cac8b06ba662112df51afa312f4c7ed76a3987ed",
-    "dist/2022-07-16/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "52b49a92f66cbc2b250a7272f58acfb9732fdb7073baa430b47ff9ebfe0c98a2",
-    "dist/2022-07-16/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "2f6b5de99c83cdd01c44b388ea059d10ee7f0f62ca17547b7a6d8d66fdf349f4",
-    "dist/2022-07-16/rust-std-beta-i686-unknown-linux-musl.tar.gz": "24d81d4d181c86dc02fe5b3fb54c50f78f72f73c2d9c319710d275fb08a53980",
-    "dist/2022-07-16/rust-std-beta-i686-unknown-linux-musl.tar.xz": "32c99f24396601c8a4afb250cda4718d6d5fae57f9534d5c3c3962e4c076d261",
-    "dist/2022-07-16/rust-std-beta-mips-unknown-linux-gnu.tar.gz": "d476561d571d62d31c03b57fd380591acbb809fd4f26873e2ef2e4b3f583da46",
-    "dist/2022-07-16/rust-std-beta-mips-unknown-linux-gnu.tar.xz": "93d3d0511508351f5e3322a3e4360586c2c2bdb60ca0c4aaea4fe5e7da081e92",
-    "dist/2022-07-16/rust-std-beta-mips-unknown-linux-musl.tar.gz": "d8c354f83a5481508a88fa6ced6fb458458678ddfa7814e47415b5daa66b0470",
-    "dist/2022-07-16/rust-std-beta-mips-unknown-linux-musl.tar.xz": "19f272db8772fa7b77cb9d5e1c56a1a2062a6e087b2980131128ab01b025f571",
-    "dist/2022-07-16/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.gz": "775aaac7be36438ce4e8f1cda3926c3540f90fc9b74e387d5e4497227ceaad97",
-    "dist/2022-07-16/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.xz": "bc460e80f4fd82492cc8e66f11320ef22c71fe26a4255606c73c325bbd2f8516",
-    "dist/2022-07-16/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "7ebb73739bafa8f412756575f4033b45629b62a92a35460bb37f3f691640bcc9",
-    "dist/2022-07-16/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "1483cde530d3d50116f4dbcb42a3b22cf7bb04559cc9bebd762f82e8b3ebea40",
-    "dist/2022-07-16/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "a7f813851b5a9c67ba16c80da5b80397db1f4c9b5a10f4877f52b6861b856b1d",
-    "dist/2022-07-16/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "3fd132910d46fb9d769d8697e81b89aff7f739d9b197e4a54b00797e217a0a66",
-    "dist/2022-07-16/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "8ddc74476e1023ee58ee5564d7357082cbba2a7d930abd7c704dbdf49439e2cf",
-    "dist/2022-07-16/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "f773cbcfb9010491f92cbeeccff0dfc8109d4407af4c10269766674a51e84b68",
-    "dist/2022-07-16/rust-std-beta-mipsel-unknown-linux-gnu.tar.gz": "85bebea249c436f016fddef2865850adcb16585cccd6fd4fbd9baf0be971160c",
-    "dist/2022-07-16/rust-std-beta-mipsel-unknown-linux-gnu.tar.xz": "74a519aa2b595b093510b81b0c65b9a864dc2cb3cb4ff5af8619531afd436b8a",
-    "dist/2022-07-16/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "f8dcb0e03629d23715e7cba213b91753d99a9e0ce8b0111e360a8c6e062b9f41",
-    "dist/2022-07-16/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "e2ad66f17aca663689d80e59b6ab854fe27aabda318c0ae41febf9fff700ac7f",
-    "dist/2022-07-16/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "6351ee40b19c7981f9b4aa2900bda8cf6fec04f5953bca78c0f480f885b78425",
-    "dist/2022-07-16/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "8c8f6ca9717ef1f4168d9ac4c4eb0f771149dcbc77ee4ec179031b10f9de13a2",
-    "dist/2022-07-16/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "706d3e633e8fdbc8f672153f16638ed2ade39321beefde054f63864bfac4e9af",
-    "dist/2022-07-16/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "0b7b37b4eee8fcccad684d606aa5b326f60473ed9f567cd2d17def4cbd8c3b63",
-    "dist/2022-07-16/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "40a2572f1a4297bef43708d1dafd1709373a0258f2bbe7914a9f954ca4dbe2f0",
-    "dist/2022-07-16/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "78ebece93dd1b8e6825d6026444484f0beca982d802651149da32b13d8de69c3",
-    "dist/2022-07-16/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "4a362a752fb6270c75fc24dc7cae00a70d4272972b1f0409a0a32582d1293acd",
-    "dist/2022-07-16/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "f1b8eb010818955e3ed21b2b4e3c42180fa817dcc0aa6b75520149fccd2b9d1c",
-    "dist/2022-07-16/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "0eb83977d0fb83eb498ff7858edd3fdfc0a2e40efa859a23b9a03972fd0f0c10",
-    "dist/2022-07-16/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "b39894ecc6fd00b8398b1430285d7876f8955eeae43949e54a45a0e374ad8c37",
-    "dist/2022-07-16/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "402e022a2a7f1eb06e91ba883532b6354e94dbd1314a7ab406f37e56026e6097",
-    "dist/2022-07-16/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "97762f1261461a996626dc922f7d2b9791d38d216e871065d1c9f3fe21dd10e2",
-    "dist/2022-07-16/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "0999c8f23113ed6cdb98f0751779d90fe368d6b322a49506dd5df96e9c00ce0b",
-    "dist/2022-07-16/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "7b289c284b7b53f7f12b05f841be6d6024dc581bbe59abf07402d87f87b78231",
-    "dist/2022-07-16/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "f6a71af82c15e20aa20881fdf0daa5815c2c9589c6fab1a69fade2380c9c740c",
-    "dist/2022-07-16/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "3adc7fd340e08b482259eece4c1abc210ec32f97fe6d5fdf6847ddeebe7e8e10",
-    "dist/2022-07-16/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "2136b39139393e6b9454b0c84a0c25256a444a940b9a6c207fddc7ef2b25a22d",
-    "dist/2022-07-16/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "ec9f3f7c62dd6fcc5339579d5becd5e5542c0eb45b415b91a9a2b6ebde18bd7c",
-    "dist/2022-07-16/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "79e21a41c5400e646f4ff76d8c4c0bea12501338742ce800093ee1e06d0d6932",
-    "dist/2022-07-16/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "f686a014f19efed6d8357d0ff88702779a0132bc412cd1e6eb93b535ebf26686",
-    "dist/2022-07-16/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "45a9dbab6143f10131f702c446768e542180572033811060947d4a1d79a7c2a0",
-    "dist/2022-07-16/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "eefcfb4558b26145aebfafb193420972be8d8e6ca1b8d83a648ab9718cdbf97b",
-    "dist/2022-07-16/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "96e69f7db947588df72b49975b53387a02d102eb1295ecc8712f5cdcf0191ba7",
-    "dist/2022-07-16/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "10c2dfa886225fdcd991db70c0ae077432a9ace7f69c5464222555f1cbe9b51c",
-    "dist/2022-07-16/rust-std-beta-sparcv9-sun-solaris.tar.gz": "254a8a83f480947878a377feb64803e6b396a967e07957513741aa7aa3ef6a07",
-    "dist/2022-07-16/rust-std-beta-sparcv9-sun-solaris.tar.xz": "a18a04dfdcb6fecea8376908114690e0ca5ca54b2aced5e922f463799483d882",
-    "dist/2022-07-16/rust-std-beta-thumbv6m-none-eabi.tar.gz": "643b8d6e5b17aa5ed0696550439039651e178695348dfb11567520e0439091a3",
-    "dist/2022-07-16/rust-std-beta-thumbv6m-none-eabi.tar.xz": "9cb7f0543dfd4f13b6126a6de336a6b11eea9a241cdbbf00290ed0c7a1d331ea",
-    "dist/2022-07-16/rust-std-beta-thumbv7em-none-eabi.tar.gz": "58d094491df31e051e9fc85d4376df165ef103651b676e494beba2b689382254",
-    "dist/2022-07-16/rust-std-beta-thumbv7em-none-eabi.tar.xz": "5e44398411718fb4cd22bc13a5fd091adb23938c2010d45ce63ac0a547435406",
-    "dist/2022-07-16/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "186ac77a1844786df52e5325e9aacd519db8f61ab72cd08376e8af869ce71e22",
-    "dist/2022-07-16/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "737d50c6ad0f0918580b29bdf3cf811f43a49fc5fcfd3b4e5f0cfdfde4acbf15",
-    "dist/2022-07-16/rust-std-beta-thumbv7m-none-eabi.tar.gz": "7e6bb04375764e3c80f2d477b2a982baa170339029a8c3f99caeefb280acd95e",
-    "dist/2022-07-16/rust-std-beta-thumbv7m-none-eabi.tar.xz": "e15af6e720e2b19884a1bfa3b6c2d394082786bf95483b0962ed134d7787161c",
-    "dist/2022-07-16/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "80a32a6988b945861eb834f3bfc0cbbf594a0b2b7cb1594f150e7ac8f2919065",
-    "dist/2022-07-16/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "75f986807dbeb40418b049264334580cf0d324db80e3e86d047d65e6ebb50a2b",
-    "dist/2022-07-16/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "d86a80418c9cc9b883faf2b5e681b530ea09c550fb39b9e558a381ab67d3f43f",
-    "dist/2022-07-16/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "30af6048b67ee64c378250b23227383b799c598aa24e3a09cf50baa4e15a9833",
-    "dist/2022-07-16/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "ed57999629478f3d1efd164249bb471eaf866a95da7c0916572bd0537f40c964",
-    "dist/2022-07-16/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "232f3099d833785dc6e50dadb205ade5440e850ec24821cdd24a534a19b93cb1",
-    "dist/2022-07-16/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "56ea2a0a2ff89efaeb791df36751cd6493161878e281d3dce507f9637044e304",
-    "dist/2022-07-16/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "820b1c2fa96e952a09b32ba0a5a94239bf69ecde2bdcb769d073f35e5ee13383",
-    "dist/2022-07-16/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "a1b9d35ed7346f43025a354c38e5836340c1be3a9b2173845c91afe7bbfadfc4",
-    "dist/2022-07-16/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "e3da59132bdef040b4618037f9d7f0c38511701420a676c9d451544cbfda0ce4",
-    "dist/2022-07-16/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "e92dce094d5c503c3a66c7419f4b2b341a0647678596f6c5ec5ddebaa4107905",
-    "dist/2022-07-16/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "b7a2e4db89f9dde15b51dea0044b57204326898e351fcb45df1da31c5edbe929",
-    "dist/2022-07-16/rust-std-beta-wasm32-unknown-unknown.tar.gz": "608834a5a7d60024e2f7275ac5615d7dc1c1723b2195695eb889dbd633a45e2c",
-    "dist/2022-07-16/rust-std-beta-wasm32-unknown-unknown.tar.xz": "646cbf64202df1f11d829d371810867e12120e12266895125b53600e4d678d26",
-    "dist/2022-07-16/rust-std-beta-wasm32-wasi.tar.gz": "b1802f8dd97e213466bdaaa769ef4b03ea1baf5cd14475edba8b70dd6736b855",
-    "dist/2022-07-16/rust-std-beta-wasm32-wasi.tar.xz": "f47bf0b5aaea9d52deea681b85daab38920db504168fb9a0eeea161996eaf494",
-    "dist/2022-07-16/rust-std-beta-x86_64-apple-darwin.tar.gz": "cd5be7559517ea844335c88e3cd5846990cad18bbb4dd96c1c1add6d873b5ef3",
-    "dist/2022-07-16/rust-std-beta-x86_64-apple-darwin.tar.xz": "3e028523c2a23a5681b6a9f4ed4f4313bbc0295f3f0e986e0c6bffad69454368",
-    "dist/2022-07-16/rust-std-beta-x86_64-apple-ios.tar.gz": "7c18b0d86b4cb7da00139112966e86de05da9286fea72458056dbf1607eab774",
-    "dist/2022-07-16/rust-std-beta-x86_64-apple-ios.tar.xz": "4aeaf6925f7a591a7ff0449d98b1ee5b1fd2fbca93e8bfb7fd2b279ecd2ec2ed",
-    "dist/2022-07-16/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "62ac06824cb70a0b02292ccdca9ae4e2660644fa9a0abb186c73d64e9632c733",
-    "dist/2022-07-16/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "8642bd83f1bf709d38260ee54fbb4de679bbec802d5c72f09e1146e82195577a",
-    "dist/2022-07-16/rust-std-beta-x86_64-fuchsia.tar.gz": "caf561a7b5efb474c9db48dd5ac3ceb32505f60813324b2665fadc639e6103e1",
-    "dist/2022-07-16/rust-std-beta-x86_64-fuchsia.tar.xz": "c6481548b0ef6b9c4a82b1f697842cb7c38176acb06699d559c825243fbbaf4a",
-    "dist/2022-07-16/rust-std-beta-x86_64-linux-android.tar.gz": "be110f47348bc63d27b541af4093167cd48d5f011897482ca7a940abcfeeb1a7",
-    "dist/2022-07-16/rust-std-beta-x86_64-linux-android.tar.xz": "11ccae4e0bfc76df7bd33d858fe47ead9294cd0707aee3f42ac3683a140d583f",
-    "dist/2022-07-16/rust-std-beta-x86_64-pc-solaris.tar.gz": "78d6662fbfb469c7cb0b2f381523ebab1b566edf2dfa676c8a509a6d584e17f2",
-    "dist/2022-07-16/rust-std-beta-x86_64-pc-solaris.tar.xz": "034be03c974835fa0d2747364c8b26f50d83762316d4a266473972622e2627d6",
-    "dist/2022-07-16/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "759eed3f19e2c8203a7b03ab90eedf4b09e0edfff9fea49bcb2fc795aef66a4f",
-    "dist/2022-07-16/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "119c6fbaa021130baa881738164810d7829ee54234e8adb6e82f1f6cba9da876",
-    "dist/2022-07-16/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "b0369c5804ab496b5ae9a2643f5da959e62cf574d394d3a74a06524816bd2fc6",
-    "dist/2022-07-16/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "130b922369beb56a30666dfb6f36881105e5446284f196eef6817939f94f1b02",
-    "dist/2022-07-16/rust-std-beta-x86_64-sun-solaris.tar.gz": "5405406252ab897de56c46023de48c08d03fce7791e7db06c009d10e4c9c03f3",
-    "dist/2022-07-16/rust-std-beta-x86_64-sun-solaris.tar.xz": "b91c6f6dfbe142102a8d72b5c91f8efd1873c20e73e34d9240898a08f63d6be3",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "17526319a486038ef77e7a0f8c1ffbc6e43b4ac3eef4d14c4b70307cbd937c5e",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "8cccb4640373abd1f17418c5b7d5198e8da3af3886206dff559fa2e23c4994e2",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-illumos.tar.gz": "ff3f98720355eede902bc3c12d5ecdfc6e7f53b70133492e26b4cd464ff585f2",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-illumos.tar.xz": "73531fe83d87304fe54adee9ede87e82220afd4dcb5c1a27878a1d9dd7dce9d9",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "936855bb97c47c0978caa65748515e3e7550916beb5d06aa569dab6192738886",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "e8b95205019e5f73e86247da9f5dab22f8ceaa98f6afa8f0eb7c6d92a258b97e",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "2f016727a0d761960923f4a83cce489d2f4d87b354352d109be1e89ad45f99e4",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "16f0829deae2df1fee609dfae7ec51bbcb7da5a9dcfe48f4d517d07934463b42",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "8bb4f4c9bb114cdee7c3d95c78e66f9c574ae47116b3aa0401712eb29c41461f",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "8a4977f3bb54c0f260c4b41f2fc7bf0fb06fd69e6eb9a9c88c438274f7ea993d",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "2b361b36d6a6f917b17a92b68dc9fb80c05e0b90a1987f4761b05ecb970ef4c6",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "5a4069a5ee239d289e13f8071c3fab252dab944706c2e223f763107509730fda",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-none.tar.gz": "d4b0d375705732ac44da55e5272bde7c0756231bed205fabfa5b8b265e0d8e79",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-none.tar.xz": "5d4f05830dc0530d60e0d570e692b0c4d7ee48e68d4bb3838878fead474bc063",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-redox.tar.gz": "c43fb78286169bcdede9e092d84a9f2e7762ad67bdd2ed7a14d6d3234af52b9e",
-    "dist/2022-07-16/rust-std-beta-x86_64-unknown-redox.tar.xz": "905d5a8f6f642a978e55afc45329f6b7b6083a34ec6f51de0bb854685c5e3add",
-    "dist/2022-07-16/rustc-beta-aarch64-apple-darwin.tar.gz": "86afdc287964673c25d3c625b5bf03231d897d46fe8565e1078747e7b85bc627",
-    "dist/2022-07-16/rustc-beta-aarch64-apple-darwin.tar.xz": "8cd87fd24927617793bb06edc581184edfc12de7c961f03a530aee7eb793166f",
-    "dist/2022-07-16/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "6c2858cc584d845ebcb8cc4dbadc5b0bf4e875dd0920b2d9106791b8bb7567e7",
-    "dist/2022-07-16/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "dde2c77b23b8ecedbec8427c3b8f6a889d96b053de74787a73faef366cdb30c1",
-    "dist/2022-07-16/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "5ff5ae57cc7eacf26a3410c499d23e520ed9ef20f7aa50e77a3354a7bbed541f",
-    "dist/2022-07-16/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "850f4456625e7ae545c3036338b5bdcb1982a2fca4d1664efc835630a7e42468",
-    "dist/2022-07-16/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "5409263cbb71867780c8a2bcce126665217632d8eb7e4dab95c199ebfee8755e",
-    "dist/2022-07-16/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "deeeff68790e4857d625fdc1e0ed430e4d31b4e5e87b5534d899cdf7fec2adf5",
-    "dist/2022-07-16/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "0701e5f5d04db2cc677366ec769fa3f6c39351a9527f8493fd54d29086294a00",
-    "dist/2022-07-16/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "a133838e0eb1d9177fe0c052667ba9820a6ba5cbba604a80ad732ca5c1e23846",
-    "dist/2022-07-16/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "9ad3ad6c0c27d50238f83821b526a1d6f598ff293a36381d0a8a28cbd0a7ab4e",
-    "dist/2022-07-16/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "3313866d0d78c82b0b571e889d6ed85fce80dc2ea3dcc495f4738672e8d3b972",
-    "dist/2022-07-16/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "0459cf4a11cc6d41aa95d837b73a339fbf1c50ecfc078a95705c110d03a9c941",
-    "dist/2022-07-16/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "16b092bd7fccc84d6776f8cf3794c302b258fe9b3bf2adcc2ba1551197d3ab92",
-    "dist/2022-07-16/rustc-beta-i686-pc-windows-gnu.tar.gz": "c3c49711e23a87fb78d2a85d4838893963f151918464708f61cbd0a0ef8d6841",
-    "dist/2022-07-16/rustc-beta-i686-pc-windows-gnu.tar.xz": "eac7e88ef96b4eb99d5f15e168c7b782f0c9bfced92e5852559414e4c95a18c4",
-    "dist/2022-07-16/rustc-beta-i686-pc-windows-msvc.tar.gz": "fe6f0c952dccbe7262678615c8a850ce76f510295202427a16755005f3505744",
-    "dist/2022-07-16/rustc-beta-i686-pc-windows-msvc.tar.xz": "bd596d7e1fac9b4e02a036aa1e59819317d210044b3298bf4ec3633817f2ec2b",
-    "dist/2022-07-16/rustc-beta-i686-unknown-linux-gnu.tar.gz": "5dbbdd77e606ad28421a39d9ec95d2254e2658033247d94a733dec05a2368cb5",
-    "dist/2022-07-16/rustc-beta-i686-unknown-linux-gnu.tar.xz": "f9471eb60265b18f755c76dc4786895804fdc2b0ed8c8c8e58a454dbd1eca3b3",
-    "dist/2022-07-16/rustc-beta-mips-unknown-linux-gnu.tar.gz": "e4e8e67a0c4240ccb478631ee3b7a0fcc22d68b2adce26228f5fc9fff34dc03c",
-    "dist/2022-07-16/rustc-beta-mips-unknown-linux-gnu.tar.xz": "c7879912b5b6bfbaea4b424562ac1174bab8e30a4d20b3a82291b606a5a5f09e",
-    "dist/2022-07-16/rustc-beta-mips64-unknown-linux-gnuabi64.tar.gz": "3b437ea0fe1c9f52505cc7e5cfe2b3b103973e3ba3c132ba304d828c210e7eb1",
-    "dist/2022-07-16/rustc-beta-mips64-unknown-linux-gnuabi64.tar.xz": "d1c144f58626f3b0df9a24ffe5db9b2df45a410071df551fec48e0a7097bb17a",
-    "dist/2022-07-16/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "364647a234f7d40095d38cf01fcbdf554128436829d2972cb22f91fde18b346a",
-    "dist/2022-07-16/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "fc2c9200111139a051c8e3bb41f936b2126d24ca91ba175d88de95d59b6e00da",
-    "dist/2022-07-16/rustc-beta-mipsel-unknown-linux-gnu.tar.gz": "884a0da049f646196964f6cf93f03d9211e3864b39190432ee2e369c34051717",
-    "dist/2022-07-16/rustc-beta-mipsel-unknown-linux-gnu.tar.xz": "d82cd504ff34e741c9cf246fd6d8829f8af74d36670de46daea858a2c282f286",
-    "dist/2022-07-16/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "0fdd190eec39c72972d8d4df7fb59c77ffd9e9fad4d219264b6ceaa301c0250f",
-    "dist/2022-07-16/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "e74704b5c21a77c3d1dd7f265a7f24e9f904405afc3170d5f3836c8d28105ee0",
-    "dist/2022-07-16/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "90c1480f585ad1d9e0c3b564f5eb87667eedf5992ce46f73d6462dbb9a136182",
-    "dist/2022-07-16/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "e5b3e75d5d85e84fbf8c0d4b8e1f4c20421e1d20c18805f413f785d594c14a4c",
-    "dist/2022-07-16/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "5163f545aca9e56edb0510c30eb9343dbdd95ce3704677cdbebcb70947437838",
-    "dist/2022-07-16/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "f6c61e0c2bb404f248986287dcf7f4bcf8458fd17e678bbb53c43ce5ef19d5eb",
-    "dist/2022-07-16/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "fce64768b803f67470e093422926f44cf621eca5052eff4d9c6b89b94556b411",
-    "dist/2022-07-16/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "e99f1ae947b812047c4367d87f0f4dde6581c0af02240625500b1ddc9133025e",
-    "dist/2022-07-16/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "c6bb4bd5eaea57d15dd995de614471aeaddd103158e609ecdf43177f1843c25b",
-    "dist/2022-07-16/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "8e54cc288f3bb2a268fe37f2815ce94c3810438aefdfab9dd679ef572dbc127b",
-    "dist/2022-07-16/rustc-beta-x86_64-apple-darwin.tar.gz": "dc06d6cc19934b091cb3894c42debf6189f7b2d54162cc93418cb8851c967154",
-    "dist/2022-07-16/rustc-beta-x86_64-apple-darwin.tar.xz": "2f177aa386c389ce18ec47495d5c48d5512bee00aed0e3dad53809fbdb81f55a",
-    "dist/2022-07-16/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "e6af40fc7d92ddfd3bdab6ed92b8bb614df2ef7158a8f59291593034191d483a",
-    "dist/2022-07-16/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "5c51250a55d9e424ced7f91a90a801d53bfcf489be033a06c15adfcd587f5e47",
-    "dist/2022-07-16/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "f4bc463f82baa6681ad7292c512836bde962743b32b28ba118c38622dc3478f4",
-    "dist/2022-07-16/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "a25e397cd228f44c0280f61621bdbab028fb07a20551a3c1b25606d0eefc4745",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-freebsd.tar.gz": "27e0d39b8bdde40899a1486fc39b6bc612068dc4d4db65d52a4b3c85f03675e4",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-freebsd.tar.xz": "74f59446e6e6b031fedd12d10380bd33c119b09d0d1435488008f104a4297a97",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-illumos.tar.gz": "9b49259f9446ffdc510b80b3cb67084f006cbf86bc6c14e6a6a42128657773eb",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-illumos.tar.xz": "2a5b5c0f33dcdf79afce7445d6dd0183ba95f898becfca6eace5858e6836706f",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "b891c82a6acbb2ee5e3b46c4e5ebfc4a215e70415879425125934b7fa8c33329",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "e33bf0cd9e7e50469c9cd98c9404aa7495268192e4be70117c75607a9a18bb95",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "f5ed5f80204fa0608e888750866b880575d9eba63bbcd69b71708713a27fe27c",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "3f69e388b687cbdafaf59ca3486eed4dda510652a8ee37fde9efeff096258801",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-netbsd.tar.gz": "57eb4ebf820c11e5d4700f6c3ec414e6d2b70475f71579f854aec66650ab9eb3",
-    "dist/2022-07-16/rustc-beta-x86_64-unknown-netbsd.tar.xz": "979c3d20834c4bdee5b47598fddc26c3e02edd7678ee34faf97ac5f11aa8314b",
-    "dist/2022-07-21/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "9099fe96569cf008c9bb92f86efe1773a1e6f8542e71af037727d411ca3e4c92",
-    "dist/2022-07-21/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "085c6086a977725738ee44c4e0b748be255847c740fbce4aec62519afa91c088",
-    "dist/2022-07-21/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "c829b598f2a7d815ddb1772153aa847e5f1fe844710acc01e18f626d5af1daaf",
-    "dist/2022-07-21/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "50d3336081798cf6dffa615e1217845b51f82017375b4b0cf18167a939de0a5c",
-    "dist/2022-07-21/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "40a86effd1d5b60735d15c33090e31a0ed1cccdcca7cece013176071a90f3c93",
-    "dist/2022-07-21/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "ee29ab772f2f24f7f4f8655cbab2a64ad7fd2253ce04a4a72c497cdd18fd71cc",
-    "dist/2022-07-21/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "d739d788caf9190fccbab1a00e42f75bb7e10d94263b556578175bdd11826468",
-    "dist/2022-07-21/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "9775c98de87876ade2a7896e0df6519334ffb21cca12f60afa1874105b7dc75b",
-    "dist/2022-07-21/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "241d9983b1314829b9311bb7e1743e422b81d22342eed7216ba534788df77016",
-    "dist/2022-07-21/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "df50d81cf63dfea4a17f32318d4b4111944323395641ad9f7c989f9f74dbd383",
-    "dist/2022-07-21/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "1953f4f8c244c81e60a97c9480f78c0a3e0373c44ef7c188306ea26a6ff087e1",
-    "dist/2022-07-21/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "296273dfe9ad0ebf0ef47bb0a566050f90ec235bdb3d7776371b0b249466764e",
-    "dist/2022-07-21/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "da67ad4667d2b39862e21d43b9e0a99ad0bbd36ccc936779ed6dacb9b2fd17c2",
-    "dist/2022-07-21/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "efc5eb6d3c6fabdb03b83c9e9215b13955f82ceec62255aafd78db0e28ba8421",
-    "dist/2022-07-21/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "e603216f64f6fcf3ca21581dcdd283b41a1b6a59779c7760b8aa79b4c593e7e8",
-    "dist/2022-07-21/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "7c5c47faf6f014b63e1193cbf27de51bec82e9811537a17cb9b4922b709618c8",
-    "dist/2022-07-21/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "ac605732e74a1c344ea7c6ef84a6ca1823d3ed51024ef895ec9a181a6f91f8c3",
-    "dist/2022-07-21/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "7044d68341f8ea2fef122600f3995fff681599dc1a545ab2b45d1b2302fd6436",
-    "dist/2022-07-21/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "b7d57d01a9985826333ecac8447e0a1a5a753cf0ed11770de70d47b59050215b",
-    "dist/2022-07-21/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "13076a20f555c18db2d38deaaf33aeaed0f27b8cb5a2962b26661b6989dc3a5f",
-    "dist/2022-07-21/rustfmt-nightly-mips-unknown-linux-gnu.tar.gz": "c64ab15040368af0c595102a7232b405b1a52164fe39e06ba189b2a26c70fe9d",
-    "dist/2022-07-21/rustfmt-nightly-mips-unknown-linux-gnu.tar.xz": "a05b3aa95231a7e6631f0da01869d8cb8b6e3a5c184eb411591583cc78cd3aaf",
-    "dist/2022-07-21/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "242650636f9b33adc71a8c1bba1dc3a2928ba7723c976ae5645428b47862c658",
-    "dist/2022-07-21/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "7a2a54f05cac08aa65645e099d2597504477bba269b6f74e99f2df397a660eaf",
-    "dist/2022-07-21/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "2c3f944a0b8a5b06c4a341882934b737a451baf38f7a902f0794b0f41e1102e3",
-    "dist/2022-07-21/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "506e4f89b5243b8c2f6709d69a8b8facad5d7a555b108bed4f689dbd3fe1e46e",
-    "dist/2022-07-21/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.gz": "fe3a12786f8eecf26213286045a69bc1046d7138a401511618b86b74a70eb66a",
-    "dist/2022-07-21/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.xz": "37409a8573c5d0c9ea1fd0a745990a4e85f325a87a25c9916dd25617b6059783",
-    "dist/2022-07-21/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "e74050fa0288e7368a9e65f2739498f38ca9c91d36c519674e4590c17d86fcd7",
-    "dist/2022-07-21/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "10da2c6d12e14f4a2c6c9a7f1d2c161a62e4f9956ed7ee100ba31fce9446ea78",
-    "dist/2022-07-21/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "a0cf070555fed25a8aa9f20d704149936dca1ccb7c3aa55aabad2be84a7860f7",
-    "dist/2022-07-21/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "f388ba16822251f2dff0d9fd837dc19c5ca181ebabc93ed81759530d07dce72f",
-    "dist/2022-07-21/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "6056b5c1f46807fce83c4c3e2a443beb66b433e678fb090ca253aef5a87d2927",
-    "dist/2022-07-21/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "642046b17142d6e9ecd207243ed82108088c941b04ee5d8f6b1371b07da60601",
-    "dist/2022-07-21/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "600b5e7a11e3cb583fae2ef9f9dc784c2bef08e355da9e3a37204e0c81a63451",
-    "dist/2022-07-21/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "a9019c838270635f2fe383da5b11fdef2c7b23f838bc5edee7ba5882e7102c63",
-    "dist/2022-07-21/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "613539dc9a67c78216d8d11b0d9baf068d48c4067d628c8144bccec2d899afd1",
-    "dist/2022-07-21/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "55d992631c567da8ea082ca6dfcfdbf4774374ec430050a16001def2221adafe",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "9bade75f59be530972a26618f4e283c89bda864cfd162f47c8d1782d31163148",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "39f21c72c31dc0cf945db142cead8aa8f9208769d8f4336905794ec52848e90e",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "3b5cdcc58acad278a1b4eb84dc5aacd8eafe0bd2ac0ab62c5056c918661a9364",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "159dd0daacf54993386b2d1cefab13354d9c7614983745d43c28a1a873fbe498",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "cfef1baac5ef48912a3d30b3ba6513da50e6a35d1ad8687452dfe64e671effc7",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "8c72ca088ae104dd3cd1ce711e083a1816d16876ddd1a07af983d9c22cec1a33",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "fdecac3b5e42523e9f5200080f682e3b557b6820ae0f67a02620e1d1fba6f571",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "cbf56b942479ee95c89e14b060765ab8e21b2152b2c3e02ffb47957e37cec4cf",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "309be4a29a875ba17ed14e351a6aff7a649e0e6897f3d2c3394f2f2ae966a275",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "72e6bfd09cb22f8400dbef4017cd09deb2881cdf67df61d4e4d2d2ed5221a683",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "d40edc2217657dedee45336aad31289190a7da43bc5620b5d36b7dc0fce1f211",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "1df1787f682e9a8bd97a054f76094281fccd4d321c3067e2600860327dd088e3",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "91ed27676b13193eecb93839c0c748e667e869f091de88cea4183c51870efbe8",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "ccb0245ac982c34c9db9f6ffc3c30769e2b62637a18d88dc30a4ed3c1922fa7e",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "54344a42f2fca291c0c10f84386135e2797c9b81519eab0c6db633a95c109f20",
-    "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "4a276eac1bdace68484b49104b8bb2c48f93a775404f2bd29e9c3d4c6ce7367f"
+    "dist/2022-08-09/cargo-beta-aarch64-apple-darwin.tar.gz": "5d9f0ee2de50a18124fd506f493cbdf6cb6385944d32aca1aca9dcdf15bdef4d",
+    "dist/2022-08-09/cargo-beta-aarch64-apple-darwin.tar.xz": "683e8546ab86d98ec84204cdcdd2192d19a98c42c13bf0c69697865641238001",
+    "dist/2022-08-09/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "fb2a95793d79e04201dcb38fb5ccdb86f1c74503b181a0b3fce0f332e3380bec",
+    "dist/2022-08-09/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "5b1b826315990487dc0afe561fecd7f937d82bc8d2898742592349c9993cb3c8",
+    "dist/2022-08-09/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "23d20d9078154f6f03b3b056607b804ce3e049dfe4d949ccf430556c2f8e79b1",
+    "dist/2022-08-09/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "d7a9283bf838c1182e6cc8904b6b464cd9c1dd342078b2447309797868aec7ff",
+    "dist/2022-08-09/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "fb82a87e759d5ab3536a8edba682793653f51c15d8f27a874ecbff11c991b1fc",
+    "dist/2022-08-09/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "21de23c600646a3d5a9421761c0411d7e173876278548c42d6a8794abfc5d3d2",
+    "dist/2022-08-09/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "d931162577c04807b093d6cedcca989315b15b48f153c790f8ee2ce3edf479dd",
+    "dist/2022-08-09/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "797752acf6d0b5814ff1c6e7dd5e54fec0716677c4a11f03143c6e769ed34b1f",
+    "dist/2022-08-09/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "f080f5f486cbfbd09206cca7b70cb051da5e5a68914227a58ee81ecb5ed19c48",
+    "dist/2022-08-09/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "79964e35d780df520ace77ec8035652571709620ba49f14ac7bc59008fd712f8",
+    "dist/2022-08-09/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "339b969dcf283d0cedd0ffea09d534994c5bf588977ecfde61ce87e64090f70d",
+    "dist/2022-08-09/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "601b6b0f58652434d888320851867b9188cb5a99b5f18358b0d7376dd98d4a0a",
+    "dist/2022-08-09/cargo-beta-i686-pc-windows-gnu.tar.gz": "1c9944d71ff7ed9cd40be1df8fc828e7faa4f5496d917dc6ccc94a1b31839a12",
+    "dist/2022-08-09/cargo-beta-i686-pc-windows-gnu.tar.xz": "4e3fc72b845b821e3aa1193250a10d494592f3e0917c7716b5bd963d0ad08b73",
+    "dist/2022-08-09/cargo-beta-i686-pc-windows-msvc.tar.gz": "80559b267ab936cb08a7ef51087e63b61a215df64fa9f5254809705fa31ea3a6",
+    "dist/2022-08-09/cargo-beta-i686-pc-windows-msvc.tar.xz": "aee6122d25a0bf7e083b45e622858acf34be3e17a1f9964a2f0d9fc7dfdbe164",
+    "dist/2022-08-09/cargo-beta-i686-unknown-linux-gnu.tar.gz": "5e1f2c32adbdde68b7135d1e4c358076f5dd872c935ac1bbdcbfda0ff43e061f",
+    "dist/2022-08-09/cargo-beta-i686-unknown-linux-gnu.tar.xz": "f0e6acd5158430866ad0bed435a7e0dbd9f35130b4805b990050b3d9751b4416",
+    "dist/2022-08-09/cargo-beta-mips-unknown-linux-gnu.tar.gz": "99b71c9001b65408f42e65cf481a905bc30f77edc96401691fb9b122a20009fb",
+    "dist/2022-08-09/cargo-beta-mips-unknown-linux-gnu.tar.xz": "08d1f3824354af35fb90d6563a7a51775ff9574a9ffe0c87e897e377be778598",
+    "dist/2022-08-09/cargo-beta-mips64-unknown-linux-gnuabi64.tar.gz": "7dd3dc44fd37af40e587dba68d973b9d2cf40a939a97605a6adee5ba0f589215",
+    "dist/2022-08-09/cargo-beta-mips64-unknown-linux-gnuabi64.tar.xz": "2f638fc21bb6e11fd59ff07d66a1012d3336d6dbd5b73b2c42461f84415e333d",
+    "dist/2022-08-09/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "ade7f1ba6f19382980b0a6cbe3e8035932a60c898f7141782921d22398b1cf03",
+    "dist/2022-08-09/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "2fe5d3b4102320fb1e36198e8d6e43d201986a2c58e4ad45fc2acb23865cf09f",
+    "dist/2022-08-09/cargo-beta-mipsel-unknown-linux-gnu.tar.gz": "c99aa42005094a65bbeb41deb3499a2fd46032296f6509fd1bf108f7d4cbdd04",
+    "dist/2022-08-09/cargo-beta-mipsel-unknown-linux-gnu.tar.xz": "7c65e8e6d76cab786f628e4ca02b6af47f6c2c4a36123ee7b8fc059309ce6039",
+    "dist/2022-08-09/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "b7b98621ef835f6108c0d1ec60c88d66b462a3daf62ddfc796d31f4e09f7baca",
+    "dist/2022-08-09/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "f85473a1d6b33d9b865a6532ea444415c7cfaa3f76af39d637619ffdddd0c00b",
+    "dist/2022-08-09/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "e783ea66457a0aff31489cd42f549a2c9c33cbb2ca0aa253575a59c9de7f73f4",
+    "dist/2022-08-09/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "d90a02cb425320fb5a5b163d87ec03726159994af31b32954c91b1cb9eb3ebf4",
+    "dist/2022-08-09/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "ff1fda58f7bdb9df563172388f66f787a60f75bdd169ef8d2c791b27bbd8c6ce",
+    "dist/2022-08-09/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "df740d61415bf15c62f9656932370e08fea5a289ac25bec78a626e771d24ab7f",
+    "dist/2022-08-09/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "019dfff6fef8c7714dd19c64a5bb408b2b5063367ec1aa8a72960316aa880834",
+    "dist/2022-08-09/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f8d025d2943b76d665500c9c72aab18a63ecd137e07c10d1463f1905b4274573",
+    "dist/2022-08-09/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "c379f3c122a9df41b66f13ca3dcb79feb9ae68798c9704dac3018d85ec96d895",
+    "dist/2022-08-09/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "69bd9bd12f4386c831aaa8e1fac8edf1a0e618d1f6e0e4bcb7be16f1eeb08d81",
+    "dist/2022-08-09/cargo-beta-x86_64-apple-darwin.tar.gz": "d74acf4f57681527af3a2c469e916bd9dc1ecdb591e16657757db493984de07a",
+    "dist/2022-08-09/cargo-beta-x86_64-apple-darwin.tar.xz": "00201568ce4b95c6618389ec86e00677a27435276dd1bec16fea44b87a2dce4b",
+    "dist/2022-08-09/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "3d049963cdda9755e524443a04b0b9c5566cb0e58dc61e13779484d92c3e0f69",
+    "dist/2022-08-09/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "c8f0c13771e010ed85002ee10e44ad7c0b21ce2ddd105c9b90fbe1896d0687f0",
+    "dist/2022-08-09/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "796d9da5a59c984a5a78afcfce762134e3a72e52525d0150ebe4bb29d207bd00",
+    "dist/2022-08-09/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "1ec2764428d4df9355380444158aaa2947c4fe00708e7a30bc6978433621d120",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-freebsd.tar.gz": "14643490b1259120b14a7be84942bfd324fdf03dcf473f33f7ae2466fb99f60b",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-freebsd.tar.xz": "3af267ab65b3c61b0184f8fb5b5cc5fb61688f9b668654986f30d3a794d9a1a6",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-illumos.tar.gz": "5b84826e0e68b6f9769ef7d00b4b1225cb1a4dde1b41f5b6021feb34e7376c63",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-illumos.tar.xz": "a1dde17fd13bfb626acd0ae65d88c440a3172e1fdb20aeefda3a205bad71d703",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "fedfd6a7b8156de19ed2d6b8f354affc4120fe311874e6563b9620634a5d962b",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "8701ba8c8fcf21623a690d3b7c00d50fc9949035af5aee092ff1239bed4a9784",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "beac64aa92687f975b3a0d5265d7c79ef3962c1d0f0e196296f67bf8e2b803d0",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "8b50c03102cfdf5ffff5fa7b51b0a4d159e24671be5430c77c07256e54a4fd12",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-netbsd.tar.gz": "dde29de6d56f02f5cdf35b96287e404ceed85372c3c671ee54972255369470fe",
+    "dist/2022-08-09/cargo-beta-x86_64-unknown-netbsd.tar.xz": "7e4d07676c4b33af0303436442dc763623784ed20293ed262780267b01843949",
+    "dist/2022-08-09/rust-std-beta-aarch64-apple-darwin.tar.gz": "63526962ddd66cd6b60f5bb348861caab7a78c7d80515baf4397cab857258d71",
+    "dist/2022-08-09/rust-std-beta-aarch64-apple-darwin.tar.xz": "64ba52408086b6c7e3578e2ded98528fd63466ec8d7f86045b55a575e0ca780b",
+    "dist/2022-08-09/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "261109cb02193cfa113697c9d769fcd4d4e265b01dbb4ca0bfa0e0d62f64c71e",
+    "dist/2022-08-09/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "7f2182b749a8980c2e7b4f31e5a8c72b8a9df8dd2552cda29d061e2236acc589",
+    "dist/2022-08-09/rust-std-beta-aarch64-apple-ios.tar.gz": "5abe9df533e7bfd62586483f20a1911be5eede5da6114b53b2a000c110e35768",
+    "dist/2022-08-09/rust-std-beta-aarch64-apple-ios.tar.xz": "2898b8ad95c6a67c2c296c4698acd043cadcb3a2b0449fb7515bfeb48db69a70",
+    "dist/2022-08-09/rust-std-beta-aarch64-fuchsia.tar.gz": "9f86fcd871ddef0fb86cdfb0084d1bf6fa150bb7cb4dfe3fcade13b75beea5a6",
+    "dist/2022-08-09/rust-std-beta-aarch64-fuchsia.tar.xz": "4aa91e4f7f3589085c2da45de78a16c48cfe9dd47541928db87ee964c3406b53",
+    "dist/2022-08-09/rust-std-beta-aarch64-linux-android.tar.gz": "910f4c1ad41d74306e7fdae43c8d04e7fc47724ae84b9276f2d264fbdf2b70f1",
+    "dist/2022-08-09/rust-std-beta-aarch64-linux-android.tar.xz": "cd60ac333fd684cb730c134cf5a037718254afb9aa65528b2463d76a138f07f7",
+    "dist/2022-08-09/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "39740739479c12203c9b6ae7c72f0e542c92750e08b2ca66c5e96355f1eea61f",
+    "dist/2022-08-09/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "1c7fb416b404c401f34d4461c61c95ffbaa5b50d8c95d090485aabe12cc78a0c",
+    "dist/2022-08-09/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "8cd2b395607ba16cac4a4fb85f1c5ccf9626849a8e11dc66e911053a6cd1df1b",
+    "dist/2022-08-09/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "c7ef35d4bb2ab6b8ad762349821b6e076851bd5b51dddb7a3b1678b78e21cb42",
+    "dist/2022-08-09/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "6410dc79e6e00eca4e483b438ef8a314a55ea6857c618efd50a32a2f95195df8",
+    "dist/2022-08-09/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "4d674cbb7d417944a1aaaa23e8c654ac9276529fed3639c75421e1de1e7bfcc2",
+    "dist/2022-08-09/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "1719104655a62e8300df06fb4636543532821c0ac43dcf90435d5fbbf39c12c1",
+    "dist/2022-08-09/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "bf3c12dae8fee831402f9700295d9a6718d6a6046a7e5a0d0748c3f2e3d82224",
+    "dist/2022-08-09/rust-std-beta-aarch64-unknown-none.tar.gz": "727621bd08ad0e879a79635fb00c187de6d23e0291143b494d3965cacb35d358",
+    "dist/2022-08-09/rust-std-beta-aarch64-unknown-none.tar.xz": "6b152098c76b2a3367dad676e4c3d328e5d5c89c95504b041e1997e5d141404a",
+    "dist/2022-08-09/rust-std-beta-arm-linux-androideabi.tar.gz": "c78d9c97e742ef1777679743765de5d475dffe62ea9b60efe2025eb91ba7ba5c",
+    "dist/2022-08-09/rust-std-beta-arm-linux-androideabi.tar.xz": "1029382048bce0b8e556b87008821f8b4c5c92e30b340c9a8086e32a8ca7f105",
+    "dist/2022-08-09/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "d4b8bb607968ca49d840c1835fc56e92006dd186c7ed71663a23b7495fa392e9",
+    "dist/2022-08-09/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "562dcbfb8ddd31e64939844055c3dbd87a4c04065ad34dbe3a2d87136c0bb4b4",
+    "dist/2022-08-09/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "1d8e8d87ce8f1ee5e8cb946c8b7a92e6f4a56ddd6b3afd1c646e4d5cdb703608",
+    "dist/2022-08-09/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "ce8edce3a2976694a8ca0cff0b296b331f64e0afa6b5cb107bf03e2aff5949c1",
+    "dist/2022-08-09/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "d57aff420435c76ff8bfaaaa8d94bce62d96299a2a0158b67b9fe914695cc188",
+    "dist/2022-08-09/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "7eecf0facd3f2dd236e5f731eaf3fbc51b46d1a039f762f5bb42aabd0ab21c00",
+    "dist/2022-08-09/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "6b6341eeca9a48e1c15b03501428ebdd2f591f4196c50d988408a1c591152fb0",
+    "dist/2022-08-09/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "019e36e7c8855ef9d1277d4f5388862412c6d49e7f16d6808d3a6f69c60e5030",
+    "dist/2022-08-09/rust-std-beta-armebv7r-none-eabi.tar.gz": "41b1cfbcfd16061d52413e0bf2503756ffbe819b4ef2d81f8570e477e0b5893b",
+    "dist/2022-08-09/rust-std-beta-armebv7r-none-eabi.tar.xz": "209828e95d236ee218a10f468b12d64e4f4bb773a0cbfc247e6f54c2aacdc8a5",
+    "dist/2022-08-09/rust-std-beta-armebv7r-none-eabihf.tar.gz": "762a5764e926cb081062040cc4f43f8653eab007ac9cb8600751c0f364f17639",
+    "dist/2022-08-09/rust-std-beta-armebv7r-none-eabihf.tar.xz": "eb9b66ad16ff5c7427112ed5cf73498a02694b7b3af37220e3160bb6a16eca1c",
+    "dist/2022-08-09/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "369b3afe600692f552f7d0bdd310c7b254f8745948e5a4ffff7c5fccf0873ce4",
+    "dist/2022-08-09/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "2cdeb7b58e979bec71aa0a67a95ede5b55ab6ac295b24b08c67e651c4a76b13a",
+    "dist/2022-08-09/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "1a31c291792ba44053c9701d8e665c62155cb319b371359c7f0f9b5b81269f6b",
+    "dist/2022-08-09/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "54b17f4959cff54daf926f33dad8141663366856f691f4ca1015fedf36720022",
+    "dist/2022-08-09/rust-std-beta-armv7-linux-androideabi.tar.gz": "77ca2251056b76db72b9e8795dfc1b9583544f35dd067435128b2336b33aa892",
+    "dist/2022-08-09/rust-std-beta-armv7-linux-androideabi.tar.xz": "888b80410a8f9f1f85ec379c4e5490fc18bfb3f7e4954fa66f9b9c27ea92d121",
+    "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "3b8132040574da39cafbf48cc1e2535ab1c52c51ac2968aaf167911bb4bab648",
+    "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "915acd9a715cb25db4e899315afbb2b97ad34aee52a7f4536b4e684295e93e8b",
+    "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "9a1e59513f6812f631fa4926ea794b05524e58cd4d36a55b7a4e286b2e7bd506",
+    "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "017892f81ce10323b76dd32347d5ba921003177fd95e5d4b4972ad4e84e699c8",
+    "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "3a7b2f2c4d06135a9ff3931a1a9c0f4431bb3a31763501bbad1dbfb85849e681",
+    "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "6226c7228337739435cd7194fe3c233250fb2eb8df4dd16c9ef637b2d91c1807",
+    "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "48b626650f72a7e3885ea2aabbb8c520b079ebda0f798f685392501f1ef7fd79",
+    "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "627a0be5e0059cc07a4bfd99a0f70e009367c7be6ea45eb4ac0f8554680309e4",
+    "dist/2022-08-09/rust-std-beta-armv7a-none-eabi.tar.gz": "2489ef3102a8b0ba9885c092309a2e7deaf65721c934a83259fa7f7698440638",
+    "dist/2022-08-09/rust-std-beta-armv7a-none-eabi.tar.xz": "0e43df943f9550e374ba9334a0bd68f3bd107dc68ee8012f92357aaa0bf3851e",
+    "dist/2022-08-09/rust-std-beta-armv7r-none-eabi.tar.gz": "edb09fe24634386fe335685bbced045cd7448d1aad520f1cbaa4f0d38f3d38a1",
+    "dist/2022-08-09/rust-std-beta-armv7r-none-eabi.tar.xz": "2b170a322d07da39e949047871dd28444feaf49d09c901fbdd4015f00e456415",
+    "dist/2022-08-09/rust-std-beta-armv7r-none-eabihf.tar.gz": "82a69f097820c70c0fdc9b5f22b5378ab1d70d3d35bfec0ebab8b30ad7903178",
+    "dist/2022-08-09/rust-std-beta-armv7r-none-eabihf.tar.xz": "0301f9984effc3b186531aacb182e65fb57519c5ebd80f445c7346db27dfcc39",
+    "dist/2022-08-09/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "47bc8975498b6f6afdce3ef7d2d8d4b239b6219f5e4bae9841a82587e1279415",
+    "dist/2022-08-09/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "0806ef9782068d292106f3fce8b7bf879931fb89efc5e832d85f82bbffa99489",
+    "dist/2022-08-09/rust-std-beta-i586-pc-windows-msvc.tar.gz": "fb11022f5410c508936617b337d8940d82431544f77366ba6dbc3da81172bd21",
+    "dist/2022-08-09/rust-std-beta-i586-pc-windows-msvc.tar.xz": "326bc6a7dfe216b03222b187ed424ca6b83325f9a91e0b873d9294c713040a37",
+    "dist/2022-08-09/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "0a608449de9eca7fbb421263fee19d22a3950f68dee80ca343c8704b2a9fcefb",
+    "dist/2022-08-09/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "ca980e9d255d4444a329983565eb15807a26c0cdb48bfe763f9fdee061d8a9e4",
+    "dist/2022-08-09/rust-std-beta-i586-unknown-linux-musl.tar.gz": "db8c6517bb71bf49470b87cc1c9bd180c0421475bad04917be988c0933620db6",
+    "dist/2022-08-09/rust-std-beta-i586-unknown-linux-musl.tar.xz": "2feccd2d2ec54e25ac36ec2b9ff823887d353c9ca1106a29f8ca0f33f2e5d08a",
+    "dist/2022-08-09/rust-std-beta-i686-linux-android.tar.gz": "0ce00226f5aa2165d043108650e7444e165ae80c985c62f953b46fd680946b5a",
+    "dist/2022-08-09/rust-std-beta-i686-linux-android.tar.xz": "e591b8ae11fa7b6b8907d598e159c8795e4c3ff9c2c55e65773c29e488f64550",
+    "dist/2022-08-09/rust-std-beta-i686-pc-windows-gnu.tar.gz": "51fa05e5fb2d0d310b97c9e255ea3bc5ecb185093013406588cc96fddba18788",
+    "dist/2022-08-09/rust-std-beta-i686-pc-windows-gnu.tar.xz": "64d87c682eb1a2e0b8abd393358e1880016803bb7da699f2d239ad2d59e0eb0c",
+    "dist/2022-08-09/rust-std-beta-i686-pc-windows-msvc.tar.gz": "e3c2df5572996ade55a9af5b5b54a84fc0ff2edfcad164f57852ab0d3695d938",
+    "dist/2022-08-09/rust-std-beta-i686-pc-windows-msvc.tar.xz": "2991215756373d253ffd27a8f650613a5f2bb636adf263b664741772c594241a",
+    "dist/2022-08-09/rust-std-beta-i686-unknown-freebsd.tar.gz": "bf82e2e7734304f12d3ed5db591ece38a1078b575d92aab8f45328d087cf56ba",
+    "dist/2022-08-09/rust-std-beta-i686-unknown-freebsd.tar.xz": "73a3b79fe72e835a8b7dfdaba6a1b9c5ee8dde25534fcc520b0ee80a7853b31a",
+    "dist/2022-08-09/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "74e23ff14e240e935f630e19467bbc9e1b02e9962313dc74f8c444c96bcbfb2e",
+    "dist/2022-08-09/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "987003e5b23308f31f613a5a133466cd045c05a5998ab29e4d3d8ef15a8342d9",
+    "dist/2022-08-09/rust-std-beta-i686-unknown-linux-musl.tar.gz": "1c76bac0701c3f9352f4439d2daecb219c08964c6a48ceb212520b4a8e532e02",
+    "dist/2022-08-09/rust-std-beta-i686-unknown-linux-musl.tar.xz": "7007e60d8ba5e9e40f6aefa248b4881057a9b9a73aa9e7ff0c67a36de7748be3",
+    "dist/2022-08-09/rust-std-beta-mips-unknown-linux-gnu.tar.gz": "0f6ca4637da137235a3e9315691f1b5c0afc2f853a855458ad6d10ea59ef8579",
+    "dist/2022-08-09/rust-std-beta-mips-unknown-linux-gnu.tar.xz": "778557cf1c57ada5c1a64ecd58db3a49e8f874217664d53a8be0cfb89b031980",
+    "dist/2022-08-09/rust-std-beta-mips-unknown-linux-musl.tar.gz": "cbe799d70ca9a24645187d61198c40d495aeed8ef037570ed3cad95b898f6c82",
+    "dist/2022-08-09/rust-std-beta-mips-unknown-linux-musl.tar.xz": "ab37bff0f1c90a6adb9d603041d5fbe7c94dccfa05a6171145c41335350d02a9",
+    "dist/2022-08-09/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.gz": "3e5aa74f970a70614751d258b7958696457b03c3f8c6eb2b8e61f3395d9f9169",
+    "dist/2022-08-09/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.xz": "e32f82fa27968b9f9cc0bad083daae95cc21bc7f56b6fed8e57de39200398248",
+    "dist/2022-08-09/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "29247f72e5d5563dbfaff65876cd1181943c57121e27a979c11005734825de4f",
+    "dist/2022-08-09/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "1835664e58cd35261f7387be0746bfd821a8d8108ef8f26dc68db1b4886cc6b6",
+    "dist/2022-08-09/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "eb6826841be8177bead8edf3d06892219fe7e898e541d2a76539e49c7cf2caa7",
+    "dist/2022-08-09/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "25c2801f324985094cf3aa9aa56d88e2c73bcd1f7849fdbfd11032fb9d853bc9",
+    "dist/2022-08-09/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "573f981b5e197ef337812fb3bcc4ee513121067968d3d33e369426ec51cfdb8e",
+    "dist/2022-08-09/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "da6d57cff4999bec0e4249c0b1f1048eae925e793149c60f044b257f306d26bf",
+    "dist/2022-08-09/rust-std-beta-mipsel-unknown-linux-gnu.tar.gz": "8637387cb7f722457e7cdbb6c75eb70fdb913a5543adb1e4dd81d7316f0d2520",
+    "dist/2022-08-09/rust-std-beta-mipsel-unknown-linux-gnu.tar.xz": "539a0a66e06fe7b49e40b2615c3d04611236746419bf03f5439b14cc37f3344e",
+    "dist/2022-08-09/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "458734ed82bb7e3feb1d831ea6224cd4eeabfbcb06599181d025660298ef7bbe",
+    "dist/2022-08-09/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "64f0ce96ae9a99daa300d49d087837c7c619e4bdb38f41664d79844c84254c32",
+    "dist/2022-08-09/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "937c3b1481aeab47b45dcb8dc45c12f856a771615c3b6e56b04e10b4f8075d1d",
+    "dist/2022-08-09/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "05094bfba7b7fe1fe66f0643ed60079c675d739613e27cb64ca8a61b5faadcd0",
+    "dist/2022-08-09/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "d15c897c52bc02a241e9756c62b48c126d651d498a72a3cc70521e6a395bce7c",
+    "dist/2022-08-09/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "2182c3300e6cf5f7fba5a687235c34fa9e799beef2edbb07206205ede50964ad",
+    "dist/2022-08-09/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "cba214c9827f639f6c88de0bb28f81c58e81f1263b10ccb4fda5c84ad23ea036",
+    "dist/2022-08-09/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "f7f9bb0d56ebd4b80db0560d6f71b25028c97b99f79eb7ef89255d46ca4df22e",
+    "dist/2022-08-09/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "b190a078b408d184766831664df1a2d472a134909ad00f195fb84d522d360a56",
+    "dist/2022-08-09/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "31bcf275272e3a46618110219f61eefd5fdd2c11a75f7ff612fea012dbc3c4b5",
+    "dist/2022-08-09/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "eadde81672eda5af55c8f2eff6729ad134dd484ac16aef4fa0e402e0164f30df",
+    "dist/2022-08-09/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "2a5d69f4ec463377e2f9eca3a70647680d1ed09bef4f9a7b839d1d08eed989ca",
+    "dist/2022-08-09/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "89b9b9149461362d54b64b2cbdec317674266a9061fc0d46b438f664e003ac83",
+    "dist/2022-08-09/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "3c56a23f2fda148e442318bb5a21d895a5b61cc698db5ea9a1ff3c2740887fc4",
+    "dist/2022-08-09/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "94f9f155ce07f09ca12814b745cce5d6dfc731cc59c95fcd5b1831f60d9c04fb",
+    "dist/2022-08-09/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "b9f76d28c4e057d9b7eada2076c4358d6876aed1c32f65dfa50dc3e3c1970d79",
+    "dist/2022-08-09/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "e664018f445157229a0c07406d3fc4e7a19cb53722fc3838fcee1bbd3a3a00cf",
+    "dist/2022-08-09/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "8d48a304ba7ca9470ed5f88076f6c50477f6b3a1afe303aab772638df8978c32",
+    "dist/2022-08-09/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "347072268911f3a03223bd494cd2d14cfe4c553fc35e9d36571b54995e04d9aa",
+    "dist/2022-08-09/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "100d5a1e75b7c302f03eba8eb26c5c023e1b396cd44d7798f2902bf8f40ec48b",
+    "dist/2022-08-09/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "f5d91e04ac7980aa5253e0c90e7e312e42b5fa7de03f35f61fe11ab207894f50",
+    "dist/2022-08-09/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "0d83e81a8c48f9cc3e62442e51aee769cef4cc618a2661506a5fb9120163be25",
+    "dist/2022-08-09/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "96d983517839cbd1d64adfff4b3b0241ceed99573579f041d136be39aa2b7995",
+    "dist/2022-08-09/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "0eb2c70b7eeb3f754ffea3716e41dc3efae49e98d77ca1843541587dddd6b880",
+    "dist/2022-08-09/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "91fa2a025c04e41a7b9a7eb6b4cda351b93fc53801f97042ae0e76bd871d92e9",
+    "dist/2022-08-09/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "8ad9da4410688824d5adc6cb8ed42f76bb8a35d41bee62b5f7b44e0d6bd346bb",
+    "dist/2022-08-09/rust-std-beta-sparcv9-sun-solaris.tar.gz": "cb3a28d68f432a3357b6a971f046b5ea37fdad5d4aaa4aea7cc997356d487b75",
+    "dist/2022-08-09/rust-std-beta-sparcv9-sun-solaris.tar.xz": "746fb859655ed6b4379fce8937fff998952cb81297412091844b0e277ec65a23",
+    "dist/2022-08-09/rust-std-beta-thumbv6m-none-eabi.tar.gz": "8bab8c46c7e873d0fa0a7078675fa7a54a90e5342f8b58419e0dd434e9942b67",
+    "dist/2022-08-09/rust-std-beta-thumbv6m-none-eabi.tar.xz": "954b5c32e5515e09b77bcaa3a7c4e139905a4f3d1801b492069c027a8311bc6b",
+    "dist/2022-08-09/rust-std-beta-thumbv7em-none-eabi.tar.gz": "9eb56471c38528c2b80dea81d94e5368f68a977745a1e02449f3eae353ca405f",
+    "dist/2022-08-09/rust-std-beta-thumbv7em-none-eabi.tar.xz": "0334379d0e8c3ef9680837b1dfc96788da4836a91e42d71446461ece7217ab78",
+    "dist/2022-08-09/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "0c65cc553ca2730d020fd8a97b90ebfe2b3c0fc2755b137df55955a3d1c7908f",
+    "dist/2022-08-09/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "625a109a589fae6e2fb64376e3fec4bb39ca19217ad6d312df524129868f343b",
+    "dist/2022-08-09/rust-std-beta-thumbv7m-none-eabi.tar.gz": "e0002c917055c85b613297da21427fc3b6c5f55ee120921ee8bae9b99afec2b6",
+    "dist/2022-08-09/rust-std-beta-thumbv7m-none-eabi.tar.xz": "74cc0f5b245b483b62c9a9e8bd642069af5205ecc59fd0b7464ab1fd6f4f3f7e",
+    "dist/2022-08-09/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "98c09985ea2d56fcc8c219c46d355310b65fd4f7c6920df2e7ec5355848ba83d",
+    "dist/2022-08-09/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "5122e60b031458c4606905a3df5d64b7bac54bcf883c18ba53443aa76fc5c1cf",
+    "dist/2022-08-09/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "6ab96971e69a073a5789c3eaaa460a7f5d6a3a5df8ac5125344744dde8476706",
+    "dist/2022-08-09/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "be874a256076dd2869d6d5780c5b4e8c850e52a62b5d10087d7c1aca32b0b831",
+    "dist/2022-08-09/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "c37ab11b56d3ac41b8eeadbed09ae5e78467c8945cecb49c218fe91a284e43c0",
+    "dist/2022-08-09/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "dfa4d1dcfb32d4001b2b9f00a829afd699065dcc6538598eaa27d684a01facac",
+    "dist/2022-08-09/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "31931cdb16a9a81bf7fc779c8aef6890c1f35130ba1c323d8b548a5dd5494346",
+    "dist/2022-08-09/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "0aeb4ff0e9b139e3b5550103c6429cb3cb4b455335514b07491e22fa63719169",
+    "dist/2022-08-09/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "ba7077816ba6f1b6b386b0245249e10a1482b82eaec711561f912a1975482817",
+    "dist/2022-08-09/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "6a49c1907e0ce91a3650aeeb61f6674c39936b67366fa4bb197fc612e9ae5a49",
+    "dist/2022-08-09/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "0e268083c1935be97e3a96ca94b824c84877970a65c2e581f3e71d7364264dff",
+    "dist/2022-08-09/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "27510dbb922d9cc0ee669f3854ffeb1ca28c105b3284e3ba523abcb9cfc10055",
+    "dist/2022-08-09/rust-std-beta-wasm32-unknown-unknown.tar.gz": "6d2f49e7e75ca2e3873dd1530d4bc3eedcebf3b2db6b1e193c0d57d7daa681a3",
+    "dist/2022-08-09/rust-std-beta-wasm32-unknown-unknown.tar.xz": "5508d36c7ae20176af2c10a0c974d5162202e3914e79468b9541c3e1b585612a",
+    "dist/2022-08-09/rust-std-beta-wasm32-wasi.tar.gz": "721726c4b073b27df9abc9e47a2b82eb48ca12a44c87363ae57a632d26619fc9",
+    "dist/2022-08-09/rust-std-beta-wasm32-wasi.tar.xz": "320ae842da96d4ba3147ca338e91306ed602250320df5163a01748491599ade3",
+    "dist/2022-08-09/rust-std-beta-x86_64-apple-darwin.tar.gz": "2dd9b9defe95357d7af5ae81428be814efe9923c308a4c2f3a370b16d912707f",
+    "dist/2022-08-09/rust-std-beta-x86_64-apple-darwin.tar.xz": "17ea6b22feb7fef1211c319a3d9d0f7bcdd8cd215d3ddffc523a83cfeb8331a6",
+    "dist/2022-08-09/rust-std-beta-x86_64-apple-ios.tar.gz": "df3618fb0b30d89d567d238d4e744d8cff81ca07cef701876b4471a98768c810",
+    "dist/2022-08-09/rust-std-beta-x86_64-apple-ios.tar.xz": "60932e2848af4a25699e7d300833f0b8e10bc8dc201d4ac9dcda417f86413cb8",
+    "dist/2022-08-09/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "57db93d53efad36639645baf0cdfa47b4b70664e22a1eac3f08a5abedc0834ac",
+    "dist/2022-08-09/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "cea91317cf86ec301730a2ef8a1c68213b6a4921c105bab228e9bd8620641f2b",
+    "dist/2022-08-09/rust-std-beta-x86_64-fuchsia.tar.gz": "7b961a55c6616b02aa91a25eb9e2521bd50ac881120975ea3af92543adfdd8b5",
+    "dist/2022-08-09/rust-std-beta-x86_64-fuchsia.tar.xz": "3ce7314f2c8f3a00430a6686fa267a5b4a8ef20b28023b765aa326f0151d2521",
+    "dist/2022-08-09/rust-std-beta-x86_64-linux-android.tar.gz": "37d538db9ab3cad73c4cdfb0b3836f124a6a2e47dbd1f6aa54167451057ced2f",
+    "dist/2022-08-09/rust-std-beta-x86_64-linux-android.tar.xz": "600ea7bc318580195d3b4e681c5f374075ec40272641050f0fd6296da4a9d383",
+    "dist/2022-08-09/rust-std-beta-x86_64-pc-solaris.tar.gz": "7d389f2d2632068cde7e8f72e685a888462897f4d5aa98034060472443cb89ff",
+    "dist/2022-08-09/rust-std-beta-x86_64-pc-solaris.tar.xz": "60a6532403d902d71883169c2001d6b279f882bee4444bb8107e742e4cfa3ecc",
+    "dist/2022-08-09/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "76c93994bc6eaa7596ee91dd24f51685ab659533835d441352f88b89a0991236",
+    "dist/2022-08-09/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "fdba628daf4b04afc1ec1d8ac4b9460ffe0a230feaf61dd7b621e2ec02b09a2b",
+    "dist/2022-08-09/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "4ee478c238ec38ec4977fa8a1689aa28b7a2b0173549da92f1b2e1a2f6772aee",
+    "dist/2022-08-09/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "c732f3054a4a67f25242ba9acb5bfbc945e3ac62a2b0de5b7ede0990313984b5",
+    "dist/2022-08-09/rust-std-beta-x86_64-sun-solaris.tar.gz": "47a4e8d8cc03e402e480ce5f24326de7094622fe339e4441df7f6a6271a8775c",
+    "dist/2022-08-09/rust-std-beta-x86_64-sun-solaris.tar.xz": "260c93c4dafb20d476a965e2681751e38be15bfb96d32b10730e44a1d4da6079",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "9d7c63a2ced8041b21459192a0176665ad93324c3774f3028b411eacafd9bfe8",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "276235e7efd773273ffe281cfe5119a9fd361f04ddb1f3ed060d0abb983ff55d",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-illumos.tar.gz": "00ee12a1d47b1d00403e8f2d083a0dbfc8bbbf86ba973b08fbf4c59333f70052",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-illumos.tar.xz": "e11ffdd664228acb94e8e92ae919f7c3bf354083a1ca586be4fa65b7abac17eb",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "d58aedd100cf952c52b8364731b1ecc05567c4d6be4899d36f210ff619b934dd",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "28021e5a4ff36813f76f6aeb063fefaf58310d65993557df2128ff5b9eeb4f75",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "ef5ed09b2bd6b9c1772aeb66444dd821176b4aefb27e657db5bbd24f09d9c104",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "c41edbd8ec4266555b7824594eef470ca6d7695675cf13303dcca6b248d0b692",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "575e5b74248f2503de16294d10e6fec2f6bacac9082ffd73e0395ac2669aefda",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "4b0f56d6a004c6ebdf325ece1d8006795ffb404ea4f1e958a1425ba9edb28b18",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "9e39545494934be7f91675de58907b7b71fe383c535b55799add8c5706371dcb",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "3807db4641082a329edbd08654f40f769e44d139edc99be0b559c8c00c27adbf",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-none.tar.gz": "4eeddd2654e6a84ef5ad5a6f90d88dab043ca087f884e640c945a4565c6b20e2",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-none.tar.xz": "656e1ff5941fe4699ac16d6c1cdd715fca3a7980b4159644b856af08d8b47918",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-redox.tar.gz": "0e0d5de37c86d6a0684b627f16dd6adebbd2ab4776f4a3fb6a386b3ebe9cdbb2",
+    "dist/2022-08-09/rust-std-beta-x86_64-unknown-redox.tar.xz": "dc79147efac5730201980035d1ae377cda5a18bb446647e1bc8375c5d645b1c9",
+    "dist/2022-08-09/rustc-beta-aarch64-apple-darwin.tar.gz": "a3916d7a71d422a0118363228bfcca4a72abd08a6fe6c6d3b4888b87846a1bbf",
+    "dist/2022-08-09/rustc-beta-aarch64-apple-darwin.tar.xz": "f18d8918c9c1ff55cc513fffa309d72b9aeb853f92dfa66e34fb151a2c374269",
+    "dist/2022-08-09/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "ba008d21693e01291e3016773f728c98040903eaa6a71abda23f8043eb9348b6",
+    "dist/2022-08-09/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "1333977a0a147bd5f05eef63ca859b8e78ddc51bed2202616ce5fda5a9203080",
+    "dist/2022-08-09/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "78e40c65e40a287e9ee2d9178f84c8ff7277c2a5beff67555185d79fee1af44b",
+    "dist/2022-08-09/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "ce24270b141952b3fb67c0f43896416dd77be66ed3b311857bff8b07121e1de9",
+    "dist/2022-08-09/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "6557c13f5014acda10349a99e24749224b4f86e55b6499e35f05b5e583a1fed3",
+    "dist/2022-08-09/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "d4b1b814bfa277f895ef4a6c8963ce482965fbdf83ba0661b11db8df39ef301c",
+    "dist/2022-08-09/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "3fd9fdfe30333a0a99cf8e9fe754cb1b8f8734b5d1ab47aaf9490d8eaf3b29b8",
+    "dist/2022-08-09/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "a736efa35fab54ebf36aebf5c7f5b6d4f0ec1f7b0e5b8b3acf2720d97b0c7d93",
+    "dist/2022-08-09/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "5b824f9aa8a77f8a21d8cf68751924739e65d599c0fe561ea9383b8de4132315",
+    "dist/2022-08-09/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "9996ad84db143044b454483cc24c6ad5c333edd7988ab4ef221237d37891e26d",
+    "dist/2022-08-09/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "6fcbf77721d4d5c51fe5c580f0ff8ac7347d6c49895da33a3eca19e505cc752d",
+    "dist/2022-08-09/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "3b4e566667ee1b2e9fdb5ac6cde4aa3ddf9c9739e7e64e519f2204db2048bd20",
+    "dist/2022-08-09/rustc-beta-i686-pc-windows-gnu.tar.gz": "cc4f775b79c3ad51bf6ff558267100e05c6fa12ac378d69cc0b0affc37b541a9",
+    "dist/2022-08-09/rustc-beta-i686-pc-windows-gnu.tar.xz": "b646befe7d3ad1b0a30c9eb4e14a6e401f1346e11f88145ee17043de2b6f4df0",
+    "dist/2022-08-09/rustc-beta-i686-pc-windows-msvc.tar.gz": "9b4847beb5faf417bc24b4b963f40c8c8dce55b73658eacb10d2d1c968c676b5",
+    "dist/2022-08-09/rustc-beta-i686-pc-windows-msvc.tar.xz": "6b57826d56686f481d2a20e90994a2af6cb9886c063b1dc08c3bb181ce248a69",
+    "dist/2022-08-09/rustc-beta-i686-unknown-linux-gnu.tar.gz": "ea34b82db9cc6d079a67df542036c83e8661d435d15802976676671cb2b27c24",
+    "dist/2022-08-09/rustc-beta-i686-unknown-linux-gnu.tar.xz": "d679a401e807b12fa8fd3686d3ac09374d3c8d660c6f0a571efc7c9217a05f09",
+    "dist/2022-08-09/rustc-beta-mips-unknown-linux-gnu.tar.gz": "cb3c3638460f3d71c94ca10ab9684ebdbb25f886b8604e62e8412361be56e579",
+    "dist/2022-08-09/rustc-beta-mips-unknown-linux-gnu.tar.xz": "0665c0e3b2ac28648c2a0ac49670181a737ae30fc74add44a2ee612b1d74dd24",
+    "dist/2022-08-09/rustc-beta-mips64-unknown-linux-gnuabi64.tar.gz": "0acc722d22b787adbe16549edbf28debdd4d84633701f8bb7514d5911d6ff124",
+    "dist/2022-08-09/rustc-beta-mips64-unknown-linux-gnuabi64.tar.xz": "441d5ca203afbd5bc4af16431c31d3c76e05edbe45ad37aea4d1f90ca4afecee",
+    "dist/2022-08-09/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "437c52c97b0a8edd1165b957b768e7c9f7c3d79023626fdcb97538899f424592",
+    "dist/2022-08-09/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "9812034d2fe8bb583dfe57a792639a6ac7ab912682ad7383db975efd5f0cd281",
+    "dist/2022-08-09/rustc-beta-mipsel-unknown-linux-gnu.tar.gz": "5d39fe2005a50e40505b18210af700ed8fd439d018fe8723c13221c7683defad",
+    "dist/2022-08-09/rustc-beta-mipsel-unknown-linux-gnu.tar.xz": "da77cb500618d57682ef4d601e1c8492d9d5412a1833757ffa95d00b0aab790f",
+    "dist/2022-08-09/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "5e4559e41c12f1248cec5f4cb40c196e5d6520bffcc043a40759e7a7668ee0b7",
+    "dist/2022-08-09/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "41c527f4dbf76275f26f7486b48613fba57171b82275ae29ad90bbe684497ce8",
+    "dist/2022-08-09/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "410f2768e5b69f03ebed37923e0c0bb54d4b297bcbef98d82529216a1dfa4c6f",
+    "dist/2022-08-09/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "7f0d0ff4a797120c1a31d33cecd4abd4bd69ec6ff97351291267423f27f7f3f1",
+    "dist/2022-08-09/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "2fa446a7f79d254350b7e9828a36fd415f6931494bdec8bf8f26e0c13636849f",
+    "dist/2022-08-09/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "8572718b7ca5aef0de8227550816dbbd7b41fcc2ab6b0624a50096fa387503ce",
+    "dist/2022-08-09/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "7d82792f2526c6e6522c5255dd350e09f838551f743f760634b875eb22b48b0e",
+    "dist/2022-08-09/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "99f4ff1b50ce3b644b12bc0da84910f376c9187adede0222dc8a1e242e347263",
+    "dist/2022-08-09/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "81f32e172bc635028fe048d2194f1d49c4f31b4daadf8690931cd3a15a9e06d1",
+    "dist/2022-08-09/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "c50258bda8d09646bef493463d66be02d8e7155122e2b7eafe9bc5bd11cbe6b9",
+    "dist/2022-08-09/rustc-beta-x86_64-apple-darwin.tar.gz": "fa2d6a74109c087f13fbbf00171252fcd9079b9978028ee6df4fb2d18c27a39e",
+    "dist/2022-08-09/rustc-beta-x86_64-apple-darwin.tar.xz": "630b218549ee04a8bc5a8a29616d5d8c1d866804cedb2fc3861cc2e354382c5e",
+    "dist/2022-08-09/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "633b22f9c9a93f6cbed7a53fb466ea0bf5895f6fa9c3a22a5883951cedbd606b",
+    "dist/2022-08-09/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "d109d67480ab01ab1e176b5c904df5053fbb54baaf422d4f5019a28dd122e149",
+    "dist/2022-08-09/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "627635dcd8515ed029515e1621b8411e1a3a6ede4058d2cf581c8d669b96dd5f",
+    "dist/2022-08-09/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "6f98febabe7229c566c86728dcf773849c97f29bc0f43ea4f5ffb4e81f163b18",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-freebsd.tar.gz": "a4b4dcd9dd1128df37d761efaa669ebb35841af0847b5bb5bcf38295ca47db6d",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-freebsd.tar.xz": "cd28418166eaa754102b469414d0fcfe6785096855e50a2b895c5903e528d8c2",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-illumos.tar.gz": "168cf42f579132b44ac35a214328f518ab201d6fb9d88d645899fdd88e1d5e34",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-illumos.tar.xz": "7792763eda89f90a878b09dd99ea9af94d6db0c36bb9570e9b1a05d8dc2f1e47",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "ec79355625df63a29487253925f5213442f8606f2fd6fca7a94f8db57220f802",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "b7df0b00cfc3bee9a1a906441726ae009aa7dfbfe22e16bc9127ec4df11cd1a7",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "372a7c389366e543f3477f2854271c7a74042abf51c37f2d5ce1450f4cd3bfd3",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "11243da1c7642ee7ece1b43de1e59b4c45fa8ecf0c9d632d6f1db4772e4479a6",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-netbsd.tar.gz": "808a451394f4a023ef28420d7dc29e2de92618e5a563055798ec2307e0ca062f",
+    "dist/2022-08-09/rustc-beta-x86_64-unknown-netbsd.tar.xz": "55b447374eb361b2ea1de87080bac3a0cc4fbd233e916e53e5424d6b9ed0dc48",
+    "dist/2022-08-09/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "bbbfd82986d5fafa76f06b87b08cfda800dbc87a1adaed3587f570336a648c3f",
+    "dist/2022-08-09/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "69a99ec973a3603c3d84361d407fbe9c79af0a284a48f5578fb6f46affe751b1",
+    "dist/2022-08-09/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "4a886c744cd6b5f4fe0ec2a3b87730e9a4f7a66c9d4fb0c6411be32014e9e5f0",
+    "dist/2022-08-09/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "095ff2687c8dd48decf47c2b65ce84579bc753de0732877cb092b4ccb9df4f92",
+    "dist/2022-08-09/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "3533a40f72ee318f04448f005e0a811add2e97285e158f63758f76b4424ebe46",
+    "dist/2022-08-09/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "85a4f34d889bf52b65b93066bd1bd6a91092ed49cf6443f476bd60fb36b1cb6d",
+    "dist/2022-08-09/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "11c4bb5a071d555cda8b685e340727eb588f7a830cd4fc22937e44e68b3d7ee4",
+    "dist/2022-08-09/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "b7c9628299f155530d5a2831a4ffe8d398d2cd222952815006eb19d6ff92a846",
+    "dist/2022-08-09/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "04ce1aec5cd9c7ba644954d8ec6ba4c851de1c964b64b0d63965cd2043e7d590",
+    "dist/2022-08-09/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "08635b48b6a7585dbeb7e53f5aac172404e8dfbdf8c165e281064737f073a013",
+    "dist/2022-08-09/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "852ea71bee89cbf9c9fd1d9abb02a88695732d51b106d3de78c36f371663341e",
+    "dist/2022-08-09/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "499ded5cd2689626186c3a51af671991ec67ea0eb16bfa30097a764c6718405a",
+    "dist/2022-08-09/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "eff28bbdd1d3dc44fb4504b24856dc8c550f1311ce56a1614acf2b7409a1c5e2",
+    "dist/2022-08-09/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "b621a87a5257c280b0610fa90abd288264ee01238669d61030ae057e87eb8e47",
+    "dist/2022-08-09/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "9307f1feb9c06f57930cd0009aa7b740f1c9e1515212bd7e2ae81149ea0f571d",
+    "dist/2022-08-09/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "fea653c9e14d305ed217f9c984742c066ea7f7d2fb6d316a13586afc820fca8a",
+    "dist/2022-08-09/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "8e600a6ad04dff36fe9b1846592faa693b1a036f58d136a522d6ca86f9d76be1",
+    "dist/2022-08-09/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "52b45791540bc754a82a7349ca4c5ce194afd28e6c857b61f0ff7e87f10f1253",
+    "dist/2022-08-09/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "964847cfa824c66db554ec20a7e623f4ea50e4cef2439b6813592bcdc31a94ce",
+    "dist/2022-08-09/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "71b89b63be5a44e12d0303e71e3e14b0b770aaac5bcf2879e17526b27e568c6d",
+    "dist/2022-08-09/rustfmt-nightly-mips-unknown-linux-gnu.tar.gz": "aac0b10cfcb07c64de04fea33d9cf8d691f307e3aefaa9582a8ba3e1fd54aa35",
+    "dist/2022-08-09/rustfmt-nightly-mips-unknown-linux-gnu.tar.xz": "e3688bc8ef82fff7685cc95fc1ec708a5d76d288cccbd42c37e5c83184f6a52e",
+    "dist/2022-08-09/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "aa89a2dbfe0c6020139d8be52be126a01af9691eaf73fa94c94f9ae75d09d619",
+    "dist/2022-08-09/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "1e7e5f11f829b06f4d8ae5b6d38f13e055ff1fda5b1481e33e40e2a336c7852a",
+    "dist/2022-08-09/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "e43b8009179139c1bd15f3e947a8bc7357e57833959f9fd18fde1d75a742bede",
+    "dist/2022-08-09/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "5bf84aa3ad0badbf0c60d31f686498801d9a23dc0324062128cd7690f9c69234",
+    "dist/2022-08-09/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.gz": "b3816072c441ee9e2b8da5cc6a8ed022795b7176d4ac604d97b0d213f89522ac",
+    "dist/2022-08-09/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.xz": "d7c6b668f4a2c128ab845e010deb7c9c3e374aaf167244395cdad6c746f73420",
+    "dist/2022-08-09/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "91c36676f8b9093976d7e30ac39f2c477f8442771a3e9c49f41610a0b8688cbe",
+    "dist/2022-08-09/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "86bc5289beee0abf87bfc57a09d6504bfe58675871f4e7559b7f9e1b748e8dc6",
+    "dist/2022-08-09/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "12a1716934b48c2cf716a56c66f95852a70bc74b65c2e44a542b9c2ebf1be5ec",
+    "dist/2022-08-09/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "591ac7d4acd0036d532c91fa3f64a7789881224dd5496b1fe3564c79fd5f0254",
+    "dist/2022-08-09/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "b558c9463e5b8380e133a7a64bc95994d8625fa0097f8b41fb39c93367704698",
+    "dist/2022-08-09/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "d28bbc411779d19279fec251e9378b3923c4b3a8c651d375e139732dd6daaaad",
+    "dist/2022-08-09/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "af9644ab1e369495a4e35fbd111946c679e597c8c1f8342d3a92bad0cad30ffc",
+    "dist/2022-08-09/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "c2acdb98f2c2565cbaf57557cbd99038fb066a09b5602ff3d3bbcb58388b4501",
+    "dist/2022-08-09/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "eddd4a32740ba700c095568bff791e959d6b8ab0a47b5e98a317ea56cc754751",
+    "dist/2022-08-09/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "021bba582076650b577d78fda0b6d9374b17e623d2f3ddb0322f9960874ac269",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "355c877020b386f0297765f8ae1b1e3fa126c9e9b537f8923d275bd31cbdba33",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "809d3314e1b69efb5544fa6daa6719907e09edfd7e0c2cf483ad89a3d508b98d",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "def326ede8106aa440b57698a027fffe024158351879d17f9bba0e58c3788662",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "86684f3c6ba66216c5c9cb203eb9fce96e0239a345df912a2071bc9aa83cc9da",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "2d658db4849089e86af76eb4d7986d605da644af6f6ad43429931f775b5bb094",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "ec14c63680836e5303450d3bfda7b6ca5b163ec01cdaf1e3f2d7b6c584c4c6a1",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "39542f4fd6261b864c59494958071dacd32703fd870286ec5fceaf3664d3e5a4",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "a02061c8bcdd23a8b3f21c4f776e900536fcd44019a495fdec159fd9b4282700",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "15fe16aca96080380c6ebf109522f60134dbaad610d3841e07ac5059ee920edc",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "43d562bce508ccc40afdc3f1ec85b6f0e29b1bad1661a758d07e57cb97d63407",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "80659ef19b274724eb3becb90ca03ea6cb6eb1ff9ff6989073df6e1e52c0d406",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "392e98288ea2ef6602dff922c9bef4fcb17acdcefbb4bca050ede73aeee669e8",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "1eccdcb7cdb96ffb5a5261d4190e4bd1f92e5cf61e92e556ed6baf42e9c316ab",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "9526d26c9fef619cf429437d45c5a79e89a894b22f88635d7995639f1f9696b6",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "486b79d19fff869275f973b274b3cddf02693ba444a79a2e100c6ba79be5d493",
+    "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "1378376c8b16aa269034cd99b2efb8d8a0fe77e9526338d652b6d6e9aff2ac0c"
   }
 }
index efb345fa9f3e52be803134e5ce50d939a63d7697..909cd0062a623050a02e6fcb98695e60295fc013 100644 (file)
@@ -12,11 +12,11 @@ async fn async_fn_test() {
 }
 
 // NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}",
-// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
+// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
 // CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
 // NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
-// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
+// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
 
 fn main() {
     let _fn = async_fn_test();
index 8995605e3dd7208f12a8d96fa99e396f9e56ce9f..73c652c9dd15ea3a87323f63628b2f5f356309e7 100644 (file)
@@ -16,7 +16,7 @@ async fn async_fn_test() {
 
 // FIXME: No way to reliably check the filename.
 
-// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
+// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
 // For brevity, we only check the struct name and members of the last variant.
 // CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
@@ -36,16 +36,17 @@ async fn async_fn_test() {
 // CHECK-SAME: )
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
 // CHECK-SAME: file: [[FILE]], line: 14,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
+// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], file: !2, baseType: [[VARIANT:![0-9]*]],
 // CHECK:      [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
-// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
 // CHECK-NOT: flags: DIFlagArtificial
 
 fn main() {
index b9cb4f93d07d8159e8a4016380a6a140a8793620..bdd312878ec887bb5ade80915bdde69fce5060f7 100644 (file)
@@ -46,7 +46,7 @@
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "align", scope: ![[VTABLE_TY2]], {{.*}}, baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{128|64}})
 
 // NONMSVC: !DIGlobalVariable(name: "<debug_vtable::bar::{closure_env#0} as core::ops::function::FnOnce<(core::option::Option<&dyn core::ops::function::Fn<(), Output=()>>)>>::{vtable}"
-// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > >, {{.*}}, {{.*}}, Some> > > >::vtable$"
+// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum2$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > > > > > >::vtable$"
 
 // NONMSVC: !DIGlobalVariable(name: "<debug_vtable::generic_closure::{closure_env#0}<bool> as core::ops::function::FnOnce<()>>::{vtable}"
 // MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::generic_closure::closure_env$0<bool>, core::ops::function::FnOnce<tuple$<> > >::vtable$
index 033da80be16cc00fe0042634723110281aa1ffee..b712068bf27f2ab9790ef7741df57ee3df78f8d3 100644 (file)
@@ -20,7 +20,7 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
 
 // FIXME: No way to reliably check the filename.
 
-// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<generator_debug_msvc::generator_test::generator_env$0>"
+// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<generator_debug_msvc::generator_test::generator_env$0>"
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
 // For brevity, we only check the struct name and members of the last variant.
 // CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
@@ -40,16 +40,18 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
 // CHECK-SAME: )
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
 // CHECK-SAME: file: [[FILE]], line: 17,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
+// CHECK:      [[VARIANT_WRAPPER]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Variant4", scope: [[GEN]],
+// CHECK:      !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], {{.*}}, baseType: [[VARIANT:![0-9]*]],
 // CHECK:      [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
-// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
 // CHECK-NOT: flags: DIFlagArtificial
 
 fn main() {
index d6d7e5b44aafc1429b96b00140ebff9de8ecfe9e..11c4ae2f65929c4e7d63268f197c3036647b4592 100644 (file)
 
 // cdb-command: g
 // cdb-command: dx b
-// cdb-check: b                : Unresumed [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [variant]        : Unresumed
+// cdb-check: b                : Unresumed [Type: enum2$<generator_objects::main::generator_env$0>]
 // cdb-check:    [+0x[...]] _ref__a          : 0x[...] : 5 [Type: int *]
 
 // cdb-command: g
 // cdb-command: dx b
-// cdb-check: b                : Suspend0 [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [variant]        : Suspend0
+// cdb-check: b                : Suspend0 [Type: enum2$<generator_objects::main::generator_env$0>]
 // cdb-check:    [+0x[...]] c                : 6 [Type: int]
 // cdb-check:    [+0x[...]] d                : 7 [Type: int]
 // cdb-check:    [+0x[...]] _ref__a          : 0x[...] : 5 [Type: int *]
 
 // cdb-command: g
 // cdb-command: dx b
-// cdb-check: b                : Suspend1 [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [variant]        : Suspend1
+// cdb-check: b                : Suspend1 [Type: enum2$<generator_objects::main::generator_env$0>]
 // cdb-check:    [+0x[...]] c                : 7 [Type: int]
 // cdb-check:    [+0x[...]] d                : 8 [Type: int]
 // cdb-check:    [+0x[...]] _ref__a          : 0x[...] : 6 [Type: int *]
 
 // cdb-command: g
 // cdb-command: dx b
-// cdb-check: b                : Returned [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [<Raw View>]     [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [variant]        : Returned
+// cdb-check: b                : Returned [Type: enum2$<generator_objects::main::generator_env$0>]
 // cdb-check:    [+0x[...]] _ref__a          : 0x[...] : 6 [Type: int *]
 
 #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
index a153a9a42289a4018b913a9f68ad3dcee080465f..45d5ddf5c0ebc8644832c112986c09bf5840418a 100644 (file)
 // cdb-command: g
 
 // cdb-command: dx a
-// cdb-check:a                :  Some({...}) [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check:    [variant]        :  Some
+// cdb-check:a                : Some [Type: enum2$<core::option::Option<msvc_pretty_enums::CStyleEnum> >]
 // cdb-check:    [+0x000] __0              : Low (0x2) [Type: msvc_pretty_enums::CStyleEnum]
 
 // cdb-command: dx b
-// cdb-check:b                : None [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check:    [variant]        : None
+// cdb-check:b                : None [Type: enum2$<core::option::Option<msvc_pretty_enums::CStyleEnum> >]
 
 // cdb-command: dx c
-// cdb-check:c                : Tag1 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [<Raw View>]     [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [variant]        : Tag1
+// cdb-check:c                : Tag1 [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
 
 // cdb-command: dx d
-// cdb-check:d                :  Data({...}) [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [<Raw View>]     [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [variant]        :  Data
+// cdb-check:d                : Data [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
 // cdb-check:    [+0x000] my_data          : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
 
 // cdb-command: dx e
-// cdb-check:e                : Tag2 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [<Raw View>]     [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [variant]        : Tag2
+// cdb-check:e                : Tag2 [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
 
 // cdb-command: dx f
-// cdb-check:f                :  Some({...}) [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check:    [variant]        :  Some
+// cdb-check:f                : Some [Type: enum2$<core::option::Option<ref$<u32> > >]
 // cdb-check:    [+0x000] __0              : 0x[...] : 0x1 [Type: unsigned int *]
 
 // cdb-command: dx g
-// cdb-check:g                : None [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check:    [variant]        : None
+// cdb-check:g                : None [Type: enum2$<core::option::Option<ref$<u32> > >]
 
 // cdb-command: dx h
-// cdb-check:h                : Some [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [variant]        : Some
+// cdb-check:h                : Some [Type: enum2$<core::option::Option<u32> >]
 // cdb-check:    [+0x004] __0              : 0xc [Type: unsigned int]
 
 // cdb-command: dx i
-// cdb-check:i                : None [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [variant]        : None
+// cdb-check:i                : None [Type: enum2$<core::option::Option<u32> >]
 
 // cdb-command: dx j
 // cdb-check:j                : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
 
 // cdb-command: dx k
-// cdb-check:k                :  Some({...}) [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check:    [variant]        :  Some
+// cdb-check:k                : Some [Type: enum2$<core::option::Option<alloc::string::String> >]
 // cdb-check:    [+0x000] __0              : "IAMA optional string!" [Type: alloc::string::String]
 
 // cdb-command: dx l
-// cdb-check:l                :  Ok [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check:    [variant]        :  Ok
+// cdb-check:l                : Ok [Type: enum2$<core::result::Result<u32,enum2$<msvc_pretty_enums::Empty> > >]
 // cdb-check:    [+0x000] __0              : 0x2a [Type: unsigned int]
 
+// cdb-command: dx niche128_some
+// cdb-check: niche128_some    : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+// Note: we can't actually read the value of the field because CDB cannot handle 128 bit integers.
+// cdb-check:    [+0x000] __0 [...] [Type: core::num::nonzero::NonZeroI128]
+
+// cdb-command: dx niche128_none
+// cdb-check: niche128_none    : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+
+// cdb-command: dx wrapping_niche128_dataful
+// cdb-check: wrapping_niche128_dataful : X [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check:    [+0x[...]] __0              [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx wrapping_niche128_none1
+// cdb-check: wrapping_niche128_none1 : Y [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check:    [+0x[...]] __0              [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx wrapping_niche128_none2
+// cdb-check: wrapping_niche128_none2 : Z [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check:    [+0x[...]] __0              [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx direct_tag_128_a,d
+// cdb-check: direct_tag_128_a,d : A [Type: enum2$<msvc_pretty_enums::DirectTag128>]
+// cdb-check:     [+0x[...]] __0              : 42 [Type: unsigned int]
+
+// cdb-command: dx direct_tag_128_b,d
+// cdb-check: direct_tag_128_b,d : B [Type: enum2$<msvc_pretty_enums::DirectTag128>]
+// cdb-check:     [+0x[...]] __0              : 137 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_1_some,d
+// cdb-check: niche_w_fields_1_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields1>]
+// cdb-check:     [+0x[...]] __0              : 0x[...] : 77 [Type: unsigned char *]
+// cdb-check:     [+0x[...]] __1              : 7 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_1_none,d
+// cdb-check: niche_w_fields_1_none,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields1>]
+// cdb-check:     [+0x[...]] __0              : 99 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_2_some,d
+// cdb-check: niche_w_fields_2_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
+// cdb-check:     [+0x[...]] __0              : 800 [Type: core::num::nonzero::NonZeroU32]
+// cdb-check:     [+0x[...]] __1              : 900 [Type: unsigned __int64]
+
+// cdb-command: dx niche_w_fields_2_none,d
+// cdb-check: niche_w_fields_2_none,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
+// cdb-check:     [+0x[...]] __0              : 1000 [Type: unsigned __int64]
+
+// cdb-command: dx niche_w_fields_3_some,d
+// cdb-check: niche_w_fields_3_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : 137 [Type: unsigned char]
+// cdb-check:     [+0x[...]] __1              : true [Type: bool]
+
+// cdb-command: dx niche_w_fields_3_niche1,d
+// cdb-check: niche_w_fields_3_niche1,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : 12 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche2,d
+// cdb-check: niche_w_fields_3_niche2,d : C [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : false [Type: bool]
+
+// cdb-command: dx niche_w_fields_3_niche3,d
+// cdb-check: niche_w_fields_3_niche3,d : D [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : 34 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche4,d
+// cdb-check: niche_w_fields_3_niche4,d : E [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : 56 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche5,d
+// cdb-check: niche_w_fields_3_niche5,d : F [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+
+// cdb-command: dx -r3 niche_w_fields_std_result_ok,d
+// cdb-check: niche_w_fields_std_result_ok,d : Ok [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check:    [+0x[...]] __0              [Type: alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>]
+// cdb-check:        [+0x[...]] data_ptr         : [...]
+// cdb-check:        [+0x[...]] length           : 3 [...]
+
+// cdb-command: dx -r3 niche_w_fields_std_result_err,d
+// cdb-check: niche_w_fields_std_result_err,d : Err [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check:    [+0x[...]] __0              : 789 [Type: unsigned __int64]
+
+// cdb-command: dx -r2 arbitrary_discr1,d
+// cdb-check: arbitrary_discr1,d : Abc [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
+// cdb-check:     [+0x[...]] __0              : 1234 [Type: unsigned int]
+
+// cdb-command: dx -r2 arbitrary_discr2,d
+// cdb-check: arbitrary_discr2,d : Def [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
+// cdb-check:     [+0x[...]] __0              : 5678 [Type: unsigned int]
+
+#![feature(rustc_attrs)]
+#![feature(repr128)]
+#![feature(arbitrary_enum_discriminant)]
+
+use std::num::{NonZeroI128, NonZeroU32};
+
 pub enum CStyleEnum {
     Low = 2,
     High = 16,
@@ -80,6 +152,51 @@ pub enum NicheLayoutEnum {
 
 pub enum Empty {}
 
+// The following three types will use a niche layout once
+// https://github.com/rust-lang/rust/pull/94075 is merged:
+enum NicheLayoutWithFields1<'a> {
+    A(&'a u8, u32),
+    B(u32),
+}
+
+enum NicheLayoutWithFields2 {
+    A(NonZeroU32, u64),
+    B(u64),
+}
+
+enum NicheLayoutWithFields3 {
+    A(u8, bool),
+    B(u8),
+    C(bool),
+    D(u8),
+    E(u8),
+    F,
+}
+
+#[rustc_layout_scalar_valid_range_start(340282366920938463463374607431768211454)]
+#[rustc_layout_scalar_valid_range_end(1)]
+#[repr(transparent)]
+struct Wrapping128(u128);
+
+// #[rustc_layout(debug)]
+enum Wrapping128Niche {
+    X(Wrapping128),
+    Y,
+    Z,
+}
+
+#[repr(i128)]
+enum DirectTag128 {
+    A(u32),
+    B(u32),
+}
+
+#[repr(u32)]
+enum ArbitraryDiscr {
+    Abc(u32) = 1000,
+    Def(u32) = 5000_000,
+}
+
 fn main() {
     let a = Some(CStyleEnum::Low);
     let b = Option::<CStyleEnum>::None;
@@ -93,6 +210,35 @@ fn main() {
     let j = CStyleEnum::High;
     let k = Some("IAMA optional string!".to_string());
     let l = Result::<u32, Empty>::Ok(42);
+    let niche128_some = Some(NonZeroI128::new(123456).unwrap());
+    let niche128_none: Option<NonZeroI128> = None;
+
+    let wrapping_niche128_dataful =
+        unsafe { Wrapping128Niche::X(Wrapping128(340282366920938463463374607431768211454)) };
+    let wrapping_niche128_none1 = Wrapping128Niche::Y;
+    let wrapping_niche128_none2 = Wrapping128Niche::Z;
+
+    let direct_tag_128_a = DirectTag128::A(42);
+    let direct_tag_128_b = DirectTag128::B(137);
+
+    let niche_w_fields_1_some = NicheLayoutWithFields1::A(&77, 7);
+    let niche_w_fields_1_none = NicheLayoutWithFields1::B(99);
+
+    let niche_w_fields_2_some = NicheLayoutWithFields2::A(NonZeroU32::new(800).unwrap(), 900);
+    let niche_w_fields_2_none = NicheLayoutWithFields2::B(1000);
+
+    let niche_w_fields_3_some = NicheLayoutWithFields3::A(137, true);
+    let niche_w_fields_3_niche1 = NicheLayoutWithFields3::B(12);
+    let niche_w_fields_3_niche2 = NicheLayoutWithFields3::C(false);
+    let niche_w_fields_3_niche3 = NicheLayoutWithFields3::D(34);
+    let niche_w_fields_3_niche4 = NicheLayoutWithFields3::E(56);
+    let niche_w_fields_3_niche5 = NicheLayoutWithFields3::F;
+
+    let niche_w_fields_std_result_ok: Result<Box<[u8]>, u64> = Ok(vec![1, 2, 3].into());
+    let niche_w_fields_std_result_err: Result<Box<[u8]>, u64> = Err(789);
+
+    let arbitrary_discr1 = ArbitraryDiscr::Abc(1234);
+    let arbitrary_discr2 = ArbitraryDiscr::Def(5678);
 
     zzz(); // #break
 }
index 3846fb42f81a5ecc1b2c1fb10281cba837efeef6..9630952cbaae0c41b44c5b8e390b97201bac3392 100644 (file)
 // cdb-command: g
 
 // cdb-command: dx o1
-// cdb-check:o1               : Some [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [variant]        : Some
+// cdb-check:o1               : Some [Type: enum2$<core::option::Option<u32> >]
 // cdb-check:    [+0x004] __0              : 0x4d2 [Type: [...]]
 // cdb-command: dx o2
-// cdb-check:o2               : Some [Type: enum$<core::option::Option<u64> >]
-// cdb-check:    [variant]        : Some
+// cdb-check:o2               : Some [Type: enum2$<core::option::Option<u64> >]
 // cdb-check:    [+0x008] __0              : 0x162e [Type: unsigned __int64]
 
 // cdb-command: g
@@ -89,7 +87,7 @@ fn slice(s: &[u8]) {
     zzz(); // #break
 }
 
-fn zzz() { }
+fn zzz() {}
 
 fn main() {
     range(10..12, 20..30);
index 00dccf5f9064a3dfa00f9d2d98c59dc5ed82e436..314ba40b0e3d0b8a4208d565fca78fd0a80d34ca 100644 (file)
 // cdb-check:    [<Raw View>]     [Type: core::cell::UnsafeCell<i32>]
 
 //
-// cdb-command:dx lock,d
-// cdb-check:lock,d           : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >]
-// cdb-check:    [variant]        : Ok
+// cdb-command:dx _lock,d
+// cdb-check:_lock,d          : Ok [Type: enum2$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum2$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> > > > >]
 // cdb-check:    [...] __0              [Type: std::sync::mutex::MutexGuard<i32>]
 
 use std::sync::Mutex;
 
-#[allow(unused_variables)]
-fn main()
-{
+fn main() {
     let m = Mutex::new(0);
-    let lock = m.try_lock();
+    let _lock = m.try_lock();
+
+    println!("this line avoids an `Ambiguous symbol error` while setting the breakpoint");
+
     zzz(); // #break
 }
 
+#[inline(never)]
 fn zzz() {}
index 55a4ecc1c1a29fffa0a6cd5cc256990cb0db063f..a51b37205e8aa2cb8cd443b6b3f6035af8106871 100644 (file)
@@ -39,7 +39,6 @@
 // gdb-command: print some_string
 // gdb-check:$8 = Some = {"IAMA "...}
 
-
 // === LLDB TESTS ==================================================================================
 
 // lldb-command: run
@@ -65,7 +64,6 @@
 // lldb-command: print os_string
 // lldb-check:[...]$6 = "IAMA OS string 😃"[...]
 
-
 // === CDB TESTS ==================================================================================
 
 // cdb-command: g
 // cdb-check:    [chars]          : "IAMA OS string [...]"
 
 // cdb-command: dx some
-// cdb-check:some             : Some [Type: enum$<core::option::Option<i16> >]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<i16> >]
-// cdb-check:    [variant]        : Some
+// cdb-check:some             : Some [Type: enum2$<core::option::Option<i16> >]
+// cdb-check:    [<Raw View>]     [Type: enum2$<core::option::Option<i16> >]
 // cdb-check:    [+0x002] __0              : 8 [Type: short]
 
 // cdb-command: dx none
-// cdb-check:none             : None [Type: enum$<core::option::Option<i64> >]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<i64> >]
-// cdb-check:    [variant]        : None
+// cdb-check:none             : None [Type: enum2$<core::option::Option<i64> >]
+// cdb-check:    [<Raw View>]     [Type: enum2$<core::option::Option<i64> >]
 
 // cdb-command: dx some_string
-// cdb-check:some_string      :  Some({...}) [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check:    [variant]        :  Some
+// cdb-check:some_string      : Some [Type: enum2$<core::option::Option<alloc::string::String> >]
+// cdb-check:    [<Raw View>]     [Type: enum2$<core::option::Option<alloc::string::String> >]
 // cdb-check:    [+0x000] __0              : "IAMA optional string!" [Type: alloc::string::String]
 
 // cdb-command: dx linkedlist
 use std::ffi::OsString;
 
 fn main() {
-
     // &[]
     let slice: &[i32] = &[0, 1, 2, 3];
 
@@ -188,4 +182,6 @@ fn main() {
     zzz(); // #break
 }
 
-fn zzz() { () }
+fn zzz() {
+    ()
+}
index c0d905a6acc4ebd1ec6e668fc659809b975d2e92..cdac47a784d94339567d2d713d9abaede6b4b610 100644 (file)
@@ -7,15 +7,14 @@
 // cdb-command: g
 
 // cdb-command: dx x,d
-// cdb-check:x,d              : Ok [Type: enum$<core::result::Result<i32,str> >]
+// cdb-check:x,d              : Ok [Type: enum2$<core::result::Result<i32,str> >]
 // cdb-check:    [...] __0              : -3 [Type: int]
 
 // cdb-command: dx y
-// cdb-check:y                : Err [Type: enum$<core::result::Result<i32,str> >]
+// cdb-check:y                : Err [Type: enum2$<core::result::Result<i32,str> >]
 // cdb-check:    [...] __0              : "Some error message" [Type: str]
 
-fn main()
-{
+fn main() {
     let x: Result<i32, &str> = Ok(-3);
     assert_eq!(x.is_ok(), true);
 
@@ -25,4 +24,6 @@ fn main()
     zzz(); // #break.
 }
 
-fn zzz() { () }
+fn zzz() {
+    ()
+}
index b040a6e74947ddaa5cb5ab72de1eaf54d0f9e479..9cc99d7767c1f927a635b29d66f53a9631249b89 100644 (file)
 // 0-sized structs appear to be optimized away in some cases, so only check the structs that do
 // actually appear.
 // cdb-command:dv /t *_struct
-// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
+// cdb-check:struct type_names::GenericStruct<enum2$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
 
 // ENUMS
 // cdb-command:dv /t *_enum_*
-// cdb-check:union enum$<type_names::Enum1> simple_enum_1 = [...]
-// cdb-check:union enum$<type_names::Enum1> simple_enum_2 = [...]
-// cdb-check:union enum$<type_names::mod1::Enum2> simple_enum_3 = [...]
-// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
-// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
+// cdb-check:union enum2$<type_names::Enum1> simple_enum_1 = [...]
+// cdb-check:union enum2$<type_names::Enum1> simple_enum_2 = [...]
+// cdb-check:union enum2$<type_names::mod1::Enum2> simple_enum_3 = [...]
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
 
 // TUPLES
 // cdb-command:dv /t tuple*
-// cdb-check:struct tuple$<u32,type_names::Struct1,enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
-// cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum$<type_names::mod1::Enum2>,char> tuple2 = [...]
+// cdb-check:struct tuple$<u32,type_names::Struct1,enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
+// cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum2$<type_names::mod1::Enum2>,char> tuple2 = [...]
 
 // BOX
 // cdb-command:dv /t box*
 // cdb-check:struct tuple$<alloc::boxed::Box<f32,alloc::alloc::Global>,i32> box1 = [...]
-// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
+// cdb-check:struct tuple$<alloc::boxed::Box<enum2$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
 
 // REFERENCES
 // cdb-command:dv /t *ref*
 // cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
 // cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
 // cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
-// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
+// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum2$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
 
 // RAW POINTERS
 // cdb-command:dv /t *_ptr*
 // cdb-check:struct tuple$<ptr_mut$<type_names::Struct1>,isize> mut_ptr1 = [...]
 // cdb-check:struct tuple$<ptr_mut$<isize>,isize> mut_ptr2 = [...]
-// cdb-check:struct tuple$<ptr_mut$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_mut$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
 // cdb-check:struct tuple$<ptr_const$<type_names::Struct1>,isize> const_ptr1 = [...]
 // cdb-check:struct tuple$<ptr_const$<isize>,isize> const_ptr2 = [...]
-// cdb-check:struct tuple$<ptr_const$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_const$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
 
 // VECTORS
 // cdb-command:dv /t *vec*
 // cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
 // cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
 // cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
-// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
+// cdb-check:struct alloc::vec::Vec<enum2$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
 // cdb-command:dv /t slice*
 // cdb-check:struct slice$<usize> slice1 = [...]
-// cdb-check:struct slice$<enum$<type_names::mod1::Enum2> > slice2 = [...]
+// cdb-check:struct slice$<enum2$<type_names::mod1::Enum2> > slice2 = [...]
 
 // TRAITS
 // cdb-command:dv /t *_trait
 // cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
 // cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
 // cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum2$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
 // cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >),usize> rust_fn = [...]
 // cdb-command:dv /t *_function*
 // cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
 // cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
 // cdb-check:struct tuple$<isize (*)(isize),usize> generic_function_int = [...]
 // cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn")
 // cdb-check:Return Type: void
-// cdb-check:Parameter Types: enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>
+// cdb-check:Parameter Types: enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >
 // cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn_with_return_value")
 // cdb-check:Return Type: usize
 // cdb-check:Parameter Types: f64
diff --git a/src/test/run-make/issue-85401-static-mir/Makefile b/src/test/run-make/issue-85401-static-mir/Makefile
new file mode 100644 (file)
index 0000000..5e094cb
--- /dev/null
@@ -0,0 +1,16 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# Regression test for issue #85401
+# Verify that we do not ICE when trying to access MIR for statics,
+# but emit an error when linking.
+
+OUTPUT_FILE := $(TMPDIR)/build-output
+
+all:
+       $(RUSTC) --crate-type rlib --crate-name foo -Crelocation-model=pic --edition=2018 foo.rs -Zalways-encode-mir=yes --emit metadata -o $(TMPDIR)/libfoo.rmeta
+       $(RUSTC) --crate-type rlib --crate-name bar -Crelocation-model=pic --edition=2018 bar.rs -o $(TMPDIR)/libbar.rlib --extern=foo=$(TMPDIR)/libfoo.rmeta
+       $(RUSTC) --crate-type bin --crate-name baz -Crelocation-model=pic --edition=2018 baz.rs -o $(TMPDIR)/baz -L $(TMPDIR) --extern=bar=$(TMPDIR)/libbar.rlib > $(OUTPUT_FILE) 2>&1; [ $$? -eq 1 ]
+       cat  $(OUTPUT_FILE)
+       $(CGREP) 'crate `foo` required to be available in rlib format, but was not found in this form' < $(OUTPUT_FILE)
+       # -v tests are fragile, hopefully this text won't change
+       $(CGREP) -v "internal compiler error" < $(OUTPUT_FILE)
diff --git a/src/test/run-make/issue-85401-static-mir/bar.rs b/src/test/run-make/issue-85401-static-mir/bar.rs
new file mode 100644 (file)
index 0000000..15b12ec
--- /dev/null
@@ -0,0 +1,4 @@
+pub fn bar() {
+    println!("bar {}", foo::FOO);
+    foo::foo();
+}
diff --git a/src/test/run-make/issue-85401-static-mir/baz.rs b/src/test/run-make/issue-85401-static-mir/baz.rs
new file mode 100644 (file)
index 0000000..2ff4c51
--- /dev/null
@@ -0,0 +1,3 @@
+fn main() {
+    bar::bar()
+}
diff --git a/src/test/run-make/issue-85401-static-mir/foo.rs b/src/test/run-make/issue-85401-static-mir/foo.rs
new file mode 100644 (file)
index 0000000..d064c45
--- /dev/null
@@ -0,0 +1,5 @@
+pub static FOO: &str = "foo";
+
+pub fn foo() {
+    println!("foo");
+}
index bfff75e7acb08429585ef8b65ffab131d2702cea..20e86c7f9a0721a127439132cb4b9adf25f6147b 100644 (file)
@@ -9,16 +9,29 @@ FAKEROOT=$(TMPDIR)/fakeroot
 
 all: normal custom sysroot
 
-normal: basic-translation.rs
+# Check that the test works normally, using the built-in fallback bundle.
+normal: test.rs
        $(RUSTC) $< 2>&1 | grep "struct literal body without path"
 
-custom: basic-translation.rs basic-translation.ftl
-       $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/basic-translation.ftl 2>&1 | grep "this is a test message"
+# Check that a primary bundle can be loaded and will be preferentially used
+# where possible.
+custom: test.rs working.ftl
+       $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/working.ftl 2>&1 | grep "this is a test message"
+
+# Check that a primary bundle with a broken message (e.g. a interpolated
+# variable is missing) will use the fallback bundle.
+missing: test.rs missing.ftl
+       $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/missing.ftl 2>&1 | grep "struct literal body without path"
+
+# Check that a primary bundle without the desired message will use the fallback
+# bundle.
+broken: test.rs broken.ftl
+       $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/broken.ftl 2>&1 | grep "struct literal body without path"
 
 # Check that a locale can be loaded from the sysroot given a language
 # identifier by making a local copy of the sysroot and adding the custom locale
 # to it.
-sysroot: basic-translation.rs basic-translation.ftl
+sysroot: test.rs working.ftl
        mkdir $(FAKEROOT)
        ln -s $(SYSROOT)/* $(FAKEROOT)
        rm -f $(FAKEROOT)/lib
@@ -31,7 +44,7 @@ sysroot: basic-translation.rs basic-translation.ftl
        mkdir $(FAKEROOT)/lib/rustlib/src
        ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src
        mkdir -p $(FAKEROOT)/share/locale/zh-CN/
-       ln -s $(CURDIR)/basic-translation.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl
+       ln -s $(CURDIR)/working.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl
        $(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | grep "this is a test message"
 
 # Check that the compiler errors out when the sysroot requested cannot be
@@ -43,7 +56,7 @@ sysroot-missing:
 # Check that the compiler errors out when the sysroot requested cannot be
 # found. This test might start failing if there actually exists a Klingon
 # translation of rustc's error messages.
-sysroot-invalid: basic-translation.rs basic-translation.ftl
+sysroot-invalid: test.rs working.ftl
        mkdir $(FAKEROOT)
        ln -s $(SYSROOT)/* $(FAKEROOT)
        rm -f $(FAKEROOT)/lib
diff --git a/src/test/run-make/translation/basic-translation.ftl b/src/test/run-make/translation/basic-translation.ftl
deleted file mode 100644 (file)
index 4681b87..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-parser-struct-literal-body-without-path = this is a test message
-    .suggestion = this is a test suggestion
diff --git a/src/test/run-make/translation/basic-translation.rs b/src/test/run-make/translation/basic-translation.rs
deleted file mode 100644 (file)
index b8f5bff..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Exact error being tested isn't relevant, it just needs to be known that it uses Fluent-backed
-// diagnostics.
-
-struct Foo {
-    val: (),
-}
-
-fn foo() -> Foo {
-    val: (),
-}
-
-fn main() {
-    let x = foo();
-    x.val == 42;
-    let x = {
-        val: (),
-    };
-}
diff --git a/src/test/run-make/translation/broken.ftl b/src/test/run-make/translation/broken.ftl
new file mode 100644 (file)
index 0000000..4e35858
--- /dev/null
@@ -0,0 +1,3 @@
+# `foo` isn't provided by this diagnostic so it is expected that the fallback message is used.
+parser_struct_literal_body_without_path = this is a {$foo} message
+    .suggestion = this is a test suggestion
diff --git a/src/test/run-make/translation/missing.ftl b/src/test/run-make/translation/missing.ftl
new file mode 100644 (file)
index 0000000..77bbda3
--- /dev/null
@@ -0,0 +1,3 @@
+# `parser_struct_literal_body_without_path` isn't provided by this resource at all, so the
+# fallback should be used.
+foo = bar
diff --git a/src/test/run-make/translation/test.rs b/src/test/run-make/translation/test.rs
new file mode 100644 (file)
index 0000000..b8f5bff
--- /dev/null
@@ -0,0 +1,18 @@
+// Exact error being tested isn't relevant, it just needs to be known that it uses Fluent-backed
+// diagnostics.
+
+struct Foo {
+    val: (),
+}
+
+fn foo() -> Foo {
+    val: (),
+}
+
+fn main() {
+    let x = foo();
+    x.val == 42;
+    let x = {
+        val: (),
+    };
+}
diff --git a/src/test/run-make/translation/working.ftl b/src/test/run-make/translation/working.ftl
new file mode 100644 (file)
index 0000000..d5ea867
--- /dev/null
@@ -0,0 +1,2 @@
+parser_struct_literal_body_without_path = this is a test message
+    .suggestion = this is a test suggestion
index 69150443c29dc9059a3c2c0c10c807bcf3c94844..98ba8e99d820c79b1a8b20ef8e43402e591f5ae2 100644 (file)
@@ -14,7 +14,7 @@ pub trait GenericFoo<'a> {}
 // @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].name" '"F"'
 // @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.default" 'null'
 // @count - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" '$foo'
+// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" '$foo'
 // @count - "$.index[*][?(@.name=='generics')].inner.decl.inputs[*]" 1
 // @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][0]" '"f"'
 // @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].kind" '"generic"'
@@ -24,12 +24,12 @@ pub fn generics<F: Foo>(f: F) {}
 // @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.where_predicates" "[]"
 // @count - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[*]" 1
 // @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].name" '"impl Foo"'
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $foo
 // @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[*]" 1
 // @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][0]" '"f"'
 // @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].kind" '"impl_trait"'
 // @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[*]" 1
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $foo
 pub fn impl_trait(f: impl Foo) {}
 
 // @count - "$.index[*][?(@.name=='where_clase')].inner.generics.params[*]" 3
@@ -43,11 +43,11 @@ pub fn impl_trait(f: impl Foo) {}
 
 // @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F", "kind": "generic"}'
 // @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.id" $foo
 
 // @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.type" '{"inner": "G", "kind": "generic"}'
 // @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.inner.id" $generic_foo
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.id" $generic_foo
 // @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1
 // @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\"
 // @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
@@ -57,7 +57,7 @@ pub fn impl_trait(f: impl Foo) {}
 // @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.lifetime" \"\'b\"
 // @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.type" '{"inner": "H", "kind": "generic"}'
 // @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.id" $foo
 // @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]"
 // @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[*]" 1
 // @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\"
index 1a0f33fe3d28e50567b115b16e83526b873e9a61..46f250a99b9b665e993b5c27ac6111e3111e56ab 100644 (file)
@@ -11,7 +11,7 @@ pub trait Foo {}
 // @is - "$.index[*][?(@.name=='get_foo')].inner.decl.inputs" []
 // @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.kind" '"impl_trait"'
 // @count - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[*]" 1
-// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.id" $foo
 pub fn get_foo() -> impl Foo {
     Fooer {}
 }
index e777fabaa52a7f22e47fe57e3e948224d9092562..e55e1e9400dc6c4b50df07521866249641dc08fd 100644 (file)
@@ -10,7 +10,7 @@ pub trait Wham {}
 // @count - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
 // @is    - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
 // @has   - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
-// @has   - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
+// @has   - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
 // @is    - "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
 pub fn one_generic_param_fn<T: Wham>(w: T) {}
 
@@ -18,9 +18,9 @@ pub fn one_generic_param_fn<T: Wham>(w: T) {}
 // @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
 // @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
 // @has   - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
-// @has   - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
+// @has   - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
 // @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
 // @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
 // @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
-// @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $wham_id
+// @is    - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $wham_id
 pub fn one_synthetic_generic_param_fn(w: impl Wham) {}
diff --git a/src/test/rustdoc-json/impls/auto.rs b/src/test/rustdoc-json/impls/auto.rs
new file mode 100644 (file)
index 0000000..fb32d7c
--- /dev/null
@@ -0,0 +1,18 @@
+#![feature(no_core, auto_traits, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub auto trait Bar {}
+
+/// has span
+impl Foo {
+    pub fn baz(&self) {}
+}
+
+// Testing spans, so all tests below code
+// @is auto.json "$.index[*][?(@.kind=='impl' && @.inner.synthetic==true)].span" null
+// @is - "$.index[*][?(@.docs=='has span')].span.begin" "[10, 0]"
+// @is - "$.index[*][?(@.docs=='has span')].span.end" "[12, 1]"
+pub struct Foo;
diff --git a/src/test/rustdoc-json/impls/import_from_private.rs b/src/test/rustdoc-json/impls/import_from_private.rs
new file mode 100644 (file)
index 0000000..ef4d8aa
--- /dev/null
@@ -0,0 +1,24 @@
+// https://github.com/rust-lang/rust/issues/100252
+
+#![feature(no_core)]
+#![no_core]
+
+mod bar {
+    // @set baz = import_from_private.json "$.index[*][?(@.kind=='struct')].id"
+    pub struct Baz;
+    // @set impl = - "$.index[*][?(@.kind=='impl')].id"
+    impl Baz {
+        // @set doit = - "$.index[*][?(@.kind=='method')].id"
+        pub fn doit() {}
+    }
+}
+
+// @set import = - "$.index[*][?(@.kind=='import')].id"
+pub use bar::Baz;
+
+// FIXME(adotinthevoid): Use hasexact once #99474 lands
+
+// @has - "$.index[*][?(@.kind=='module')].inner.items[*]" $import
+// @is  - "$.index[*][?(@.kind=='import')].inner.id" $baz
+// @has - "$.index[*][?(@.kind=='struct')].inner.impls[*]" $impl
+// @has - "$.index[*][?(@.kind=='impl')].inner.items[*]" $doit
index 486a8e713f811b50a860337df062bd6d204230dd..ce2f3912ba650168f9f4630c8acde94aaf32ccd6 100644 (file)
@@ -9,18 +9,18 @@ pub trait Loud {}
 
 // @set very_loud_id = - "$.index[*][?(@.name=='VeryLoud')].id"
 // @count - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[*]" 1
-// @is -    "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.inner.id" $loud_id
+// @is -    "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.id" $loud_id
 pub trait VeryLoud: Loud {}
 
 // @set sounds_good_id = - "$.index[*][?(@.name=='SoundsGood')].id"
 pub trait SoundsGood {}
 
 // @count - "$.index[*][?(@.name=='MetalBand')].inner.bounds[*]" 2
-// @is -    "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.inner.id" $very_loud_id
-// @is -    "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.inner.id" $sounds_good_id
+// @is -    "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.id" $very_loud_id
+// @is -    "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.id" $sounds_good_id
 pub trait MetalBand: VeryLoud + SoundsGood {}
 
 // @count - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[*]" 2
-// @is -    "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.inner.id" $very_loud_id
-// @is -    "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.inner.id" $sounds_good_id
+// @is -    "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.id" $very_loud_id
+// @is -    "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.id" $sounds_good_id
 pub trait DnabLatem: SoundsGood + VeryLoud {}
index c18b54d1fdf0ed18bba992190874850bed4e7a16..690dccc8287042e30095d29795928afae00453b5 100644 (file)
 // @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].generic_params" []
 // @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].generic_params" []
 // @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].generic_params" []
-// @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.inner.name" '"Fn"'
-// @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.inner.name" '"Send"'
-// @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].trait.inner.name" '"Sync"'
-// @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.inner.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}'
+// @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.name" '"Fn"'
+// @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.name" '"Send"'
+// @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].trait.name" '"Sync"'
+// @is    - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}'
 pub type SyncIntGen = Box<dyn Fn() -> i32 + Send + Sync + 'static>;
 
 // @is - "$.index[*][?(@.name=='RefFn')].kind" \"typedef\"
 // @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.lifetime" null
 // @count - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[*]" 1
 // @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.kind" '"resolved_path"'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.name" '"Fn"'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.inputs[0].kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.inputs[0].inner.lifetime" "\"'b\""
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.output.kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.output.inner.lifetime" "\"'b\""
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.name" '"Fn"'
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.inputs[0].kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.inputs[0].inner.lifetime" "\"'b\""
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.output.kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.output.inner.lifetime" "\"'b\""
 pub type RefFn<'a> = &'a dyn for<'b> Fn(&'b i32) -> &'b i32;
 
-// @is    - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.inner.name" '"Send"'
-// @is    - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.inner.name" '"Debug"'
+// @is    - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.name" '"Send"'
+// @is    - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.name" '"Debug"'
 pub type WeirdOrder = Box<dyn Send + Debug>;
index 9311737be0fec0ead932028d4332be8e5b4b034d..5b0c4caee21869550698fa747f3635939d2cd9f7 100644 (file)
@@ -19,7 +19,7 @@ pub fn genfn<F>(f: F)
 // @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.lifetime" null
 // @count - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[*]" 1
 // @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
-// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].trait.inner.name" '"Fn"'
+// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].trait.name" '"Fn"'
 pub fn dynfn(f: &dyn for<'a, 'b> Fn(&'a i32, &'b i32)) {
     let zero = 0;
     f(&zero, &zero);
index 6dc41231559c0dc25d2440e772b477f4fed1fc72..236469ce9797a643843f62a538ee68962571db55 100644 (file)
@@ -38,6 +38,7 @@
     -Z                        emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
     -Z                           emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes)
     -Z               export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries
+    -Z                   extra-const-ub-checks=val -- turns on more checks to detect const UB, which can be slow (default: no)
     -Z                             fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
     -Z              force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
     -Z                                    fuel=val -- set the optimization fuel quota for a crate
index a95d6c462069755329d3d6b81d8b46d8e4ec4bfd..4c8d02310955972b193f230aeecd500f342eef7e 100644 (file)
@@ -24,5 +24,5 @@ mod private_module {
 }
 
 // @has foo/all.html '//a[@href="struct.ReexportedStruct.html"]' 'ReexportedStruct'
-// @!has foo/all.html 'private_module'
+// @!hasraw foo/all.html 'private_module'
 pub use private_module::ReexportedStruct;
index a79e93145ba7db99905043b11be0b3ab8b764a83..97b7739b4c975f83794ea27bb64648cfaab68614 100644 (file)
@@ -5,7 +5,7 @@ pub trait Foo {
     const FOO: usize = 12 + 1;
     // @has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool'
     const FOO_NO_DEFAULT: bool;
-    // @!has - FOO_HIDDEN
+    // @!hasraw - FOO_HIDDEN
     #[doc(hidden)]
     const FOO_HIDDEN: u8 = 0;
 }
@@ -18,7 +18,7 @@ impl Foo for Bar {
     const FOO: usize = 12;
     // @has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool'
     const FOO_NO_DEFAULT: bool = false;
-    // @!has - FOO_HIDDEN
+    // @!hasraw - FOO_HIDDEN
     #[doc(hidden)]
     const FOO_HIDDEN: u8 = 0;
 }
@@ -50,9 +50,9 @@ impl Bar {
 }
 
 impl Bar {
-    // @!has assoc_consts/struct.Bar.html 'BAR_PRIVATE'
+    // @!hasraw assoc_consts/struct.Bar.html 'BAR_PRIVATE'
     const BAR_PRIVATE: char = 'a';
-    // @!has assoc_consts/struct.Bar.html 'BAR_HIDDEN'
+    // @!hasraw assoc_consts/struct.Bar.html 'BAR_HIDDEN'
     #[doc(hidden)]
     pub const BAR_HIDDEN: &'static str = "a";
 }
index 8455dd9ef95f4f4777b6e195691050ece8d8207e..594501b22b142dbd5f74c17dad09d70642b87b88 100644 (file)
@@ -20,7 +20,7 @@ pub const fn foo() -> u32 { 42 }
 pub const unsafe fn foo_unsafe() -> u32 { 42 }
 
 // @has 'foo/fn.foo2.html' '//pre' 'pub const fn foo2() -> u32'
-// @!has - '//span[@class="since"]'
+// @!hasraw - '//span[@class="since"]'
 #[unstable(feature = "humans", issue = "none")]
 pub const fn foo2() -> u32 { 42 }
 
@@ -32,7 +32,7 @@ pub const fn bar2() -> u32 { 42 }
 
 
 // @has 'foo/fn.foo2_gated.html' '//pre' 'pub const unsafe fn foo2_gated() -> u32'
-// @!has - '//span[@class="since"]'
+// @!hasraw - '//span[@class="since"]'
 #[unstable(feature = "foo2", issue = "none")]
 pub const unsafe fn foo2_gated() -> u32 { 42 }
 
@@ -43,7 +43,7 @@ pub const fn bar2() -> u32 { 42 }
 pub const unsafe fn bar2_gated() -> u32 { 42 }
 
 // @has 'foo/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32'
-// @!has - '//span[@class="since"]'
+// @!hasraw - '//span[@class="since"]'
 pub const unsafe fn bar_not_gated() -> u32 { 42 }
 
 pub struct Foo;
index efd250ce9f00f24a1a473872c8c7b3f6c84589de..e419d2631f6847e8824084a8cf44852d272d6dd1 100644 (file)
@@ -5,8 +5,8 @@
 
 impl Foo0 {
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.1: fn_with_doc'
-    // @has - 'fn_with_doc short'
-    // @has - 'fn_with_doc full'
+    // @hasraw - 'fn_with_doc short'
+    // @hasraw - 'fn_with_doc full'
     /// fn_with_doc short
     ///
     /// fn_with_doc full
@@ -52,8 +52,8 @@ fn fn_def_def_without_doc() {}
 
 impl Bar for Foo1 {
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.3: fn_empty_with_doc'
-    // @has - 'fn_empty_with_doc_impl short'
-    // @has - 'fn_empty_with_doc_impl full'
+    // @hasraw - 'fn_empty_with_doc_impl short'
+    // @hasraw - 'fn_empty_with_doc_impl full'
     /// fn_empty_with_doc_impl short
     ///
     /// fn_empty_with_doc_impl full
@@ -63,8 +63,8 @@ fn fn_empty_with_doc() {}
     fn fn_empty_without_doc() {}
 
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.5: fn_def_with_doc'
-    // @has - 'fn_def_with_doc_impl short'
-    // @has - 'fn_def_with_doc_impl full'
+    // @hasraw - 'fn_def_with_doc_impl short'
+    // @hasraw - 'fn_def_with_doc_impl full'
     /// fn_def_with_doc_impl short
     ///
     /// fn_def_with_doc_impl full
@@ -74,8 +74,8 @@ fn fn_def_with_doc() {}
     fn fn_def_without_doc() {}
 
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.7: fn_def_def_with_doc'
-    // @has - 'fn_def_def_with_doc short'
-    // @!has - 'fn_def_def_with_doc full'
+    // @hasraw - 'fn_def_def_with_doc short'
+    // @!hasraw - 'fn_def_def_with_doc full'
 
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.8: fn_def_def_without_doc'
 }
@@ -85,34 +85,34 @@ fn fn_def_without_doc() {}
 
 impl Bar for Foo2 {
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.3: fn_empty_with_doc'
-    // @has - 'fn_empty_with_doc short'
-    // @!has - 'fn_empty_with_doc full'
+    // @hasraw - 'fn_empty_with_doc short'
+    // @!hasraw - 'fn_empty_with_doc full'
     fn fn_empty_with_doc() {}
 
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.4: fn_empty_without_doc'
-    // @has - 'fn_empty_without_doc_impl short'
-    // @has - 'fn_empty_without_doc_impl full'
+    // @hasraw - 'fn_empty_without_doc_impl short'
+    // @hasraw - 'fn_empty_without_doc_impl full'
     /// fn_empty_without_doc_impl short
     ///
     /// fn_empty_without_doc_impl full
     fn fn_empty_without_doc() {}
 
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.5: fn_def_with_doc'
-    // @has - 'fn_def_with_doc short'
-    // @!has - 'fn_def_with_doc full'
+    // @hasraw - 'fn_def_with_doc short'
+    // @!hasraw - 'fn_def_with_doc full'
     fn fn_def_with_doc() {}
 
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.6: fn_def_without_doc'
-    // @has - 'fn_def_without_doc_impl short'
-    // @has - 'fn_def_without_doc_impl full'
+    // @hasraw - 'fn_def_without_doc_impl short'
+    // @hasraw - 'fn_def_without_doc_impl full'
     /// fn_def_without_doc_impl short
     ///
     /// fn_def_without_doc_impl full
     fn fn_def_without_doc() {}
 
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.7: fn_def_def_with_doc'
-    // @has - 'fn_def_def_with_doc short'
-    // @!has - 'fn_def_def_with_doc full'
+    // @hasraw - 'fn_def_def_with_doc short'
+    // @!hasraw - 'fn_def_def_with_doc full'
 
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.8: fn_def_def_without_doc'
 }
index 5a32554f972b726bdc9a9343bd2d018b97324761..9b4ceb4f9cd86bbd29c0eb55840e718dc423a040 100644 (file)
 type ARef<'a> = Ref<'a>;
 
 // @has foo/fn.test1.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
 pub fn test1(a: &u32) -> Ref {
     Ref(a)
 }
 
 // @has foo/fn.test2.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
 pub fn test2(a: &u32) -> Ref<'_> {
     Ref(a)
 }
 
 // @has foo/fn.test3.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
 pub fn test3(a: &u32) -> ARef {
     Ref(a)
 }
 
 // @has foo/fn.test4.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
 pub fn test4(a: &u32) -> ARef<'_> {
     Ref(a)
 }
 
 // Ensure external paths in inlined docs also display elided lifetime
 // @has foo/bar/fn.test5.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
 // @has foo/bar/fn.test6.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
 #[doc(inline)]
 pub extern crate bar;
index c2a98049a48cb7000f9e5ad0db4d7fe9a06c81cc..147e11e5882e09c5ce4c0ba190794564bf44d94d 100644 (file)
@@ -1,16 +1,16 @@
 // compile-flags: --document-private-items
 
 // @has 'empty_mod_private/index.html' '//a[@href="foo/index.html"]' 'foo'
-// @has 'empty_mod_private/sidebar-items.js' 'foo'
+// @hasraw 'empty_mod_private/sidebar-items.js' 'foo'
 // @matches 'empty_mod_private/foo/index.html' '//h1' 'Module empty_mod_private::foo'
 mod foo {}
 
 // @has 'empty_mod_private/index.html' '//a[@href="bar/index.html"]' 'bar'
-// @has 'empty_mod_private/sidebar-items.js' 'bar'
+// @hasraw 'empty_mod_private/sidebar-items.js' 'bar'
 // @matches 'empty_mod_private/bar/index.html' '//h1' 'Module empty_mod_private::bar'
 mod bar {
     // @has 'empty_mod_private/bar/index.html' '//a[@href="baz/index.html"]' 'baz'
-    // @has 'empty_mod_private/bar/sidebar-items.js' 'baz'
+    // @hasraw 'empty_mod_private/bar/sidebar-items.js' 'baz'
     // @matches 'empty_mod_private/bar/baz/index.html' '//h1' 'Module empty_mod_private::bar::baz'
     mod baz {}
 }
index d097fcf839cba56d0020f90a027de79a78b40409..c0bac40212c90a8218b0d3a7d86d2399a603ecbd 100644 (file)
@@ -1,14 +1,14 @@
 // @has 'empty_mod_public/index.html' '//a[@href="foo/index.html"]' 'foo'
-// @has 'empty_mod_public/sidebar-items.js' 'foo'
+// @hasraw 'empty_mod_public/sidebar-items.js' 'foo'
 // @matches 'empty_mod_public/foo/index.html' '//h1' 'Module empty_mod_public::foo'
 pub mod foo {}
 
 // @has 'empty_mod_public/index.html' '//a[@href="bar/index.html"]' 'bar'
-// @has 'empty_mod_public/sidebar-items.js' 'bar'
+// @hasraw 'empty_mod_public/sidebar-items.js' 'bar'
 // @matches 'empty_mod_public/bar/index.html' '//h1' 'Module empty_mod_public::bar'
 pub mod bar {
     // @has 'empty_mod_public/bar/index.html' '//a[@href="baz/index.html"]' 'baz'
-    // @has 'empty_mod_public/bar/sidebar-items.js' 'baz'
+    // @hasraw 'empty_mod_public/bar/sidebar-items.js' 'baz'
     // @matches 'empty_mod_public/bar/baz/index.html' '//h1' 'Module empty_mod_public::bar::baz'
     pub mod baz {}
 }
index 665aa38b11ebac0562081b386ac13ebea3846041..d8241ab96f6ddce6036fddd835845156a70100bb 100644 (file)
@@ -5,7 +5,7 @@
 pub struct Foo;
 
 // @has foo/struct.Foo.html
-// @!has - 'Auto Trait Implementations'
+// @!hasraw - 'Auto Trait Implementations'
 impl !Send for Foo {}
 impl !Sync for Foo {}
 impl !std::marker::Unpin for Foo {}
index 38ecf5283108f047462a5832192b6001e4689b30..91499100ec6872fd32734eb6140026c6a8009a1a 100644 (file)
@@ -8,6 +8,6 @@ pub trait Trait {
 // Make sure that the elided lifetime shows up
 
 // @has foo/type.T.html
-// @has - "pub type T = "
-// @has - "&lt;'_&gt;"
+// @hasraw - "pub type T = "
+// @hasraw - "&lt;'_&gt;"
 pub type T = fn(&<() as Trait>::Gat<'_>);
index 8f33a6604c2195d317c696f806e6802ab0b7c34d..26e2e0e0660088ebb7dc3e937c0acff45bb30b8a 100644 (file)
@@ -11,7 +11,7 @@ pub mod __hidden {
 }
 
 // @has foo/trait.Clone.html
-// @!has - 'Foo'
+// @!hasraw - 'Foo'
 // @has implementors/core/clone/trait.Clone.js
-// @!has - 'Foo'
+// @!hasraw - 'Foo'
 pub use std::clone::Clone;
index f2f6173d26db9177ac0130de9019507f1bbfdd20..00a05a7c26f0e9c7e03ded2f0b5ca8124663bb0f 100644 (file)
@@ -15,5 +15,5 @@
 /// ```
 pub fn foo() {}
 
-// @!has hidden_line/fn.foo.html invisible
+// @!hasraw hidden_line/fn.foo.html invisible
 // @matches - //pre "#\[derive\(PartialEq\)\] // Bar"
index 27181d489f59d3c4f4d3be8b38b3f4355ab168bd..543d8f768a61c393d26f1890fb6ac28b9615fcca 100644 (file)
@@ -17,13 +17,13 @@ fn this_should_be_hidden() {}
 }
 
 // @has foo/struct.Foo.html
-// @!has - 'Methods'
+// @!hasraw - 'Methods'
 // @!has - '//code' 'impl Foo'
-// @!has - 'this_should_be_hidden'
+// @!hasraw - 'this_should_be_hidden'
 pub use hidden::Foo;
 
 // @has foo/struct.Bar.html
-// @!has - 'Methods'
+// @!hasraw - 'Methods'
 // @!has - '//code' 'impl Bar'
-// @!has - 'this_should_be_hidden'
+// @!hasraw - 'this_should_be_hidden'
 pub use hidden::Bar;
index c30d6ed7b52203d42f524a095311f3be286ea26c..0bf7cabc43b2401a29df1e752b054b7d0609603d 100644 (file)
@@ -5,7 +5,7 @@
 
 extern crate unstable_trait;
 
-// @has foo/struct.Foo.html 'bar'
-// @has foo/struct.Foo.html 'bar2'
+// @hasraw foo/struct.Foo.html 'bar'
+// @hasraw foo/struct.Foo.html 'bar2'
 #[doc(inline)]
 pub use unstable_trait::Foo;
index 6c5e79d5aa32380bb781b3221dd6540f9ee66c00..34733f1f8ccb8518cf7d722599ef08099da30f06 100644 (file)
@@ -12,9 +12,9 @@ pub struct Bar<T> { t: T }
 // full impl string.  Instead, just make sure something from each part
 // is mentioned.
 
-// @has implementors/rustdoc_impl_parts_crosscrate/trait.AnAutoTrait.js Bar
-// @has - Send
-// @has - !AnAutoTrait
-// @has - Copy
+// @hasraw implementors/rustdoc_impl_parts_crosscrate/trait.AnAutoTrait.js Bar
+// @hasraw - Send
+// @hasraw - !AnAutoTrait
+// @hasraw - Copy
 impl<T: Send> !rustdoc_impl_parts_crosscrate::AnAutoTrait for Bar<T>
     where T: Copy {}
index 54c3f856ddb3c0ad8a2f901c2e8a3e3ae9a5d0c7..4f681c78ee1171ae4fdcc861d0b88a2c410e27f3 100644 (file)
@@ -3,11 +3,11 @@
 trait MyTrait {}
 impl MyTrait for i32 {}
 
-// @has impl_trait_alias/type.Foo.html 'Foo'
+// @hasraw impl_trait_alias/type.Foo.html 'Foo'
 /// debug type
 pub type Foo = impl MyTrait;
 
-// @has impl_trait_alias/fn.foo.html 'foo'
+// @hasraw impl_trait_alias/fn.foo.html 'foo'
 /// debug function
 pub fn foo() -> Foo {
     1
index 8f0c4e5e6418485cbb4709ace79c66a9f8f38d4d..a1124d2094c0fb6177d555c54fe0a5e8d24aee9e 100644 (file)
@@ -4,6 +4,6 @@
 
 
 // @has add_docs/struct.MyStruct.html
-// @has add_docs/struct.MyStruct.html "Doc comment from ‘pub use’, Doc comment from definition"
+// @hasraw add_docs/struct.MyStruct.html "Doc comment from ‘pub use’, Doc comment from definition"
 /// Doc comment from 'pub use',
 pub use inner::MyStruct;
index 231805a52b90e25096d328da70eccc42b776f59d..811827a17feebcc0e301e608b34bec3eff70962f 100644 (file)
@@ -7,10 +7,10 @@
 extern crate assoc_items;
 
 // @has foo/struct.MyStruct.html
-// @!has - 'PrivateConst'
+// @!hasraw - 'PrivateConst'
 // @has - '//*[@id="associatedconstant.PublicConst"]' 'pub const PublicConst: u8'
 // @has - '//*[@class="docblock"]' 'docs for PublicConst'
-// @!has - 'private_method'
+// @!hasraw - 'private_method'
 // @has - '//*[@id="method.public_method"]' 'pub fn public_method()'
 // @has - '//*[@class="docblock"]' 'docs for public_method'
 // @has - '//*[@id="associatedconstant.ConstNoDefault"]' 'const ConstNoDefault: i16'
index 97715737fd90da245c808611d399cda7cb9d93b4..28a4f4bac1a4a38006eaa38abb633325e20c88df 100644 (file)
@@ -5,8 +5,8 @@
 extern crate rustdoc_hidden;
 
 // @has hidden_use/index.html
-// @!has - 'rustdoc_hidden'
-// @!has - 'Bar'
+// @!hasraw - 'rustdoc_hidden'
+// @!hasraw - 'Bar'
 // @!has hidden_use/struct.Bar.html
 #[doc(hidden)]
 pub use rustdoc_hidden::Bar;
index 532a295c0f3f79dc4dfd42cfb216c8f436d993fd..a46550865c8b1e930374a44a26bc5cdb0b4498d0 100644 (file)
 // @has proc_macro/derive.SomeDerive.html
 
 // @has proc_macro/macro.some_proc_macro.html
-// @has - 'a proc-macro that swallows its input and does nothing.'
+// @hasraw - 'a proc-macro that swallows its input and does nothing.'
 pub use some_macros::some_proc_macro;
 
 // @has proc_macro/macro.reexported_macro.html
-// @has - 'Doc comment from the original crate'
+// @hasraw - 'Doc comment from the original crate'
 pub use some_macros::reexported_macro;
 
 // @has proc_macro/attr.some_proc_attr.html
-// @has - 'a proc-macro attribute that passes its item through verbatim.'
+// @hasraw - 'a proc-macro attribute that passes its item through verbatim.'
 pub use some_macros::some_proc_attr;
 
 // @has proc_macro/derive.SomeDerive.html
-// @has - 'a derive attribute that adds nothing to its input.'
+// @hasraw - 'a derive attribute that adds nothing to its input.'
 pub use some_macros::SomeDerive;
 
 // @has proc_macro/attr.first_attr.html
-// @has - 'Generated doc comment'
+// @hasraw - 'Generated doc comment'
 pub use some_macros::first_attr;
 
 // @has proc_macro/attr.second_attr.html
-// @has - 'Generated doc comment'
+// @hasraw - 'Generated doc comment'
 pub use some_macros::second_attr;
index a2f0d65efce4cb800b577da42275cae33dc8e0a2..8e1089d60ec5133df76ca86325b12b7eca413745 100644 (file)
@@ -12,14 +12,14 @@ mod mod1 {
 pub use mod1::*;
 
 // @has foo/index.html
-// @has - "mod1"
-// @has - "public_fn"
-// @!has - "private_fn"
+// @hasraw - "mod1"
+// @hasraw - "public_fn"
+// @!hasraw - "private_fn"
 // @has foo/fn.public_fn.html
 // @!has foo/fn.private_fn.html
 
 // @has foo/mod1/index.html
-// @has - "public_fn"
-// @has - "private_fn"
+// @hasraw - "public_fn"
+// @hasraw - "private_fn"
 // @has foo/mod1/fn.public_fn.html
 // @has foo/mod1/fn.private_fn.html
index 686e55de39264e87ded18749ec45291eec0f27b2..c592a4db19d98c42757bf37afe4e4226aaf908b7 100644 (file)
@@ -10,9 +10,9 @@ mod mod1 {
 pub use mod1::*;
 
 // @has foo/index.html
-// @!has - "mod1"
-// @has - "public_fn"
-// @!has - "private_fn"
+// @!hasraw - "mod1"
+// @hasraw - "public_fn"
+// @!hasraw - "private_fn"
 // @has foo/fn.public_fn.html
 // @!has foo/fn.private_fn.html
 
index f16d21ecdb1395756fe19434289aaf9dbe775f36..d8cbd42343b9d7026af5ad17bbcd1b28632cf18c 100644 (file)
@@ -15,31 +15,31 @@ mod mod2 {
 pub use mod1::*;
 
 // @has foo/index.html
-// @has - "mod1"
-// @has - "Mod1Public"
-// @!has - "Mod1Private"
-// @!has - "mod2"
-// @has - "Mod2Public"
-// @!has - "Mod2Private"
+// @hasraw - "mod1"
+// @hasraw - "Mod1Public"
+// @!hasraw - "Mod1Private"
+// @!hasraw - "mod2"
+// @hasraw - "Mod2Public"
+// @!hasraw - "Mod2Private"
 // @has foo/struct.Mod1Public.html
 // @!has foo/struct.Mod1Private.html
 // @has foo/struct.Mod2Public.html
 // @!has foo/struct.Mod2Private.html
 
 // @has foo/mod1/index.html
-// @has - "mod2"
-// @has - "Mod1Public"
-// @has - "Mod1Private"
-// @!has - "Mod2Public"
-// @!has - "Mod2Private"
+// @hasraw - "mod2"
+// @hasraw - "Mod1Public"
+// @hasraw - "Mod1Private"
+// @!hasraw - "Mod2Public"
+// @!hasraw - "Mod2Private"
 // @has foo/mod1/struct.Mod1Public.html
 // @has foo/mod1/struct.Mod1Private.html
 // @!has foo/mod1/struct.Mod2Public.html
 // @!has foo/mod1/struct.Mod2Private.html
 
 // @has foo/mod1/mod2/index.html
-// @has - "Mod2Public"
-// @has - "Mod2Private"
+// @hasraw - "Mod2Public"
+// @hasraw - "Mod2Private"
 // @has foo/mod1/mod2/struct.Mod2Public.html
 // @has foo/mod1/mod2/struct.Mod2Private.html
 
index d294d590e1b626a0eee4f2b692e0414fdf0614b7..303f1d61048893adf0994005e26754c323efe6bf 100644 (file)
@@ -13,12 +13,12 @@ mod mod2 {
 pub use mod1::*;
 
 // @has foo/index.html
-// @!has - "mod1"
-// @has - "Mod1Public"
-// @!has - "Mod1Private"
-// @!has - "mod2"
-// @has - "Mod2Public"
-// @!has - "Mod2Private"
+// @!hasraw - "mod1"
+// @hasraw - "Mod1Public"
+// @!hasraw - "Mod1Private"
+// @!hasraw - "mod2"
+// @hasraw - "Mod2Public"
+// @!hasraw - "Mod2Private"
 // @has foo/struct.Mod1Public.html
 // @!has foo/struct.Mod1Private.html
 // @has foo/struct.Mod2Public.html
index a972d376aab33d99abcff143c6fd9e142e2771ae..de512fb26e6eff7d43b6282448aff2665480f3e6 100644 (file)
@@ -3,8 +3,8 @@ pub struct Foo {}
 }
 
 // @has hidden_use/index.html
-// @!has - 'private'
-// @!has - 'Foo'
+// @!hasraw - 'private'
+// @!hasraw - 'Foo'
 // @!has hidden_use/struct.Foo.html
 #[doc(hidden)]
 pub use private::Foo;
index dacc7cfb3cb76b64dd0365b21757ef007510409b..5c33c0037e48ef4d2e6b421ab22909f33297c290 100644 (file)
@@ -7,7 +7,7 @@ macro_rules! foo {
 
 // @has macro_by_example/macros/index.html
 pub mod macros {
-    // @!has - 'pub use foo as bar;'
+    // @!hasraw - 'pub use foo as bar;'
     // @has macro_by_example/macros/macro.bar.html
     // @has - '//*[@class="docblock"]' 'docs for foo'
     // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.2.3: text'
index 48539361fbfb559407674436ddaad6c8c51fcd4d..e4429ef33a928801f6c997729dc1593777f8e874 100644 (file)
@@ -4,7 +4,7 @@ pub mod foo {
 
 // @has please_inline/a/index.html
 pub mod a {
-    // @!has - 'pub use foo::'
+    // @!hasraw - 'pub use foo::'
     // @has please_inline/a/struct.Foo.html
     #[doc(inline)]
     pub use foo::Foo;
@@ -12,7 +12,7 @@ pub mod a {
 
 // @has please_inline/b/index.html
 pub mod b {
-    // @has - 'pub use foo::'
+    // @hasraw - 'pub use foo::'
     // @!has please_inline/b/struct.Foo.html
     #[feature(inline)]
     pub use foo::Foo;
index f316eb24a48514067dd5b5ad16e7201702c432a7..caad43a087c4eda9f516e6cc98710d51ee6acdc1 100644 (file)
@@ -3,13 +3,15 @@
 // Check that the unstable marker is not added for "rustc_private".
 
 // @!matches internal/index.html \
-//      '//*[@class="item-right docblock-short"]/span[@class="stab unstable"]'
+//      '//*[@class="item-right docblock-short"]/span[@class="stab unstable"]' \
+//      ''
 // @!matches internal/index.html \
-//      '//*[@class="item-right docblock-short"]/span[@class="stab internal"]'
+//      '//*[@class="item-right docblock-short"]/span[@class="stab internal"]' \
+//      ''
 // @matches - '//*[@class="item-right docblock-short"]' 'Docs'
 
-// @!has internal/struct.S.html '//*[@class="stab unstable"]'
-// @!has internal/struct.S.html '//*[@class="stab internal"]'
+// @!has internal/struct.S.html '//*[@class="stab unstable"]' ''
+// @!has internal/struct.S.html '//*[@class="stab internal"]' ''
 /// Docs
 pub struct S;
 
index ab088ab789d43b15d886cd3ec7a4402deb84e5e7..5440f582dff7e3360502b2f3b67674c0ff96965a 100644 (file)
@@ -25,11 +25,11 @@ fn g(&self, n: usize) {}
 }
 
 // @has 'extern_type/foreigntype.ExternType.html'
-// @has 'extern_type/fn.links_to_extern_type.html' \
+// @hasraw 'extern_type/fn.links_to_extern_type.html' \
 // 'href="foreigntype.ExternType.html#method.f"'
-// @has 'extern_type/fn.links_to_extern_type.html' \
+// @hasraw 'extern_type/fn.links_to_extern_type.html' \
 // 'href="foreigntype.ExternType.html#method.test"'
-// @has 'extern_type/fn.links_to_extern_type.html' \
+// @hasraw 'extern_type/fn.links_to_extern_type.html' \
 // 'href="foreigntype.ExternType.html#method.g"'
 /// See also [ExternType::f]
 /// See also [ExternType::test]
index ec007e36b726c8e8cd66a7090c6ac5b886aeb321..2fda637a64131f6d9b6299df8418a4db46f7f858 100644 (file)
@@ -1,6 +1,6 @@
 pub struct Foo;
 
-// @has issue_16265_1/traits/index.html 'source'
+// @hasraw issue_16265_1/traits/index.html 'source'
 pub mod traits {
     impl PartialEq for super::Foo {
         fn eq(&self, _: &super::Foo) -> bool {
index d5cd18d9daf9d80449a6f6d73280fbe6978baaf1..c3eb356171e856e7f36b96d6c3bb51f3c2eb8fc2 100644 (file)
@@ -1,4 +1,4 @@
-// @has issue_16265_2/index.html 'source'
+// @hasraw issue_16265_2/index.html 'source'
 
 trait Y {}
 impl Y for Option<u32> {}
index 2d2a7908fb187a619c60088af3eb48d7e681d633..7576ebb0305aaa5604cd2566397466e7c00ebea6 100644 (file)
@@ -6,7 +6,7 @@ pub mod str {
     #![doc(primitive = "str")]
 
     impl str {
-        // @has search-index.js foo
+        // @hasraw search-index.js foo
         #[rustc_allow_incoherent_impl]
         pub fn foo(&self) {}
     }
index 5dac8d87b089ca335e96963d66bcd49f87972251..08fd1833bcef33ebd373bab41c0cf9fb2dcb67ee 100644 (file)
@@ -16,10 +16,10 @@ mod Foo {
 }
 
 // @has issue_23812/Foo/index.html
-// @has - 'Outer comment'
-// @!has - '/// Outer comment'
-// @has - 'Inner comment'
-// @!has - '//! Inner comment'
+// @hasraw - 'Outer comment'
+// @!hasraw - '/// Outer comment'
+// @hasraw - 'Inner comment'
+// @!hasraw - '//! Inner comment'
 
 
 doc! {
@@ -30,7 +30,7 @@ mod Bar {
 }
 
 // @has issue_23812/Bar/index.html
-// @has - 'Outer block comment'
-// @!has - '/** Outer block comment */'
-// @has - 'Inner block comment'
-// @!has - '/*! Inner block comment */'
+// @hasraw - 'Outer block comment'
+// @!hasraw - '/** Outer block comment */'
+// @hasraw - 'Inner block comment'
+// @!hasraw - '/*! Inner block comment */'
index b74c3eb78ace4b0820b4a54847b38e507b49e208..9f2fd9071144fc0776321a3e9102db6d2bb79689 100644 (file)
@@ -3,8 +3,8 @@
 // ignore-cross-compile
 
 // @has issue_27104/index.html
-// @!has - 'extern crate std'
-// @!has - 'use std::prelude::'
+// @!hasraw - 'extern crate std'
+// @!hasraw - 'use std::prelude::'
 
-// @has - 'pub extern crate empty'
+// @hasraw - 'pub extern crate empty'
 pub extern crate empty;
index f3739dafdf2f13dea1bbd3b2c6bf0a832ebd9a90..65e0f7cb87b0c5f41b7fe3e3375453191f29d528 100644 (file)
@@ -4,11 +4,11 @@
 #![unstable(feature="test", issue="27759")]
 
 // @has issue_27759/unstable/index.html
-// @has - '<code>test</code>&nbsp;<a href="http://issue_url/27759">#27759</a>'
+// @hasraw - '<code>test</code>&nbsp;<a href="http://issue_url/27759">#27759</a>'
 #[unstable(feature="test", issue="27759")]
 pub mod unstable {
     // @has issue_27759/unstable/fn.issue.html
-    // @has - '<code>test_function</code>&nbsp;<a href="http://issue_url/12345">#12345</a>'
+    // @hasraw - '<code>test_function</code>&nbsp;<a href="http://issue_url/12345">#12345</a>'
     #[unstable(feature="test_function", issue="12345")]
     pub fn issue() {}
 }
index 28e1efec608dc024e69176cac6fddd40bf49c502..4364a9649b57b48ac11cfa970d342c13389cbce2 100644 (file)
@@ -4,5 +4,5 @@
 extern crate issue_29584;
 
 // @has issue_29584/struct.Foo.html
-// @!has - 'impl Bar for'
+// @!hasraw - 'impl Bar for'
 pub use issue_29584::Foo;
index e7a8ee239e2f95d9c78a47588b9be6949658d636..3eee374465d2bc4e482ddb161a9febc328704983 100644 (file)
@@ -1,8 +1,8 @@
 // @has issue_31899/index.html
-// @has - 'Make this line a bit longer.'
-// @!has - 'rust rust-example-rendered'
-// @!has - 'use ndarray::arr2'
-// @!has - 'prohibited'
+// @hasraw - 'Make this line a bit longer.'
+// @!hasraw - 'rust rust-example-rendered'
+// @!hasraw - 'use ndarray::arr2'
+// @!hasraw - 'prohibited'
 
 /// A tuple or fixed size array that can be used to index an array.
 /// Make this line a bit longer.
index 01f95538196f06925c7338a83ce8dd18607452cf..9c585497d354faaefa8213a546164b1bba29c573 100644 (file)
@@ -10,7 +10,7 @@
 
 // @has issue_32374/struct.T.html '//*[@class="stab deprecated"]' \
 //      '👎 Deprecated since 1.0.0: text'
-// @has - '<code>test</code>&nbsp;<a href="https://issue_url/32374">#32374</a>'
+// @hasraw - '<code>test</code>&nbsp;<a href="https://issue_url/32374">#32374</a>'
 // @matches issue_32374/struct.T.html '//*[@class="stab unstable"]' \
 //      '🔬 This is a nightly-only experimental API. \(test\s#32374\)$'
 /// Docs
index 13468c153132e7b602c9243b14b5e52f993db57a..5552300f9fe896db7fc63fb867b850e9af845661 100644 (file)
@@ -3,13 +3,13 @@
 // ignore-cross-compile
 
 // @has variant_struct/enum.Foo.html
-// @!has - 'pub qux'
-// @!has - 'pub(crate) qux'
-// @!has - 'pub Bar'
+// @!hasraw - 'pub qux'
+// @!hasraw - 'pub(crate) qux'
+// @!hasraw - 'pub Bar'
 extern crate variant_struct;
 
 // @has issue_32395/enum.Foo.html
-// @!has - 'pub qux'
-// @!has - 'pub(crate) qux'
-// @!has - 'pub Bar'
+// @!hasraw - 'pub qux'
+// @!hasraw - 'pub(crate) qux'
+// @!hasraw - 'pub Bar'
 pub use variant_struct::Foo;
index d96301f3ae736f35eaf5e95001d834fd3cf8b829..37da3dd1999753fdc14fd5cbb94dfb2eee06f30e 100644 (file)
@@ -5,7 +5,7 @@ mod second {
 }
 
 // @has foo/index.html
-// @!has - SomeTypeWithLongName
+// @!hasraw - SomeTypeWithLongName
 // @has foo/struct.SomeType.html
 // @!has foo/struct.SomeTypeWithLongName.html
 pub use second::{SomeTypeWithLongName as SomeType};
diff --git a/src/test/rustdoc/issue-41783.codeblock.html b/src/test/rustdoc/issue-41783.codeblock.html
new file mode 100644 (file)
index 0000000..b919935
--- /dev/null
@@ -0,0 +1,5 @@
+<code># single
+## double
+### triple
+<span class="attribute">#[outer]</span>
+<span class="attribute">#![inner]</span></code>
\ No newline at end of file
index cb9b9b1538951fc17043cedcd08cabbdcaf76a03..d67716028799b6e8f5785ebe1b5582d13689830f 100644 (file)
@@ -1,11 +1,9 @@
 // @has issue_41783/struct.Foo.html
-// @!has - 'space'
-// @!has - 'comment'
-// @has - '# <span class="ident">single'
-// @has - '## <span class="ident">double</span>'
-// @has - '### <span class="ident">triple</span>'
-// @has - '<span class="attribute">#[<span class="ident">outer</span>]</span>'
-// @has - '<span class="attribute">#![<span class="ident">inner</span>]</span>'
+// @!hasraw - 'space'
+// @!hasraw - 'comment'
+// @hasraw - '<span class="attribute">#[outer]</span>'
+// @hasraw - '<span class="attribute">#![inner]</span>'
+// @snapshot 'codeblock' - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]//pre/code'
 
 /// ```no_run
 /// # # space
index 52ce4159d823ec85b2fd5b8f9f42a88e2ed6b72b..832140e061b51cefa6fb126fa30fa3ac7a31714e 100644 (file)
@@ -5,7 +5,7 @@
 extern crate issue_53689;
 
 // @has foo/trait.MyTrait.html
-// @!has - 'MyStruct'
+// @!hasraw - 'MyStruct'
 // @count - '//*[h3="impl<T> MyTrait for T"]' 1
 pub trait MyTrait {}
 
index aef038c07d8917697e54c0a5e143d04b15b2bc36..4b6c37b94aa71535ffcdb2185bef8580d57d4592 100644 (file)
@@ -5,11 +5,11 @@
 // @has issue_61592/index.html
 // @has - '//a[@href="#reexports"]' 'Re-exports'
 // @has - '//code' 'pub use foo::FooTrait as _;'
-// @!has - '//a[@href="trait._.html"]'
+// @!has - '//a[@href="trait._.html"]' ''
 pub use foo::FooTrait as _;
 
 // @has issue_61592/index.html
 // @has - '//a[@href="#reexports"]' 'Re-exports'
 // @has - '//code' 'pub use foo::FooStruct as _;'
-// @!has - '//a[@href="struct._.html"]'
+// @!has - '//a[@href="struct._.html"]' ''
 pub use foo::FooStruct as _;
index 45544dbeea6a0e18346f383954affd95a3a07e1b..4f2da5e07bee1eea9a5a328f2d71dae58a299d05 100644 (file)
@@ -3,8 +3,8 @@
 #![no_core]
 #![feature(no_core)]
 
-// @matches 'issue_89852/sidebar-items.js' '"repro"'
-// @!matches 'issue_89852/sidebar-items.js' '"repro".*"repro"'
+// @matchesraw 'issue_89852/sidebar-items.js' '"repro"'
+// @!matchesraw 'issue_89852/sidebar-items.js' '"repro".*"repro"'
 
 #[macro_export]
 macro_rules! repro {
index 01aa8d00b707b58076fd2b97b69b5a909a244704..7a322ea6d3414ddc61eb816704f98e59616224f5 100644 (file)
@@ -6,4 +6,4 @@
 //!
 //! [foo]: url 'title & <stuff> & "things"'
 
-// @has 'foo/index.html' 'title &amp; &lt;stuff&gt; &amp; &quot;things&quot;'
+// @hasraw 'foo/index.html' 'title &amp; &lt;stuff&gt; &amp; &quot;things&quot;'
index 7576c1326b8e494c8902d21888a85976639d9d82..ee3010514417a7da47aaaf9b9761b7ebb166a740 100644 (file)
 //
 // compile-flags: --document-private-items
 
-// @has macro_document_private_duplicate/index.html 'Doc 1.'
-// @has macro_document_private_duplicate/macro.a_macro.html 'Doc 1.'
+// @hasraw macro_document_private_duplicate/index.html 'Doc 1.'
+// @hasraw macro_document_private_duplicate/macro.a_macro.html 'Doc 1.'
 /// Doc 1.
 macro_rules! a_macro {
     () => ()
 }
 
-// @has macro_document_private_duplicate/index.html 'Doc 2.'
-// @!has macro_document_private_duplicate/macro.a_macro.html 'Doc 2.'
+// @hasraw macro_document_private_duplicate/index.html 'Doc 2.'
+// @!hasraw macro_document_private_duplicate/macro.a_macro.html 'Doc 2.'
 /// Doc 2.
 macro_rules! a_macro {
     () => ()
index ae8b0e7229f91a1138e044b924c44af0bcd6729a..f135a3a9ca662dd362a4e9c85188b20b41a7a956 100644 (file)
@@ -6,13 +6,13 @@
 // This is a regression text for issue #88453.
 #![feature(decl_macro)]
 
-// @!has macro_private_not_documented/index.html 'a_macro'
+// @!hasraw macro_private_not_documented/index.html 'a_macro'
 // @!has macro_private_not_documented/macro.a_macro.html
 macro_rules! a_macro {
     () => ()
 }
 
-// @!has macro_private_not_documented/index.html 'another_macro'
+// @!hasraw macro_private_not_documented/index.html 'another_macro'
 // @!has macro_private_not_documented/macro.another_macro.html
 macro another_macro {
     () => ()
index efc3b21e6da99952af08845e512d4d689c828595..96f4126c7c277f06e3e450eaa99cf2e6b3e20667 100644 (file)
@@ -5,32 +5,27 @@
 
 // @has 'foo/macro.todo.html'
 // @has - '//span[@class="macro"]' 'macro_rules!'
-// @has - '//span[@class="ident"]' 'todo'
-// Note: the only op is the `+`
-// @count - '//pre[@class="rust macro"]//span[@class="op"]' 1
+// @hasraw - ' todo {'
 
-// @has - '{ () =&gt; { ... }; ($('
+// @hasraw - '{ () =&gt; { ... }; ($('
 // @has - '//span[@class="macro-nonterminal"]' '$'
 // @has - '//span[@class="macro-nonterminal"]' 'arg'
-// @has - ':'
-// @has - '//span[@class="ident"]' 'tt'
-// @has - '),'
-// @has - '//span[@class="op"]' '+'
-// @has - ') =&gt; { ... }; }'
+// @hasraw - ':tt)+'
+// @hasraw - ') =&gt; { ... }; }'
 pub use std::todo;
 
 mod mod1 {
     // @has 'foo/macro.macro1.html'
-    // @has - 'macro_rules!'
-    // @has - 'macro1'
-    // @has - '{ () =&gt; { ... }; ($('
+    // @hasraw - 'macro_rules!'
+    // @hasraw - 'macro1'
+    // @hasraw - '{ () =&gt; { ... }; ($('
     // @has - '//span[@class="macro-nonterminal"]' '$'
     // @has - '//span[@class="macro-nonterminal"]' 'arg'
-    // @has - ':'
-    // @has - 'expr'
-    // @has - '),'
-    // @has - '+'
-    // @has - ') =&gt; { ... }; }'
+    // @hasraw - ':'
+    // @hasraw - 'expr'
+    // @hasraw - '),'
+    // @hasraw - '+'
+    // @hasraw - ') =&gt; { ... }; }'
     #[macro_export]
     macro_rules! macro1 {
         () => {};
index b843e28e7b0d3a9e7ccd1c06e659618eeed01eb4..31e7072b5ce9bc7e05c4b596d777aaf991ad2d6d 100644 (file)
@@ -7,21 +7,21 @@
 //!
 //! [link]: https://example.com
 
-// @has search-index.js 'This <em>summary</em> has a link and <code>code</code>.'
-// @!has - 'second paragraph'
+// @hasraw search-index.js 'This <em>summary</em> has a link and <code>code</code>.'
+// @!hasraw - 'second paragraph'
 
 /// This `code` will be rendered in a code tag.
 ///
 /// This text should not be rendered.
 pub struct Sidebar;
 
-// @has search-index.js 'This <code>code</code> will be rendered in a code tag.'
-// @has summaries/sidebar-items.js 'This `code` will be rendered in a code tag.'
-// @!has - 'text should not be rendered'
+// @hasraw search-index.js 'This <code>code</code> will be rendered in a code tag.'
+// @hasraw summaries/sidebar-items.js 'This `code` will be rendered in a code tag.'
+// @!hasraw - 'text should not be rendered'
 
 /// ```text
 /// this block should not be rendered
 /// ```
 pub struct Sidebar2;
 
-// @!has summaries/sidebar-items.js 'block should not be rendered'
+// @!hasraw summaries/sidebar-items.js 'block should not be rendered'
index c7ad690d66e3e750474616e48202baaa66f5f12a..80d5b99c0b035df9b9eca5ce92070e461181d1e3 100644 (file)
@@ -7,24 +7,24 @@
 #[doc(masked)]
 extern crate masked;
 
-// @!has 'search-index.js' 'masked_method'
+// @!hasraw 'search-index.js' 'masked_method'
 
-// @!has 'foo/struct.String.html' 'MaskedTrait'
-// @!has 'foo/struct.String.html' 'masked_method'
+// @!hasraw 'foo/struct.String.html' 'MaskedTrait'
+// @!hasraw 'foo/struct.String.html' 'masked_method'
 pub use std::string::String;
 
-// @!has 'foo/trait.Clone.html' 'MaskedStruct'
+// @!hasraw 'foo/trait.Clone.html' 'MaskedStruct'
 pub use std::clone::Clone;
 
-// @!has 'foo/struct.MyStruct.html' 'MaskedTrait'
-// @!has 'foo/struct.MyStruct.html' 'masked_method'
+// @!hasraw 'foo/struct.MyStruct.html' 'MaskedTrait'
+// @!hasraw 'foo/struct.MyStruct.html' 'masked_method'
 pub struct MyStruct;
 
 impl masked::MaskedTrait for MyStruct {
     fn masked_method() {}
 }
 
-// @!has 'foo/trait.MyTrait.html' 'MaskedStruct'
+// @!hasraw 'foo/trait.MyTrait.html' 'MaskedStruct'
 pub trait MyTrait {}
 
 impl MyTrait for masked::MaskedStruct {}
index 198b3446c61b7ddad302788f873a7fd7ff512a5a..852f444e99b65d4af0486206078c1929a0515746 100644 (file)
@@ -2,4 +2,4 @@
 
 pub use std::marker::Send;
 
-// @!has foo/index.html 'Implementations'
+// @!hasraw foo/index.html 'Implementations'
index 1596f46740e8f3cede3df6837e3495a3050bbe40..12234d2cf7ef52cd99146bfe70e497ca2adc8fbe 100644 (file)
@@ -7,22 +7,22 @@ pub fn private_function() {}
 
     pub mod a_nested_module {
         // @has aCrate/a_nested_module/index.html '//a[@href="fn.a_nested_public_function.html"]' 'a_nested_public_function'
-        // @has aCrate/a_nested_module/fn.a_nested_public_function.html 'pub fn a_nested_public_function()'
+        // @hasraw aCrate/a_nested_module/fn.a_nested_public_function.html 'pub fn a_nested_public_function()'
         pub fn a_nested_public_function() {}
 
         // @has aCrate/a_nested_module/index.html '//a[@href="fn.another_nested_public_function.html"]' 'another_nested_public_function'
-        // @has aCrate/a_nested_module/fn.another_nested_public_function.html 'pub fn another_nested_public_function()'
+        // @hasraw aCrate/a_nested_module/fn.another_nested_public_function.html 'pub fn another_nested_public_function()'
         pub use a_nested_module::a_nested_public_function as another_nested_public_function;
     }
 
-    // @!has aCrate/a_nested_module/index.html 'yet_another_nested_public_function'
+    // @!hasraw aCrate/a_nested_module/index.html 'yet_another_nested_public_function'
     pub use a_nested_module::a_nested_public_function as yet_another_nested_public_function;
 
-    // @!has aCrate/a_nested_module/index.html 'one_last_nested_public_function'
+    // @!hasraw aCrate/a_nested_module/index.html 'one_last_nested_public_function'
     pub use a_nested_module::another_nested_public_function as one_last_nested_public_function;
 }
 
-// @!has aCrate/index.html 'a_module'
+// @!hasraw aCrate/index.html 'a_module'
 // @has aCrate/index.html '//a[@href="a_nested_module/index.html"]' 'a_nested_module'
 pub use a_module::a_nested_module;
 
@@ -36,7 +36,7 @@ pub fn a_nested_public_function() {}
 };
 
 // @has aCrate/index.html '//a[@href="fn.private_function.html"]' 'private_function'
-// @!has aCrate/fn.private_function.html 'a_module'
+// @!hasraw aCrate/fn.private_function.html 'a_module'
 // @has aCrate/index.html '//a[@href="fn.other_private_function.html"]' 'other_private_function'
-// @!has aCrate/fn.other_private_function.html 'a_module'
+// @!hasraw aCrate/fn.other_private_function.html 'a_module'
 pub use a_module::{other_private_function, private_function};
index c694d1456ef349558fd768982a37af526f518908..b2f89906480d6c22f692544c3e09e7529998e523 100644 (file)
@@ -2,5 +2,5 @@
 
 // compile-flags: -Z unstable-options --disable-per-crate-search
 
-// @!has 'foo/struct.Foo.html' '//*[id="crate-search"]'
+// @!has 'foo/struct.Foo.html' '//*[id="crate-search"]' ''
 pub struct Foo;
index a7504fbccfb508f9384b13b551698a2fc59fd2cc..2ab9d44be6dac9f3267f9e9485414d582397cf91 100644 (file)
@@ -51,7 +51,7 @@ pub fn g() {}
 
 // @has recursive_deref/struct.D.html '//h3[@class="code-header in-band"]' 'impl Deref for D'
 // We also check that `G::g` method isn't rendered because there is no `self` argument.
-// @!has '-' '//*[@id="deref-methods-G"]'
+// @!has '-' '//*[@id="deref-methods-G"]' ''
 impl Deref for D {
     type Target = E;
 
@@ -62,7 +62,7 @@ fn deref(&self) -> &Self::Target {
 
 // @has recursive_deref/struct.E.html '//h3[@class="code-header in-band"]' 'impl Deref for E'
 // We also check that `G::g` method isn't rendered because there is no `self` argument.
-// @!has '-' '//*[@id="deref-methods-G"]'
+// @!has '-' '//*[@id="deref-methods-G"]' ''
 impl Deref for E {
     type Target = F;
 
@@ -73,7 +73,7 @@ fn deref(&self) -> &Self::Target {
 
 // @has recursive_deref/struct.F.html '//h3[@class="code-header in-band"]' 'impl Deref for F'
 // We also check that `G::g` method isn't rendered because there is no `self` argument.
-// @!has '-' '//*[@id="deref-methods-G"]'
+// @!has '-' '//*[@id="deref-methods-G"]' ''
 impl Deref for F {
     type Target = G;
 
@@ -101,7 +101,7 @@ pub fn i() {}
 }
 
 // @has recursive_deref/struct.H.html '//h3[@class="code-header in-band"]' 'impl Deref for H'
-// @!has '-' '//*[@id="deref-methods-I"]'
+// @!has '-' '//*[@id="deref-methods-I"]' ''
 impl Deref for H {
     type Target = I;
 
index e2b232a6efb931f5185c3b536fc53f156340f8a9..599c429a6e1de388f306ae803c44ecdfb95ce2bd 100644 (file)
@@ -1,7 +1,7 @@
 #![crate_name = "foo"]
 
 // @has foo/fn.foo.html
-// @!has - '//a[@href="http://a.a"]'
+// @!has - '//a[@href="http://a.a"]' ''
 // @has - '//a[@href="#implementing-stuff-somewhere"]' 'Implementing stuff somewhere'
 // @has - '//a[@href="#another-one-urg"]' 'Another one urg'
 
index dd9c1a0b47dfccd8e829480e48e6ffe56d708d5b..efd366405bfeb0bbe9caa5328602cba92269c0db 100644 (file)
@@ -1,8 +1,8 @@
 #![crate_name = "foo"]
 
-// @has 'search-index.js' 'Foo short link.'
-// @!has - 'www.example.com'
-// @!has - 'More Foo.'
+// @hasraw 'search-index.js' 'Foo short link.'
+// @!hasraw - 'www.example.com'
+// @!hasraw - 'More Foo.'
 
 /// Foo short [link](https://www.example.com/).
 ///
index f1b78f17277d1348656754e3f4570091be7cc34f..d1d05eb886b00e144708c57e697eb7b9a3fba0ad 100644 (file)
@@ -2,25 +2,25 @@
 
 use std::ops::Deref;
 
-// @has search-index.js Foo
+// @hasraw search-index.js Foo
 pub use private::Foo;
 
 mod private {
     pub struct Foo;
     impl Foo {
-        pub fn test_method() {} // @has - test_method
-        fn priv_method() {} // @!has - priv_method
+        pub fn test_method() {} // @hasraw - test_method
+        fn priv_method() {} // @!hasraw - priv_method
     }
 
     pub trait PrivateTrait {
-        fn trait_method(&self) {} // @!has - priv_method
+        fn trait_method(&self) {} // @!hasraw - priv_method
     }
 }
 
 pub struct Bar;
 
 impl Deref for Bar {
-    // @!has search-index.js Target
+    // @!hasraw search-index.js Target
     type Target = Bar;
     fn deref(&self) -> &Bar { self }
 }
index 48b60885974afc7542ddcde7241d95f213f0c458..69e742ee74739a5429a1a2cb630e854cfe7185f8 100644 (file)
@@ -1,57 +1,57 @@
 // Test that the contents of constants are displayed as part of the
 // documentation.
 
-// @has show_const_contents/constant.CONST_S.html 'show this'
-// @!has show_const_contents/constant.CONST_S.html '; //'
+// @hasraw show_const_contents/constant.CONST_S.html 'show this'
+// @!hasraw show_const_contents/constant.CONST_S.html '; //'
 pub const CONST_S: &'static str = "show this";
 
-// @has show_const_contents/constant.CONST_I32.html '= 42;'
-// @!has show_const_contents/constant.CONST_I32.html '; //'
+// @hasraw show_const_contents/constant.CONST_I32.html '= 42;'
+// @!hasraw show_const_contents/constant.CONST_I32.html '; //'
 pub const CONST_I32: i32 = 42;
 
-// @has show_const_contents/constant.CONST_I32_HEX.html '= 0x42;'
-// @!has show_const_contents/constant.CONST_I32_HEX.html '; //'
+// @hasraw show_const_contents/constant.CONST_I32_HEX.html '= 0x42;'
+// @!hasraw show_const_contents/constant.CONST_I32_HEX.html '; //'
 pub const CONST_I32_HEX: i32 = 0x42;
 
-// @has show_const_contents/constant.CONST_NEG_I32.html '= -42;'
-// @!has show_const_contents/constant.CONST_NEG_I32.html '; //'
+// @hasraw show_const_contents/constant.CONST_NEG_I32.html '= -42;'
+// @!hasraw show_const_contents/constant.CONST_NEG_I32.html '; //'
 pub const CONST_NEG_I32: i32 = -42;
 
-// @has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
-// @!has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
+// @hasraw show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
+// @!hasraw show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
 pub const CONST_EQ_TO_VALUE_I32: i32 = 42i32;
 
-// @has show_const_contents/constant.CONST_CALC_I32.html '= _; // 43i32'
+// @hasraw show_const_contents/constant.CONST_CALC_I32.html '= _; // 43i32'
 pub const CONST_CALC_I32: i32 = 42 + 1;
 
-// @!has show_const_contents/constant.CONST_REF_I32.html '= &42;'
-// @!has show_const_contents/constant.CONST_REF_I32.html '; //'
+// @!hasraw show_const_contents/constant.CONST_REF_I32.html '= &42;'
+// @!hasraw show_const_contents/constant.CONST_REF_I32.html '; //'
 pub const CONST_REF_I32: &'static i32 = &42;
 
-// @has show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX; // 2_147_483_647i32'
+// @hasraw show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX; // 2_147_483_647i32'
 pub const CONST_I32_MAX: i32 = i32::MAX;
 
-// @!has show_const_contents/constant.UNIT.html '= ();'
-// @!has show_const_contents/constant.UNIT.html '; //'
+// @!hasraw show_const_contents/constant.UNIT.html '= ();'
+// @!hasraw show_const_contents/constant.UNIT.html '; //'
 pub const UNIT: () = ();
 
 pub struct MyType(i32);
 
-// @!has show_const_contents/constant.MY_TYPE.html '= MyType(42);'
-// @!has show_const_contents/constant.MY_TYPE.html '; //'
+// @!hasraw show_const_contents/constant.MY_TYPE.html '= MyType(42);'
+// @!hasraw show_const_contents/constant.MY_TYPE.html '; //'
 pub const MY_TYPE: MyType = MyType(42);
 
 pub struct MyTypeWithStr(&'static str);
 
-// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '= MyTypeWithStr("show this");'
-// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
+// @!hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '= MyTypeWithStr("show this");'
+// @!hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
 pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this");
 
-// @has show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;'
-// @has show_const_contents/constant.PI.html '; // 3.14159274f32'
+// @hasraw show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;'
+// @hasraw show_const_contents/constant.PI.html '; // 3.14159274f32'
 pub use std::f32::consts::PI;
 
-// @has show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32'
+// @hasraw show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32'
 #[allow(deprecated, deprecated_in_future)]
 pub use std::i32::MAX;
 
@@ -61,7 +61,7 @@ macro_rules! int_module {
     )
 }
 
-// @has show_const_contents/constant.MIN.html '= i16::MIN; // -32_768i16'
+// @hasraw show_const_contents/constant.MIN.html '= i16::MIN; // -32_768i16'
 int_module!(i16);
 
 // @has show_const_contents/constant.ESCAPE.html //pre '= r#"<script>alert("ESCAPE");</script>"#;'
index 9d2c1967757f103df4ef07dbb47c0fb40ff02b86..36718ebe1a6302712bfe1b8b9efaac5125c93bff 100644 (file)
@@ -1,13 +1,13 @@
 #![crate_name = "foo"]
 
 // @has foo/struct.Bar.html
-// @!has - '//*[@id="impl-Sized"]'
+// @!has - '//*[@id="impl-Sized"]' ''
 pub struct Bar {
     a: u16,
 }
 
 // @has foo/struct.Foo.html
-// @!has - '//*[@id="impl-Sized"]'
+// @!has - '//*[@id="impl-Sized"]' ''
 pub struct Foo<T: ?Sized>(T);
 
 // @has foo/struct.Unsized.html
index 5be6b98264a10b22b9de274a5778a3b6e57e2365..b5cc8bc8304e8d4d3dbeec28d00dd70118ca9696 100644 (file)
@@ -9,5 +9,5 @@ pub mod module_c {}
 
 pub mod module_a {}
 
-// @matches 'sort_modules_by_appearance/index.html' '(?s)module_b.*module_c.*module_a'
-// @matches 'sort_modules_by_appearance/sidebar-items.js' '"module_b".*"module_c".*"module_a"'
+// @matchesraw 'sort_modules_by_appearance/index.html' '(?s)module_b.*module_c.*module_a'
+// @matchesraw 'sort_modules_by_appearance/sidebar-items.js' '"module_b".*"module_c".*"module_a"'
index 968899dab8852ec19c6ffb0a51c4c6fe47c54218..4e166479063cc072c55a37d5d12857aa5a693e6f 100644 (file)
@@ -1,5 +1,5 @@
 #![crate_name = "foo"]
 
-// @has source-files.js source-file.rs
+// @hasraw source-files.js source-file.rs
 
 pub struct Foo;
index f1d49b9fcb20ae98d5eea6d56731d4cc870dd1f0..08c055c5b8dbbed9d72c661f7d498bf62414ceed 100644 (file)
@@ -1,18 +1,18 @@
 // compile-flags:-Z unstable-options --static-root-path /cache/
 
 // @has static_root_path/struct.SomeStruct.html
-// @matches - '"/cache/main\.js"'
-// @!matches - '"\.\./main\.js"'
-// @matches - 'data-root-path="\.\./"'
-// @!matches - '"/cache/search-index\.js"'
+// @matchesraw - '"/cache/main\.js"'
+// @!matchesraw - '"\.\./main\.js"'
+// @matchesraw - 'data-root-path="\.\./"'
+// @!matchesraw - '"/cache/search-index\.js"'
 pub struct SomeStruct;
 
 // @has src/static_root_path/static-root-path.rs.html
-// @matches - '"/cache/source-script\.js"'
-// @!matches - '"\.\./\.\./source-script\.js"'
-// @matches - '"\.\./\.\./source-files.js"'
-// @!matches - '"/cache/source-files\.js"'
+// @matchesraw - '"/cache/source-script\.js"'
+// @!matchesraw - '"\.\./\.\./source-script\.js"'
+// @matchesraw - '"\.\./\.\./source-files.js"'
+// @!matchesraw - '"/cache/source-files\.js"'
 
 // @has settings.html
-// @matches - '/cache/settings\.js'
-// @!matches - '\./settings\.js'
+// @matchesraw - '/cache/settings\.js'
+// @!matchesraw - '\./settings\.js'
index 858b589196e7219f896c293a58e63719e0e11b98..194f49f16d007cb6f6f603f776bcae982471b923 100644 (file)
@@ -2,7 +2,7 @@
 
 // @has foo/struct.Foo.html
 // @count - '//*[@class="docblock"]/div/table' 2
-// @!has - '//*[@class="docblock"]/table'
+// @!has - '//*[@class="docblock"]/table' ''
 /// | hello | hello2 |
 /// | ----- | ------ |
 /// | data  | data2  |
index c1df4613e3562ccd9dbc286bc2a098fcb8d36260..dbaf195e1a9636b369fa09e1ef46449663383dba 100644 (file)
@@ -62,7 +62,7 @@ pub struct PrivStruct {
 }
 
 // @has 'toggle_item_contents/enum.Enum.html'
-// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
+// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]' ''
 pub enum Enum {
     A, B, C,
     D {
@@ -72,7 +72,7 @@ pub enum Enum {
 }
 
 // @has 'toggle_item_contents/enum.EnumStructVariant.html'
-// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
+// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]' ''
 pub enum EnumStructVariant {
     A, B, C,
     D {
index b5a97c610daeac7ca9efe9575efbdf6add7faf16..fba594c38273cfb2f2a5b55ad666fcb13a354c9b 100644 (file)
@@ -59,7 +59,7 @@ fn defaulted_override(&self) {}
 
 // We check that associated items with default values aren't generated in the implementors list.
 impl MyTrait for (u8, u8) {
-    // @!has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-4"]'
+    // @!has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-4"]' ''
     type Assoc = bool;
     fn trait_function(&self) {}
 }
index 4f7e2dfe3b9a53310e1d63b20394649461869462..4d5173f6024c774e167a88a348408c3795ab9f7e 100644 (file)
@@ -40,7 +40,7 @@ fn b() {}
     fn c() {}
 
     // @has - '//*[@id="method.d"]/../../div[@class="docblock"]/p' 'Escaped formatting a*b*c* works'
-    // @!has - '//*[@id="method.d"]/../../div[@class="docblock"]/p/em'
+    // @!has - '//*[@id="method.d"]/../../div[@class="docblock"]/p/em' ''
     fn d() {}
 
     // @has - '//*[@id="impl-Trait-for-Struct"]/h3//a/@href' 'trait.Trait.html'
index 31426131bc2c1897312145ebd8d418413138468a..66bb409325c9980908dc4d89ac776b6a76d2a127 100644 (file)
@@ -5,7 +5,7 @@
 // @has - '//h3[@class="sidebar-title"]/a[@href="#fields"]' 'Tuple Fields'
 // @has - '//*[@id="structfield.0"]' '0: u32'
 // @has - '//*[@id="main-content"]/div[@class="docblock"]' 'hello'
-// @!has - '//*[@id="structfield.1"]'
+// @!has - '//*[@id="structfield.1"]' ''
 // @has - '//*[@id="structfield.2"]' '2: char'
 // @has - '//*[@id="structfield.3"]' '3: i8'
 // @has - '//*[@id="main-content"]/div[@class="docblock"]' 'not hello'
index a01fbd229508b1331627fb9f896f20e6ae9437b0..6bb5e10f8813734ab072a7b6103a3a213ef69014 100644 (file)
@@ -1,4 +1,4 @@
 // Tests that `--show-type-layout` is required in order to show layout info.
 
-// @!has type_layout_flag_required/struct.Foo.html 'Size: '
+// @!hasraw type_layout_flag_required/struct.Foo.html 'Size: '
 pub struct Foo(usize);
index e5c6e9dc3f9ed30f29c95cf134d565ed1ef7e386..5e0a0411a62b656135df2b24647c0f6da6641714 100644 (file)
@@ -1,84 +1,84 @@
 // compile-flags: --show-type-layout -Z unstable-options
 
-// @has type_layout/struct.Foo.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/struct.Foo.html 'Size: '
+// @hasraw - ' bytes'
 // @has - '//*[@id="layout"]/a[@href="#layout"]' ''
 pub struct Foo {
     pub a: usize,
     b: Vec<String>,
 }
 
-// @has type_layout/enum.Bar.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/enum.Bar.html 'Size: '
+// @hasraw - ' bytes'
 pub enum Bar<'a> {
     A(String),
     B(&'a str, (std::collections::HashMap<String, usize>, Foo)),
 }
 
-// @has type_layout/union.Baz.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/union.Baz.html 'Size: '
+// @hasraw - ' bytes'
 pub union Baz {
     a: &'static str,
     b: usize,
     c: &'static [u8],
 }
 
-// @has type_layout/struct.X.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/struct.X.html 'Size: '
+// @hasraw - ' bytes'
 pub struct X(usize);
 
-// @has type_layout/struct.Y.html 'Size: '
-// @has - '1 byte'
-// @!has - ' bytes'
+// @hasraw type_layout/struct.Y.html 'Size: '
+// @hasraw - '1 byte'
+// @!hasraw - ' bytes'
 pub struct Y(u8);
 
-// @has type_layout/struct.Z.html 'Size: '
-// @has - '0 bytes'
+// @hasraw type_layout/struct.Z.html 'Size: '
+// @hasraw - '0 bytes'
 pub struct Z;
 
 // We can't compute layout for generic types.
-// @has type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters'
-// @!has - 'Size: '
+// @hasraw type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters'
+// @!hasraw - 'Size: '
 pub struct Generic<T>(T);
 
 // We *can*, however, compute layout for types that are only generic over lifetimes,
 // because lifetimes are a type-system construct.
-// @has type_layout/struct.GenericLifetimes.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/struct.GenericLifetimes.html 'Size: '
+// @hasraw - ' bytes'
 pub struct GenericLifetimes<'a>(&'a str);
 
-// @has type_layout/struct.Unsized.html 'Size: '
-// @has - '(unsized)'
+// @hasraw type_layout/struct.Unsized.html 'Size: '
+// @hasraw - '(unsized)'
 pub struct Unsized([u8]);
 
-// @has type_layout/type.TypeAlias.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/type.TypeAlias.html 'Size: '
+// @hasraw - ' bytes'
 pub type TypeAlias = X;
 
-// @has type_layout/type.GenericTypeAlias.html 'Size: '
-// @has - '8 bytes'
+// @hasraw type_layout/type.GenericTypeAlias.html 'Size: '
+// @hasraw - '8 bytes'
 pub type GenericTypeAlias = (Generic<(u32, ())>, Generic<u32>);
 
 // Regression test for the rustdoc equivalent of #85103.
-// @has type_layout/type.Edges.html 'Encountered an error during type layout; the type failed to be normalized.'
+// @hasraw type_layout/type.Edges.html 'Encountered an error during type layout; the type failed to be normalized.'
 pub type Edges<'a, E> = std::borrow::Cow<'a, [E]>;
 
-// @!has type_layout/trait.MyTrait.html 'Size: '
+// @!hasraw type_layout/trait.MyTrait.html 'Size: '
 pub trait MyTrait {}
 
-// @has type_layout/enum.Variants.html 'Size: '
-// @has - '2 bytes'
-// @has - '<code>A</code>: 0 bytes'
-// @has - '<code>B</code>: 1 byte'
+// @hasraw type_layout/enum.Variants.html 'Size: '
+// @hasraw - '2 bytes'
+// @hasraw - '<code>A</code>: 0 bytes'
+// @hasraw - '<code>B</code>: 1 byte'
 pub enum Variants {
     A,
     B(u8),
 }
 
-// @has type_layout/enum.WithNiche.html 'Size: '
+// @hasraw type_layout/enum.WithNiche.html 'Size: '
 // @has - //p '4 bytes'
-// @has - '<code>None</code>: 0 bytes'
-// @has - '<code>Some</code>: 4 bytes'
+// @hasraw - '<code>None</code>: 0 bytes'
+// @hasraw - '<code>Some</code>: 4 bytes'
 pub enum WithNiche {
     None,
     Some(std::num::NonZeroU32),
index 4ecd62cded22e9a22c56ff6c0356978b483002ed..b68ec4557ad55c7baf3adac783ad4f6f2358ba67 100644 (file)
@@ -11,7 +11,7 @@ pub fn method_on_mystruct() {}
 // @has typedef/type.MyAlias.html
 // @has - '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' 'impl MyAlias'
 // @has - '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' 'impl MyTrait for MyAlias'
-// @has - 'Alias docstring'
+// @hasraw - 'Alias docstring'
 // @has - '//*[@class="sidebar"]//*[@class="location"]' 'MyAlias'
 // @has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Methods'
 // @has - '//*[@class="sidebar"]//a[@href="#trait-implementations"]' 'Trait Implementations'
index b10b1b8658db9664ffb4e9ea4cb82cf380009ed2..f5eabda59b7820e3bde8fe45e65493de2128d67f 100644 (file)
@@ -5,15 +5,15 @@
 
 // @has foo/fn.foo.html
 // @has - //pre 'foo('
-// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
-// @matches - '_z: .+impl.+trait\.Copy\.html.+, impl.+trait\.Clone\.html'
+// @matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
+// @matchesraw - '_z: .+impl.+trait\.Copy\.html.+, impl.+trait\.Clone\.html'
 pub fn foo(_x: impl Clone, _y: i32, _z: (impl Copy, impl Clone)) {
 }
 
 pub trait Trait {
     // @has foo/trait.Trait.html
-    // @has - 'method</a>('
-    // @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+    // @hasraw - 'method</a>('
+    // @matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
     fn method(&self, _x: impl std::fmt::Debug) {
     }
 }
@@ -22,30 +22,30 @@ fn method(&self, _x: impl std::fmt::Debug) {
 
 impl<T> S<T> {
     // @has foo/struct.S.html
-    // @has - 'bar</a>('
-    // @matches - '_bar: impl <a class="trait" href="[^"]+/trait\.Copy\.html"'
+    // @hasraw - 'bar</a>('
+    // @matchesraw - '_bar: impl <a class="trait" href="[^"]+/trait\.Copy\.html"'
     pub fn bar(_bar: impl Copy) {
     }
 
-    // @has - 'baz</a>('
-    // @matches - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
+    // @hasraw - 'baz</a>('
+    // @matchesraw - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
     pub fn baz(_baz: S<impl Clone>) {
     }
 
-    // @has - 'qux</a>('
-    // @matches - 'trait\.Read\.html'
+    // @hasraw - 'qux</a>('
+    // @matchesraw - 'trait\.Read\.html'
     pub fn qux(_qux: impl IntoIterator<Item = S<impl Read>>) {
     }
 }
 
-// @has - 'method</a>('
-// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+// @hasraw - 'method</a>('
+// @matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
 impl<T> Trait for S<T> {}
 
 // @has foo/fn.much_universe.html
-// @matches - 'T:.+Borrow.+impl .+trait\.Trait\.html'
-// @matches - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
-// @matches - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
+// @matchesraw - 'T:.+Borrow.+impl .+trait\.Trait\.html'
+// @matchesraw - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
+// @matchesraw - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
 pub fn much_universe<
     T: Borrow<impl Trait>,
     U: IntoIterator<Item = impl Iterator<Item = impl Clone>>,
diff --git a/src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl b/src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
new file mode 100644 (file)
index 0000000..84b6c3e
--- /dev/null
@@ -0,0 +1,2 @@
+some_slug = hi
+    .label-has-hyphens = test
index 372b1a2e453d210edbc8608b7e3d4f23c3881017..74b2aa1d44d1f9552a039d1b90b7ad4042c63dd3 100644 (file)
@@ -1 +1 @@
-missing-message = 
+missing_message =
diff --git a/src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl b/src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
new file mode 100644 (file)
index 0000000..07517c9
--- /dev/null
@@ -0,0 +1 @@
+this-slug-has-hyphens = hi
index 0390a07850b41ee04dbc88c843df682d503f7d8d..f0f35780666bbdd07a98ed3ae15488ea6c721f65 100644 (file)
@@ -55,6 +55,24 @@ mod duplicate {
     }
 }
 
+mod slug_with_hyphens {
+    use super::fluent_messages;
+
+    fluent_messages! {
+        slug_with_hyphens => "./slug-with-hyphens.ftl",
+//~^ ERROR name `this-slug-has-hyphens` contains a '-' character
+    }
+}
+
+mod label_with_hyphens {
+    use super::fluent_messages;
+
+    fluent_messages! {
+        label_with_hyphens => "./label-with-hyphens.ftl",
+//~^ ERROR attribute `label-has-hyphens` contains a '-' character
+    }
+}
+
 mod valid {
     use super::fluent_messages;
 
index 526bca43f694d529b921b4b2abf63ffe87bfd895..856642c4818da2058a55b5d9b1443fa0593c02a9 100644 (file)
@@ -22,11 +22,11 @@ LL |         missing_message => "./missing-message.ftl",
    |
    = help: see additional errors emitted
 
-error: expected a message field for "missing-message"
+error: expected a message field for "missing_message"
  --> ./missing-message.ftl:1:1
   |
-1 | missing-message = 
-  | ^^^^^^^^^^^^^^^^^^
+1 | missing_message =
+  | ^^^^^^^^^^^^^^^^^
   |
 
 error: overrides existing message: `key`
@@ -41,5 +41,21 @@ help: previously defined in this resource
 LL |         a => "./duplicate-a.ftl",
    |         ^
 
-error: aborting due to 4 previous errors
+error: name `this-slug-has-hyphens` contains a '-' character
+  --> $DIR/test.rs:62:9
+   |
+LL |         slug_with_hyphens => "./slug-with-hyphens.ftl",
+   |         ^^^^^^^^^^^^^^^^^
+   |
+   = help: replace any '-'s with '_'s
+
+error: attribute `label-has-hyphens` contains a '-' character
+  --> $DIR/test.rs:71:9
+   |
+LL |         label_with_hyphens => "./label-with-hyphens.ftl",
+   |         ^^^^^^^^^^^^^^^^^^
+   |
+   = help: replace any '-'s with '_'s
+
+error: aborting due to 6 previous errors
 
index fa030a8f49d8c46a37a0e64c27cbe5537ab02824..bf49e7444583b55eecb43ecd31e8dc544f657aaa 100644 (file)
@@ -8,7 +8,7 @@ note: function defined here
   --> $DIR/complex.rs:11:4
    |
 LL | fn complex(_i: u32, _s: &str, _e: E, _f: F, _g: G, _x: X, _y: Y, _z: Z ) {}
-   |    ^^^^^^^ -------  --------  -----  -----  -----  -----  -----  ------
+   |    ^^^^^^^ -------  --------  -----  -----  -----  -----  -----  -----
 help: did you mean
    |
 LL |   complex(/* u32 */, &"", /* E */, F::X2, G{}, X {}, Y {}, Z {});
index 33f27d48fec80341baad7b6babbfd89917995b31..303f0869578535b96d33c2a39cfefbcca30e72a7 100644 (file)
@@ -24,7 +24,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:6:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
-   |    ^^^^^^^^^^^^ -------  -------
+   |    ^^^^^^^^^^^^          -------
 
 error[E0308]: mismatched types
   --> $DIR/invalid_arguments.rs:17:16
@@ -38,7 +38,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:6:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
-   |    ^^^^^^^^^^^^ -------  -------
+   |    ^^^^^^^^^^^^ -------
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/invalid_arguments.rs:18:3
@@ -66,7 +66,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:7:4
    |
 LL | fn two_arg_diff(_a: i32, _b: f32) {}
-   |    ^^^^^^^^^^^^ -------  -------
+   |    ^^^^^^^^^^^^          -------
 
 error[E0308]: mismatched types
   --> $DIR/invalid_arguments.rs:20:16
@@ -80,7 +80,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:7:4
    |
 LL | fn two_arg_diff(_a: i32, _b: f32) {}
-   |    ^^^^^^^^^^^^ -------  -------
+   |    ^^^^^^^^^^^^ -------
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/invalid_arguments.rs:21:3
@@ -108,7 +108,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:8:4
    |
 LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
-   |    ^^^^^^^^^^^^^^ -------  -------  --------
+   |    ^^^^^^^^^^^^^^ -------
 
 error[E0308]: mismatched types
   --> $DIR/invalid_arguments.rs:25:21
@@ -122,7 +122,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:8:4
    |
 LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
-   |    ^^^^^^^^^^^^^^ -------  -------  --------
+   |    ^^^^^^^^^^^^^^          -------
 
 error[E0308]: mismatched types
   --> $DIR/invalid_arguments.rs:26:26
@@ -136,7 +136,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:8:4
    |
 LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
-   |    ^^^^^^^^^^^^^^ -------  -------  --------
+   |    ^^^^^^^^^^^^^^                   --------
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/invalid_arguments.rs:28:3
@@ -207,7 +207,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:9:4
    |
 LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
-   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+   |    ^^^^^^^^^^^^^^^^ -------
 
 error[E0308]: mismatched types
   --> $DIR/invalid_arguments.rs:35:23
@@ -221,7 +221,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:9:4
    |
 LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
-   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+   |    ^^^^^^^^^^^^^^^^          -------
 
 error[E0308]: mismatched types
   --> $DIR/invalid_arguments.rs:36:26
@@ -235,7 +235,7 @@ note: function defined here
   --> $DIR/invalid_arguments.rs:9:4
    |
 LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
-   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+   |    ^^^^^^^^^^^^^^^^                   --------
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/invalid_arguments.rs:38:3
index 8af31b8b751f3f1312f9ebb4c8b2e8e98ae125ba..804cb1aa322190344eecfd1d60c619cfce52f32a 100644 (file)
@@ -2,7 +2,9 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied
   --> $DIR/issue-96638.rs:8:5
    |
 LL |     f(&x, "");
-   |     ^ -- an argument of type `usize` is missing
+   |     ^ --  -- expected `usize`, found `&str`
+   |       |
+   |       an argument of type `usize` is missing
    |
 note: function defined here
   --> $DIR/issue-96638.rs:1:4
index 9589e919c0a1f15f0ad9359949eb8f75f92d35bd..b5dedf0f4fa05494a8b9dea6823f83639cda07ef 100644 (file)
@@ -2,8 +2,9 @@ error[E0061]: this function takes 4 arguments but 7 arguments were supplied
   --> $DIR/issue-97484.rs:12:5
    |
 LL |     foo(&&A, B, C, D, E, F, G);
-   |     ^^^      -  -        - argument of type `F` unexpected
-   |              |  |
+   |     ^^^      -  -     -  - argument of type `F` unexpected
+   |              |  |     |
+   |              |  |     expected `&E`, found struct `E`
    |              |  argument of type `C` unexpected
    |              argument of type `B` unexpected
    |
diff --git a/src/test/ui/argument-suggestions/too-long.rs b/src/test/ui/argument-suggestions/too-long.rs
new file mode 100644 (file)
index 0000000..7ec56af
--- /dev/null
@@ -0,0 +1,41 @@
+struct Qux;
+
+impl Qux {
+    fn foo(
+        &self,
+        a: i32,
+        b: i32,
+        c: i32,
+        d: i32,
+        e: i32,
+        f: i32,
+        g: i32,
+        h: i32,
+        i: i32,
+        j: i32,
+        k: i32,
+        l: i32,
+    ) {
+    }
+}
+
+fn what(
+    qux: &Qux,
+    a: i32,
+    b: i32,
+    c: i32,
+    d: i32,
+    e: i32,
+    f: &i32,
+    g: i32,
+    h: i32,
+    i: i32,
+    j: i32,
+    k: i32,
+    l: i32,
+) {
+    qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/argument-suggestions/too-long.stderr b/src/test/ui/argument-suggestions/too-long.stderr
new file mode 100644 (file)
index 0000000..bd43019
--- /dev/null
@@ -0,0 +1,24 @@
+error[E0308]: mismatched types
+  --> $DIR/too-long.rs:37:28
+   |
+LL |     qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
+   |         ---                ^ expected `i32`, found `&i32`
+   |         |
+   |         arguments to this function are incorrect
+   |
+note: associated function defined here
+  --> $DIR/too-long.rs:4:8
+   |
+LL |     fn foo(
+   |        ^^^
+...
+LL |         f: i32,
+   |         ------
+help: consider dereferencing the borrow
+   |
+LL |     qux.foo(a, b, c, d, e, *f, g, h, i, j, k, l);
+   |                            +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/argument-suggestions/two-mismatch-notes.rs b/src/test/ui/argument-suggestions/two-mismatch-notes.rs
new file mode 100644 (file)
index 0000000..1309041
--- /dev/null
@@ -0,0 +1,11 @@
+#[derive(Copy, Clone)]
+struct Wrapper<T>(T);
+
+fn foo(_: fn(i32), _: Wrapper<i32>) {}
+
+fn f(_: u32) {}
+
+fn main() {
+    let w = Wrapper::<isize>(1isize);
+    foo(f, w); //~ ERROR arguments to this function are incorrect
+}
diff --git a/src/test/ui/argument-suggestions/two-mismatch-notes.stderr b/src/test/ui/argument-suggestions/two-mismatch-notes.stderr
new file mode 100644 (file)
index 0000000..7873cf9
--- /dev/null
@@ -0,0 +1,29 @@
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/two-mismatch-notes.rs:10:5
+   |
+LL |     foo(f, w);
+   |     ^^^
+   |
+note: expected `i32`, found `u32`
+  --> $DIR/two-mismatch-notes.rs:10:9
+   |
+LL |     foo(f, w);
+   |         ^
+   = note: expected fn pointer `fn(i32)`
+                 found fn item `fn(u32) {f}`
+note: expected `i32`, found `isize`
+  --> $DIR/two-mismatch-notes.rs:10:12
+   |
+LL |     foo(f, w);
+   |            ^
+   = note: expected struct `Wrapper<i32>`
+              found struct `Wrapper<isize>`
+note: function defined here
+  --> $DIR/two-mismatch-notes.rs:4:4
+   |
+LL | fn foo(_: fn(i32), _: Wrapper<i32>) {}
+   |    ^^^ ----------  ---------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
index b904ad102e97e794468a1281066144f9577e66ed..e761c6c62a6cf43c549b4da0d70b4cff84605167 100644 (file)
@@ -10,7 +10,7 @@ note: function defined here
   --> $DIR/associated-type-projection-from-supertrait.rs:25:4
    |
 LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
-   |    ^^^^        ----  ---------------
+   |    ^^^^              ---------------
 
 error[E0308]: mismatched types
   --> $DIR/associated-type-projection-from-supertrait.rs:28:23
@@ -24,7 +24,7 @@ note: function defined here
   --> $DIR/associated-type-projection-from-supertrait.rs:25:4
    |
 LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
-   |    ^^^^        ----  ---------------
+   |    ^^^^              ---------------
 
 error[E0308]: mismatched types
   --> $DIR/associated-type-projection-from-supertrait.rs:32:28
@@ -38,7 +38,7 @@ note: associated function defined here
   --> $DIR/associated-type-projection-from-supertrait.rs:12:8
    |
 LL |     fn chip_paint(&self, c: Self::Color) { }
-   |        ^^^^^^^^^^ -----  --------------
+   |        ^^^^^^^^^^        --------------
 
 error[E0308]: mismatched types
   --> $DIR/associated-type-projection-from-supertrait.rs:33:28
@@ -52,7 +52,7 @@ note: associated function defined here
   --> $DIR/associated-type-projection-from-supertrait.rs:12:8
    |
 LL |     fn chip_paint(&self, c: Self::Color) { }
-   |        ^^^^^^^^^^ -----  --------------
+   |        ^^^^^^^^^^        --------------
 
 error: aborting due to 4 previous errors
 
index 0cccc6b38a3a931d14e8603d9dc66ffb67f3efef..a777e064f1a0ad8cc4617d97fe133660ae780d51 100644 (file)
@@ -1,8 +1,10 @@
 error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
-  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10
+  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:19
    |
 LL | fn b() { blue_car(ModelT); }
-   |          ^^^^^^^^ type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
+   |          -------- ^^^^^^ type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
+   |          |
+   |          required by a bound introduced by this call
    |
 note: expected this to be `Blue`
   --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:16:40
@@ -16,10 +18,12 @@ LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
    |                   ^^^^^^^^^^ required by this bound in `blue_car`
 
 error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
-  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10
+  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:20
    |
 LL | fn c() { black_car(ModelU); }
-   |          ^^^^^^^^^ type mismatch resolving `<ModelU as Vehicle>::Color == Black`
+   |          --------- ^^^^^^ type mismatch resolving `<ModelU as Vehicle>::Color == Black`
+   |          |
+   |          required by a bound introduced by this call
    |
 note: expected this to be `Black`
   --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:21:40
index bed63a5e6df03d20aabd3eaa00a673777e137d8d..19750fe1f333f74cc0d4cd89dfc0f5a478d95907 100644 (file)
@@ -14,10 +14,12 @@ LL | fn foo2<I: Foo<A = Bar>>(x: I) {
    |               +++++++++
 
 error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
-  --> $DIR/associated-types-eq-3.rs:38:5
+  --> $DIR/associated-types-eq-3.rs:38:10
    |
 LL |     foo1(a);
-   |     ^^^^ type mismatch resolving `<isize as Foo>::A == Bar`
+   |     ---- ^ type mismatch resolving `<isize as Foo>::A == Bar`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: expected this to be `Bar`
   --> $DIR/associated-types-eq-3.rs:12:14
@@ -34,7 +36,9 @@ error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
   --> $DIR/associated-types-eq-3.rs:40:9
    |
 LL |     baz(&a);
-   |         ^^ type mismatch resolving `<isize as Foo>::A == Bar`
+   |     --- ^^ type mismatch resolving `<isize as Foo>::A == Bar`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: expected this to be `Bar`
   --> $DIR/associated-types-eq-3.rs:12:14
index b306ae273e870ba3686b77a666ba9520537e194c..6cff403b318c193cd0e55e213debb9b6c772a1db 100644 (file)
@@ -1,8 +1,8 @@
 error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
-  --> $DIR/associated-types-eq-hr.rs:87:5
+  --> $DIR/associated-types-eq-hr.rs:87:11
    |
 LL |     foo::<UintStruct>();
-   |     ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
+   |           ^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
    |
 note: expected this to be `&isize`
   --> $DIR/associated-types-eq-hr.rs:26:14
@@ -21,10 +21,10 @@ LL |     T: for<'x> TheTrait<&'x isize, A = &'x isize>,
    |                                    ^^^^^^^^^^^^^ required by this bound in `foo`
 
 error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
-  --> $DIR/associated-types-eq-hr.rs:91:5
+  --> $DIR/associated-types-eq-hr.rs:91:11
    |
 LL |     bar::<IntStruct>();
-   |     ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
+   |           ^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
    |
 note: expected this to be `&usize`
   --> $DIR/associated-types-eq-hr.rs:14:14
index a67cf99283cfaaa1d6a5b3b67cc799643cf35e23..b1708b96e525403771b8e642a9098f29320d8240 100644 (file)
@@ -1,11 +1,13 @@
 error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
-  --> $DIR/associated-types-issue-20346.rs:34:5
+  --> $DIR/associated-types-issue-20346.rs:34:36
    |
 LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
    |                 - this type parameter
 ...
 LL |     is_iterator_of::<Option<T>, _>(&adapter);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
+   |     ------------------------------ ^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: expected this to be `Option<T>`
   --> $DIR/associated-types-issue-20346.rs:23:17
index 922cf88a04999d5c9cf7b81536bc381c67d55935..89cdba524be23b1ed4cc30f86e621b0ee483f469 100644 (file)
@@ -1,8 +1,10 @@
 error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
-  --> $DIR/associated-types-multiple-types-one-trait.rs:13:5
+  --> $DIR/associated-types-multiple-types-one-trait.rs:13:12
    |
 LL |     want_y(t);
-   |     ^^^^^^ expected `i32`, found associated type
+   |     ------ ^ expected `i32`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:         expected type `i32`
            found associated type `<T as Foo>::Y`
@@ -17,10 +19,12 @@ LL | fn have_x_want_y<T:Foo<X=u32, Y = i32>>(t: &T)
    |                             +++++++++
 
 error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
-  --> $DIR/associated-types-multiple-types-one-trait.rs:18:5
+  --> $DIR/associated-types-multiple-types-one-trait.rs:18:12
    |
 LL |     want_x(t);
-   |     ^^^^^^ expected `u32`, found associated type
+   |     ------ ^ expected `u32`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:         expected type `u32`
            found associated type `<T as Foo>::X`
index 1d0b84d31d4104e4331424a3618ca45d7e07670a..c37d469890c08689134f3beadbd3a8ddd17e561b 100644 (file)
@@ -10,7 +10,7 @@ note: function defined here
   --> $DIR/associated-types-path-2.rs:13:8
    |
 LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
-   |        ^^         ----  -------
+   |        ^^               -------
 help: change the type of the numeric literal from `i32` to `u32`
    |
 LL |     f1(2i32, 4u32);
index 700923c1b3f58686b1b138ba0ff1d11044cb8a5a..2b88cf0b4411eaccca994ec545e4584f6f9c00cf 100644 (file)
@@ -1,25 +1,3 @@
-error[E0393]: the type parameter `Rhs` must be explicitly specified
-  --> $DIR/issue-22560.rs:9:23
-   |
-LL | trait Sub<Rhs=Self> {
-   | ------------------- type parameter `Rhs` must be specified for this
-...
-LL | type Test = dyn Add + Sub;
-   |                       ^^^ help: set the type parameter to the desired type: `Sub<Rhs>`
-   |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
-
-error[E0393]: the type parameter `Rhs` must be explicitly specified
-  --> $DIR/issue-22560.rs:9:17
-   |
-LL | trait Add<Rhs=Self> {
-   | ------------------- type parameter `Rhs` must be specified for this
-...
-LL | type Test = dyn Add + Sub;
-   |                 ^^^ help: set the type parameter to the desired type: `Add<Rhs>`
-   |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
-
 error[E0225]: only auto traits can be used as additional traits in a trait object
   --> $DIR/issue-22560.rs:9:23
    |
@@ -28,7 +6,7 @@ LL | type Test = dyn Add + Sub;
    |                 |
    |                 first non-auto trait
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<[type error]> + Sub<[type error]> {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0191]: the value of the associated types `Output` (from trait `Add`), `Output` (from trait `Sub`) must be specified
@@ -50,6 +28,28 @@ help: specify the associated types
 LL | type Test = dyn Add<Output = Type> + Sub<Output = Type>;
    |                 ~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~
 
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+  --> $DIR/issue-22560.rs:9:17
+   |
+LL | trait Add<Rhs=Self> {
+   | ------------------- type parameter `Rhs` must be specified for this
+...
+LL | type Test = dyn Add + Sub;
+   |                 ^^^ help: set the type parameter to the desired type: `Add<Rhs>`
+   |
+   = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+  --> $DIR/issue-22560.rs:9:23
+   |
+LL | trait Sub<Rhs=Self> {
+   | ------------------- type parameter `Rhs` must be specified for this
+...
+LL | type Test = dyn Add + Sub;
+   |                       ^^^ help: set the type parameter to the desired type: `Sub<Rhs>`
+   |
+   = note: because of the default `Self` reference, type parameters must be specified on object types
+
 error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0191, E0225, E0393.
index 8db4a49da3c96e4f7790d038e62ac3ad0062a3d4..f24423dd106669af20debca20e3016509ac3a571 100644 (file)
@@ -1,8 +1,10 @@
 error[E0271]: type mismatch resolving `<A as Trait>::Associated == ()`
-  --> $DIR/issue-87261.rs:56:5
+  --> $DIR/issue-87261.rs:56:19
    |
 LL |     accepts_trait(a);
-   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |     ------------- ^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<A as Trait>::Associated`
@@ -17,10 +19,12 @@ LL |     A: Trait<Associated = ()> + 'static,
    |             +++++++++++++++++
 
 error[E0271]: type mismatch resolving `<B as Trait>::Associated == ()`
-  --> $DIR/issue-87261.rs:59:5
+  --> $DIR/issue-87261.rs:59:19
    |
 LL |     accepts_trait(b);
-   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |     ------------- ^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<B as Trait>::Associated`
@@ -33,10 +37,12 @@ LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
    |                           ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
 
 error[E0271]: type mismatch resolving `<C as Trait>::Associated == ()`
-  --> $DIR/issue-87261.rs:62:5
+  --> $DIR/issue-87261.rs:62:19
    |
 LL |     accepts_trait(c);
-   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |     ------------- ^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<C as Trait>::Associated`
@@ -51,10 +57,12 @@ LL |     C: Trait<Associated = ()> + Foo,
    |             +++++++++++++++++
 
 error[E0271]: type mismatch resolving `<D as Trait>::Associated == ()`
-  --> $DIR/issue-87261.rs:65:5
+  --> $DIR/issue-87261.rs:65:19
    |
 LL |     accepts_trait(d);
-   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |     ------------- ^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<D as Trait>::Associated`
@@ -67,10 +75,12 @@ LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
    |                           ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
 
 error[E0271]: type mismatch resolving `<E as GenericTrait<()>>::Associated == ()`
-  --> $DIR/issue-87261.rs:68:5
+  --> $DIR/issue-87261.rs:68:27
    |
 LL |     accepts_generic_trait(e);
-   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     --------------------- ^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<E as GenericTrait<()>>::Associated`
@@ -85,10 +95,12 @@ LL |     E: GenericTrait<(), Associated = ()> + 'static,
    |                       +++++++++++++++++
 
 error[E0271]: type mismatch resolving `<F as GenericTrait<()>>::Associated == ()`
-  --> $DIR/issue-87261.rs:71:5
+  --> $DIR/issue-87261.rs:71:27
    |
 LL |     accepts_generic_trait(f);
-   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     --------------------- ^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<F as GenericTrait<()>>::Associated`
@@ -103,10 +115,12 @@ LL |     F: GenericTrait<(), Associated = ()> + Foo,
    |                       +++++++++++++++++
 
 error[E0271]: type mismatch resolving `<G as GenericTrait<()>>::Associated == ()`
-  --> $DIR/issue-87261.rs:74:5
+  --> $DIR/issue-87261.rs:74:27
    |
 LL |     accepts_generic_trait(g);
-   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     --------------------- ^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<G as GenericTrait<()>>::Associated`
@@ -119,13 +133,15 @@ LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
    |                                              ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
 
 error[E0271]: type mismatch resolving `<impl Trait as Trait>::Associated == ()`
-  --> $DIR/issue-87261.rs:79:5
+  --> $DIR/issue-87261.rs:79:19
    |
 LL | fn returns_opaque() -> impl Trait + 'static {
    |                        -------------------- the found opaque type
 ...
 LL |     accepts_trait(returns_opaque());
-   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |     ------------- ^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<impl Trait as Trait>::Associated`
@@ -140,13 +156,15 @@ LL | fn returns_opaque() -> impl Trait<Associated = ()> + 'static {
    |                                  +++++++++++++++++
 
 error[E0271]: type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
-  --> $DIR/issue-87261.rs:82:5
+  --> $DIR/issue-87261.rs:82:19
    |
 LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static {
    |                                --------------------------- the found opaque type
 ...
 LL |     accepts_trait(returns_opaque_derived());
-   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |     ------------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<impl DerivedTrait as Trait>::Associated`
@@ -161,13 +179,15 @@ LL | fn returns_opaque_derived() -> impl DerivedTrait<Associated = ()> + 'static
    |                                                 +++++++++++++++++
 
 error[E0271]: type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
-  --> $DIR/issue-87261.rs:85:5
+  --> $DIR/issue-87261.rs:85:19
    |
 LL | fn returns_opaque_foo() -> impl Trait + Foo {
    |                            ---------------- the found opaque type
 ...
 LL |     accepts_trait(returns_opaque_foo());
-   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |     ------------- ^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<impl Trait + Foo as Trait>::Associated`
@@ -182,13 +202,15 @@ LL | fn returns_opaque_foo() -> impl Trait<Associated = ()> + Foo {
    |                                      +++++++++++++++++
 
 error[E0271]: type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
-  --> $DIR/issue-87261.rs:88:5
+  --> $DIR/issue-87261.rs:88:19
    |
 LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
    |                                    ----------------------- the found opaque type
 ...
 LL |     accepts_trait(returns_opaque_derived_foo());
-   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |     ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<impl DerivedTrait + Foo as Trait>::Associated`
@@ -201,13 +223,15 @@ LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
    |                           ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
 
 error[E0271]: type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
-  --> $DIR/issue-87261.rs:91:5
+  --> $DIR/issue-87261.rs:91:27
    |
 LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {
    |                                ------------------------------- the found opaque type
 ...
 LL |     accepts_generic_trait(returns_opaque_generic());
-   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<impl GenericTrait<()> as GenericTrait<()>>::Associated`
@@ -222,13 +246,15 @@ LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'st
    |                                                    +++++++++++++++++
 
 error[E0271]: type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`
-  --> $DIR/issue-87261.rs:94:5
+  --> $DIR/issue-87261.rs:94:27
    |
 LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
    |                                    --------------------------- the found opaque type
 ...
 LL |     accepts_generic_trait(returns_opaque_generic_foo());
-   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated`
@@ -243,13 +269,15 @@ LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> +
    |                                                        +++++++++++++++++
 
 error[E0271]: type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
-  --> $DIR/issue-87261.rs:97:5
+  --> $DIR/issue-87261.rs:97:27
    |
 LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
    |                                          ---------------------------------------- the found opaque type
 ...
 LL |     accepts_generic_trait(returns_opaque_generic_duplicate());
-   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |     |
+   |     required by a bound introduced by this call
    |
    = note:    expected unit type `()`
            found associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated`
index 3be8c552063e7893e3e217a8d6cc470903fda009..2494c3feb2a89206e5feff16ebf644aacdcb5e55 100644 (file)
@@ -42,7 +42,7 @@ note: function defined here
   --> $DIR/generator-desc.rs:8:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
-   |    ^^^                         -----  -----
+   |    ^^^                                -----
 
 error[E0308]: mismatched types
   --> $DIR/generator-desc.rs:14:26
@@ -67,7 +67,7 @@ note: function defined here
   --> $DIR/generator-desc.rs:8:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
-   |    ^^^                         -----  -----
+   |    ^^^                                -----
 
 error: aborting due to 3 previous errors
 
index 5d119bb8557a4d40480a9ede8c127953223e520d..60b379faf4e060fe4c4317ffe4b7ce3a0f44de04 100644 (file)
@@ -44,19 +44,19 @@ error: `...` must be the last argument of a C-variadic function
   --> $DIR/issue-86053-1.rs:11:12
    |
 LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
-   |            ^^^^
+   |            ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
   --> $DIR/issue-86053-1.rs:11:12
    |
 LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
-   |            ^^^^
+   |            ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
   --> $DIR/issue-86053-1.rs:11:36
    |
 LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
-   |                                    ^^^^
+   |                                    ^^^
 
 error[E0412]: cannot find type `F` in this scope
   --> $DIR/issue-86053-1.rs:11:48
diff --git a/src/test/ui/closures/binder/disallow-const.rs b/src/test/ui/closures/binder/disallow-const.rs
new file mode 100644 (file)
index 0000000..72ad618
--- /dev/null
@@ -0,0 +1,6 @@
+#![feature(closure_lifetime_binder)]
+
+fn main() {
+    for<const N: i32> || -> () {};
+    //~^ ERROR only lifetime parameters can be used in this context
+}
diff --git a/src/test/ui/closures/binder/disallow-const.stderr b/src/test/ui/closures/binder/disallow-const.stderr
new file mode 100644 (file)
index 0000000..3c3b43d
--- /dev/null
@@ -0,0 +1,8 @@
+error: only lifetime parameters can be used in this context
+  --> $DIR/disallow-const.rs:4:15
+   |
+LL |     for<const N: i32> || -> () {};
+   |               ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/closures/binder/disallow-ty.rs b/src/test/ui/closures/binder/disallow-ty.rs
new file mode 100644 (file)
index 0000000..bbe3d84
--- /dev/null
@@ -0,0 +1,6 @@
+#![feature(closure_lifetime_binder)]
+
+fn main() {
+    for<T> || -> () {};
+    //~^ ERROR only lifetime parameters can be used in this context
+}
diff --git a/src/test/ui/closures/binder/disallow-ty.stderr b/src/test/ui/closures/binder/disallow-ty.stderr
new file mode 100644 (file)
index 0000000..51b6773
--- /dev/null
@@ -0,0 +1,8 @@
+error: only lifetime parameters can be used in this context
+  --> $DIR/disallow-ty.rs:4:9
+   |
+LL |     for<T> || -> () {};
+   |         ^
+
+error: aborting due to previous error
+
index 36551e5afc6c65e7f8cb59fb8cf59edabe8e4986..5cbdef218311416f5ed1669d6a3cb44cbb15d9d1 100644 (file)
@@ -12,7 +12,7 @@ note: function defined here
   --> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4
    |
 LL | fn test<T>(_a: T, _b: T) {}
-   |    ^^^^    -----  -----
+   |    ^^^^           -----
 
 error: aborting due to previous error
 
index add8f14cfa591884a3ee3fb8805313d85ec8144b..1207dc7e7a2ff4415da00c5e039b3e4b16418d39 100644 (file)
@@ -12,7 +12,7 @@ note: function defined here
   --> $DIR/coerce-to-bang.rs:3:4
    |
 LL | fn foo(x: usize, y: !, z: usize) { }
-   |    ^^^ --------  ----  --------
+   |    ^^^           ----
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:18:13
@@ -28,7 +28,7 @@ note: function defined here
   --> $DIR/coerce-to-bang.rs:3:4
    |
 LL | fn foo(x: usize, y: !, z: usize) { }
-   |    ^^^ --------  ----  --------
+   |    ^^^           ----
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:26:12
@@ -44,7 +44,7 @@ note: function defined here
   --> $DIR/coerce-to-bang.rs:3:4
    |
 LL | fn foo(x: usize, y: !, z: usize) { }
-   |    ^^^ --------  ----  --------
+   |    ^^^           ----
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:36:12
@@ -60,7 +60,7 @@ note: function defined here
   --> $DIR/coerce-to-bang.rs:3:4
    |
 LL | fn foo(x: usize, y: !, z: usize) { }
-   |    ^^^ --------  ----  --------
+   |    ^^^           ----
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:45:12
@@ -76,7 +76,7 @@ note: function defined here
   --> $DIR/coerce-to-bang.rs:3:4
    |
 LL | fn foo(x: usize, y: !, z: usize) { }
-   |    ^^^ --------  ----  --------
+   |    ^^^           ----
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:50:21
diff --git a/src/test/ui/coherence/auxiliary/trait-with-const-param.rs b/src/test/ui/coherence/auxiliary/trait-with-const-param.rs
new file mode 100644 (file)
index 0000000..a44eb14
--- /dev/null
@@ -0,0 +1 @@
+pub trait Trait<const N: usize, T> {}
diff --git a/src/test/ui/coherence/const-generics-orphan-check-ok.rs b/src/test/ui/coherence/const-generics-orphan-check-ok.rs
new file mode 100644 (file)
index 0000000..217e8ae
--- /dev/null
@@ -0,0 +1,28 @@
+// check-pass
+// aux-build:trait-with-const-param.rs
+extern crate trait_with_const_param;
+use trait_with_const_param::*;
+
+// Trivial case, const param after local type.
+struct Local1;
+impl<const N: usize, T> Trait<N, T> for Local1 {}
+
+// Concrete consts behave the same as foreign types,
+// so this also trivially works.
+impl Trait<3, Local1> for i32 {}
+
+// This case isn't as trivial as we would forbid type
+// parameters here, we do allow const parameters though.
+//
+// The reason that type parameters are forbidden for
+// `impl<T> Trait<T, LocalInA> for i32 {}` is that another
+// downstream crate can add `impl<T> Trait<LocalInB, T> for i32`.
+// As these two impls would overlap we forbid any impls which
+// have a type parameter in front of a local type.
+//
+// With const parameters this issue does not exist as there are no
+// constants local to another downstream crate.
+struct Local2;
+impl<const N: usize> Trait<N, Local2> for i32 {}
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-100191-2.rs b/src/test/ui/coherence/issue-100191-2.rs
new file mode 100644 (file)
index 0000000..1c8316f
--- /dev/null
@@ -0,0 +1,12 @@
+//~ ERROR overflow evaluating the requirement `T: Trait<_>`
+
+#![feature(specialization, with_negative_coherence)]
+#![allow(incomplete_features)]
+
+pub trait Trait<T> {}
+
+default impl<T, U> Trait<T> for U {}
+
+impl<T> Trait<<T as Iterator>::Item> for T {}
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-100191-2.stderr b/src/test/ui/coherence/issue-100191-2.stderr
new file mode 100644 (file)
index 0000000..ea09fb1
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0275]: overflow evaluating the requirement `T: Trait<_>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_100191_2`)
+note: required because of the requirements on the impl of `Trait<_>` for `T`
+  --> $DIR/issue-100191-2.rs:8:20
+   |
+LL | default impl<T, U> Trait<T> for U {}
+   |                    ^^^^^^^^     ^
+   = note: 128 redundant requirements hidden
+   = note: required because of the requirements on the impl of `Trait<_>` for `T`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/coherence/issue-100191.rs b/src/test/ui/coherence/issue-100191.rs
new file mode 100644 (file)
index 0000000..e8597fd
--- /dev/null
@@ -0,0 +1,21 @@
+#![crate_type = "lib"]
+#![feature(specialization, with_negative_coherence)]
+#![allow(incomplete_features)]
+
+trait X {}
+trait Y: X {}
+trait Z {
+    type Assoc: Y;
+}
+struct A<T>(T);
+
+impl<T> Y for T where T: X {}
+impl<T: X> Z for A<T> {
+    type Assoc = T;
+}
+
+// this impl is invalid, but causes an ICE anyway
+impl<T> From<<A<T> as Z>::Assoc> for T {}
+//~^ ERROR type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-100191.stderr b/src/test/ui/coherence/issue-100191.stderr
new file mode 100644 (file)
index 0000000..1adb0f1
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+  --> $DIR/issue-100191.rs:18:6
+   |
+LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
+   |      ^ type parameter `T` must be used as the type parameter for some local type
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
+   = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-100360.rs b/src/test/ui/const-generics/generic_const_exprs/issue-100360.rs
new file mode 100644 (file)
index 0000000..5572f1f
--- /dev/null
@@ -0,0 +1,13 @@
+// check-pass
+// (this requires debug assertions)
+
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+fn foo<const B: &'static bool>(arg: &'static bool) -> bool {
+    B == arg
+}
+
+fn main() {
+    foo::<{ &true }>(&false);
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-89851.rs b/src/test/ui/const-generics/generic_const_exprs/issue-89851.rs
new file mode 100644 (file)
index 0000000..cde849d
--- /dev/null
@@ -0,0 +1,12 @@
+// check-pass
+// (this requires debug assertions)
+
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+pub const BAR: () = ice::<"">();
+pub const fn ice<const N: &'static str>() {
+    &10;
+}
+
+fn main() {}
index 38e5c454edf7566677a91f23a006b1a5af0d7114..3ce3e1bdbac0f9b6d4b30c12bce22173e38b0c0a 100644 (file)
@@ -13,10 +13,10 @@ fn main() {
     const _BAD1: () = unsafe {
         MaybeUninit::<!>::uninit().assume_init();
     };
-    const _BAD2: () = unsafe {
+    const _BAD2: () = {
         intrinsics::assert_uninit_valid::<bool>();
     };
-    const _BAD3: () = unsafe {
+    const _BAD3: () = {
         intrinsics::assert_zero_valid::<&'static i32>();
     };
 }
index f3b9170d428af716b83d66ffda88c65356aee4ea..6eab10197b8553af4e006a64e6741a361bbda8bc 100644 (file)
@@ -13,7 +13,7 @@ LL |         MaybeUninit::<!>::uninit().assume_init();
 error: any use of this value will cause an error
   --> $DIR/assert-type-intrinsics.rs:17:9
    |
-LL |     const _BAD2: () = unsafe {
+LL |     const _BAD2: () = {
    |     ---------------
 LL |         intrinsics::assert_uninit_valid::<bool>();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
@@ -24,7 +24,7 @@ LL |         intrinsics::assert_uninit_valid::<bool>();
 error: any use of this value will cause an error
   --> $DIR/assert-type-intrinsics.rs:20:9
    |
-LL |     const _BAD3: () = unsafe {
+LL |     const _BAD3: () = {
    |     ---------------
 LL |         intrinsics::assert_zero_valid::<&'static i32>();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
@@ -51,7 +51,7 @@ Future breakage diagnostic:
 error: any use of this value will cause an error
   --> $DIR/assert-type-intrinsics.rs:17:9
    |
-LL |     const _BAD2: () = unsafe {
+LL |     const _BAD2: () = {
    |     ---------------
 LL |         intrinsics::assert_uninit_valid::<bool>();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
@@ -64,7 +64,7 @@ Future breakage diagnostic:
 error: any use of this value will cause an error
   --> $DIR/assert-type-intrinsics.rs:20:9
    |
-LL |     const _BAD3: () = unsafe {
+LL |     const _BAD3: () = {
    |     ---------------
 LL |         intrinsics::assert_zero_valid::<&'static i32>();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs
new file mode 100644 (file)
index 0000000..97c9e15
--- /dev/null
@@ -0,0 +1,45 @@
+// revisions: no_flag with_flag
+// [no_flag] check-pass
+// [with_flag] compile-flags: -Zextra-const-ub-checks
+#![feature(const_ptr_read)]
+
+use std::mem::transmute;
+
+const INVALID_BOOL: () = unsafe {
+    let _x: bool = transmute(3u8);
+    //[with_flag]~^ ERROR: evaluation of constant value failed
+    //[with_flag]~| invalid value
+};
+
+const INVALID_PTR_IN_INT: () = unsafe {
+    let _x: usize = transmute(&3u8);
+    //[with_flag]~^ ERROR: evaluation of constant value failed
+    //[with_flag]~| invalid value
+};
+
+const INVALID_SLICE_TO_USIZE_TRANSMUTE: () = unsafe {
+    let x: &[u8] = &[0; 32];
+    let _x: (usize, usize) = transmute(x);
+    //[with_flag]~^ ERROR: evaluation of constant value failed
+    //[with_flag]~| invalid value
+};
+
+const UNALIGNED_PTR: () = unsafe {
+    let _x: &u32 = transmute(&[0u8; 4]);
+    //[with_flag]~^ ERROR: evaluation of constant value failed
+    //[with_flag]~| invalid value
+};
+
+const UNALIGNED_READ: () = {
+    INNER; //[with_flag]~ERROR any use of this value will cause an error
+    //[with_flag]~| previously accepted
+    // There is an error here but its span is in the standard library so we cannot match it...
+    // so we have this in a *nested* const, such that the *outer* const fails to use it.
+    const INNER: () = unsafe {
+        let x = &[0u8; 4];
+        let ptr = x.as_ptr().cast::<u32>();
+        ptr.read();
+    };
+};
+
+fn main() {}
diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
new file mode 100644 (file)
index 0000000..1706db7
--- /dev/null
@@ -0,0 +1,71 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/detect-extra-ub.rs:9:20
+   |
+LL |     let _x: bool = transmute(3u8);
+   |                    ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/detect-extra-ub.rs:15:21
+   |
+LL |     let _x: usize = transmute(&3u8);
+   |                     ^^^^^^^^^^^^^^^ constructing invalid value: encountered (potentially part of) a pointer, but expected plain (non-pointer) bytes
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/detect-extra-ub.rs:22:30
+   |
+LL |     let _x: (usize, usize) = transmute(x);
+   |                              ^^^^^^^^^^^^ constructing invalid value at .0: encountered (potentially part of) a pointer, but expected plain (non-pointer) bytes
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/detect-extra-ub.rs:28:20
+   |
+LL |     let _x: &u32 = transmute(&[0u8; 4]);
+   |                    ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1)
+
+error[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |
+LL |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         accessing memory with alignment 1, but alignment 4 is required
+   |         inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |
+  ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+   |
+LL |         unsafe { read(self) }
+   |                  ---------- inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+   |
+  ::: $DIR/detect-extra-ub.rs:41:9
+   |
+LL |         ptr.read();
+   |         ---------- inside `INNER` at $DIR/detect-extra-ub.rs:41:9
+
+error: any use of this value will cause an error
+  --> $DIR/detect-extra-ub.rs:34:5
+   |
+LL | const UNALIGNED_READ: () = {
+   | ------------------------
+LL |     INNER;
+   |     ^^^^^ referenced constant has errors
+   |
+   = note: `#[deny(const_err)]` on by default
+   = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+  --> $DIR/detect-extra-ub.rs:34:5
+   |
+LL | const UNALIGNED_READ: () = {
+   | ------------------------
+LL |     INNER;
+   |     ^^^^^ referenced constant has errors
+   |
+   = note: `#[deny(const_err)]` on by default
+   = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+
index b2edc1a1f66ca8b3c9d2e1e1f7cae8193e41ab9f..6175b7df1107ad78029a5ffc4f4231a2d105a05b 100644 (file)
@@ -3,7 +3,6 @@
 
 trait Foo<X = Box<dyn Foo>> {
     //~^ ERROR cycle detected
-    //~| ERROR cycle detected
 }
 
 fn main() { }
index d4976a0f9c9cd1c61bd52b2bc62d4728179b66bb..9d715f49471463f94d333cc8c2bab63389117b37 100644 (file)
@@ -10,30 +10,11 @@ note: cycle used when collecting item types in top-level module
    |
 LL | / trait Foo<X = Box<dyn Foo>> {
 LL | |
-LL | |
-LL | | }
-LL | |
-LL | | fn main() { }
-   | |_____________^
-
-error[E0391]: cycle detected when computing type of `Foo::X`
-  --> $DIR/cycle-trait-default-type-trait.rs:4:23
-   |
-LL | trait Foo<X = Box<dyn Foo>> {
-   |                       ^^^
-   |
-   = note: ...which immediately requires computing type of `Foo::X` again
-note: cycle used when collecting item types in top-level module
-  --> $DIR/cycle-trait-default-type-trait.rs:4:1
-   |
-LL | / trait Foo<X = Box<dyn Foo>> {
-LL | |
-LL | |
 LL | | }
 LL | |
 LL | | fn main() { }
    | |_____________^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/drop/drop_order.rs b/src/test/ui/drop/drop_order.rs
new file mode 100644 (file)
index 0000000..e42150d
--- /dev/null
@@ -0,0 +1,145 @@
+// run-pass
+
+use std::cell::RefCell;
+use std::convert::TryInto;
+
+#[derive(Default)]
+struct DropOrderCollector(RefCell<Vec<u32>>);
+
+struct LoudDrop<'a>(&'a DropOrderCollector, u32);
+
+impl Drop for LoudDrop<'_> {
+    fn drop(&mut self) {
+        println!("{}", self.1);
+        self.0.0.borrow_mut().push(self.1);
+    }
+}
+
+impl DropOrderCollector {
+    fn option_loud_drop(&self, n: u32) -> Option<LoudDrop> {
+        Some(LoudDrop(self, n))
+    }
+
+    fn loud_drop(&self, n: u32) -> LoudDrop {
+        LoudDrop(self, n)
+    }
+
+    fn print(&self, n: u32) {
+        println!("{}", n);
+        self.0.borrow_mut().push(n)
+    }
+
+    fn if_(&self) {
+        if self.option_loud_drop(1).is_some() {
+            self.print(2);
+        }
+
+        if self.option_loud_drop(3).is_none() {
+            unreachable!();
+        } else if self.option_loud_drop(4).is_some() {
+            self.print(5);
+        }
+
+        if {
+            if self.option_loud_drop(7).is_some() && self.option_loud_drop(6).is_some() {
+                self.loud_drop(8);
+                true
+            } else {
+                false
+            }
+        } {
+            self.print(9);
+        }
+    }
+
+    fn if_let(&self) {
+        if let None = self.option_loud_drop(2) {
+            unreachable!();
+        } else {
+            self.print(1);
+        }
+
+        if let Some(_) = self.option_loud_drop(4) {
+            self.print(3);
+        }
+
+        if let Some(_d) = self.option_loud_drop(6) {
+            self.print(5);
+        }
+    }
+
+    fn match_(&self) {
+        match self.option_loud_drop(2) {
+            _any => self.print(1),
+        }
+
+        match self.option_loud_drop(4) {
+            _ => self.print(3),
+        }
+
+        match self.option_loud_drop(6) {
+            Some(_) => self.print(5),
+            _ => unreachable!(),
+        }
+
+        match {
+            let _ = self.loud_drop(7);
+            let _d = self.loud_drop(9);
+            self.print(8);
+            ()
+        } {
+            () => self.print(10),
+        }
+
+        match {
+            match self.option_loud_drop(14) {
+                _ => {
+                    self.print(11);
+                    self.option_loud_drop(13)
+                }
+            }
+        } {
+            _ => self.print(12),
+        }
+
+        match {
+            loop {
+                break match self.option_loud_drop(16) {
+                    _ => {
+                        self.print(15);
+                        self.option_loud_drop(18)
+                    }
+                };
+            }
+        } {
+            _ => self.print(17),
+        }
+    }
+
+    fn assert_sorted(self) {
+        assert!(
+            self.0
+                .into_inner()
+                .into_iter()
+                .enumerate()
+                .all(|(idx, item)| idx + 1 == item.try_into().unwrap())
+        );
+    }
+}
+
+fn main() {
+    println!("-- if --");
+    let collector = DropOrderCollector::default();
+    collector.if_();
+    collector.assert_sorted();
+
+    println!("-- if let --");
+    let collector = DropOrderCollector::default();
+    collector.if_let();
+    collector.assert_sorted();
+
+    println!("-- match --");
+    let collector = DropOrderCollector::default();
+    collector.match_();
+    collector.assert_sorted();
+}
index 9c9c7237d71459a4ad74b88d71374954c3100ec0..1e2f4383459e2e40a8d2e16f9ad2eafa549515f1 100644 (file)
@@ -1,8 +1,10 @@
 error[E0271]: type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
-  --> $DIR/E0271.rs:10:5
+  --> $DIR/E0271.rs:10:9
    |
 LL |     foo(3_i8);
-   |     ^^^ type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
+   |     --- ^^^^ type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: expected this to be `u32`
   --> $DIR/E0271.rs:7:43
index ecc6485d6d2b5c1d5375e33ac22d32cd5eede579..f03a47d5c2c75c4727ba65d9685265b190159a0f 100644 (file)
@@ -15,7 +15,7 @@ note: function defined here
   --> $DIR/fn-item-type.rs:7:4
    |
 LL | fn eq<T>(x: T, y: T) { }
-   |    ^^    ----  ----
+   |    ^^          ----
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:22:19
@@ -34,7 +34,7 @@ note: function defined here
   --> $DIR/fn-item-type.rs:7:4
    |
 LL | fn eq<T>(x: T, y: T) { }
-   |    ^^    ----  ----
+   |    ^^          ----
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:29:23
@@ -53,7 +53,7 @@ note: function defined here
   --> $DIR/fn-item-type.rs:7:4
    |
 LL | fn eq<T>(x: T, y: T) { }
-   |    ^^    ----  ----
+   |    ^^          ----
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:38:26
@@ -72,7 +72,7 @@ note: function defined here
   --> $DIR/fn-item-type.rs:7:4
    |
 LL | fn eq<T>(x: T, y: T) { }
-   |    ^^    ----  ----
+   |    ^^          ----
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:45:19
@@ -90,7 +90,7 @@ note: function defined here
   --> $DIR/fn-item-type.rs:7:4
    |
 LL | fn eq<T>(x: T, y: T) { }
-   |    ^^    ----  ----
+   |    ^^          ----
 
 error: aborting due to 5 previous errors
 
index f0e03e73f0b3ef32766d0b2a320364a3d8c87776..7c2935d32bfd2a582f10df477a59c8713b958708 100644 (file)
@@ -1,8 +1,10 @@
 error[E0271]: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
-  --> $DIR/issue-74684-2.rs:23:5
+  --> $DIR/issue-74684-2.rs:23:9
    |
 LL |     bug(Box::new(x));
-   |     ^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+   |     --- ^^^^^^^^^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: expected this to be `[u8]`
   --> $DIR/issue-74684-2.rs:10:18
diff --git a/src/test/ui/higher-rank-trait-bounds/complex.rs b/src/test/ui/higher-rank-trait-bounds/complex.rs
new file mode 100644 (file)
index 0000000..8cdfe24
--- /dev/null
@@ -0,0 +1,28 @@
+// check-pass
+
+trait A<'a> {}
+trait B<'b> {}
+fn foo<T>() where for<'a> T: A<'a> + 'a {}
+trait C<'c>: for<'a> A<'a> + for<'b> B<'b> {
+    type As;
+}
+struct D<T> where T: for<'c> C<'c, As=&'c ()> {
+    t: std::marker::PhantomData<T>,
+}
+trait E<'e, 'g> {
+    type As;
+}
+trait F<'f>: for<'a> A<'a> + for<'e> E<'e, 'f> {}
+struct G<T> where T: for<'f> F<'f, As=&'f ()> {
+    t: std::marker::PhantomData<T>,
+}
+trait H<'a, 'b> {
+    type As;
+}
+trait I<'a>: for<'b> H<'a, 'b> {}
+
+struct J<T> where T: for<'i> I<'i, As=&'i ()> {
+    t: std::marker::PhantomData<T>,
+}
+
+fn main() {}
diff --git a/src/test/ui/higher-rank-trait-bounds/due-to-where-clause.rs b/src/test/ui/higher-rank-trait-bounds/due-to-where-clause.rs
new file mode 100644 (file)
index 0000000..1afd156
--- /dev/null
@@ -0,0 +1,13 @@
+fn main() {
+    test::<FooS>(&mut 42); //~ ERROR implementation of `Foo` is not general enough
+}
+
+trait Foo<'a> {}
+
+struct FooS<'a> {
+    data: &'a mut u32,
+}
+
+impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {}
+
+fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {}
diff --git a/src/test/ui/higher-rank-trait-bounds/due-to-where-clause.stderr b/src/test/ui/higher-rank-trait-bounds/due-to-where-clause.stderr
new file mode 100644 (file)
index 0000000..520938a
--- /dev/null
@@ -0,0 +1,11 @@
+error: implementation of `Foo` is not general enough
+  --> $DIR/due-to-where-clause.rs:2:5
+   |
+LL |     test::<FooS>(&mut 42);
+   |     ^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
+   = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs
new file mode 100644 (file)
index 0000000..a20d03c
--- /dev/null
@@ -0,0 +1,24 @@
+// Regression test for #54302.
+//
+// We were incorrectly using the "evaluation cache" (which ignored
+// region results) to conclude that `&'static str: Deserialize`, even
+// though it would require that `for<'de> 'de: 'static`, which is
+// clearly false.
+
+trait Deserialize<'de> {}
+
+trait DeserializeOwned: for<'de> Deserialize<'de> {}
+impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
+
+// Based on this impl, `&'static str` only implements Deserialize<'static>.
+// It does not implement for<'de> Deserialize<'de>.
+impl<'de: 'a, 'a> Deserialize<'de> for &'a str {}
+
+fn main() {
+    fn assert_deserialize_owned<T: DeserializeOwned>() {}
+    assert_deserialize_owned::<&'static str>(); //~ ERROR
+
+    // It correctly does not implement for<'de> Deserialize<'de>.
+    // fn assert_hrtb<T: for<'de> Deserialize<'de>>() {}
+    // assert_hrtb::<&'static str>();
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr
new file mode 100644 (file)
index 0000000..f014eab
--- /dev/null
@@ -0,0 +1,11 @@
+error: implementation of `Deserialize` is not general enough
+  --> $DIR/hrtb-cache-issue-54302.rs:19:5
+   |
+LL |     assert_deserialize_owned::<&'static str>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
+   |
+   = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
+   = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs
new file mode 100644 (file)
index 0000000..e836864
--- /dev/null
@@ -0,0 +1,31 @@
+// Test that an impl with only one bound region `'a` cannot be used to
+// satisfy a constraint where there are two bound regions.
+
+trait Foo<X> {
+    fn foo(&self, x: X) { }
+}
+
+fn want_foo2<T>()
+    where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
+{
+}
+
+fn want_foo1<T>()
+    where T : for<'z> Foo<(&'z isize, &'z isize)>
+{
+}
+
+// Expressed as a where clause
+
+struct SomeStruct;
+
+impl<'a> Foo<(&'a isize, &'a isize)> for SomeStruct
+{
+}
+
+fn a() { want_foo1::<SomeStruct>(); } // OK -- foo wants just one region
+fn b() { want_foo2::<SomeStruct>(); }
+//~^ ERROR implementation of
+//~| ERROR implementation of
+
+fn main() { }
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr
new file mode 100644 (file)
index 0000000..46f5308
--- /dev/null
@@ -0,0 +1,20 @@
+error: implementation of `Foo` is not general enough
+  --> $DIR/hrtb-conflate-regions.rs:27:10
+   |
+LL | fn b() { want_foo2::<SomeStruct>(); }
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+
+error: implementation of `Foo` is not general enough
+  --> $DIR/hrtb-conflate-regions.rs:27:10
+   |
+LL | fn b() { want_foo2::<SomeStruct>(); }
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs
new file mode 100644 (file)
index 0000000..05d3e1a
--- /dev/null
@@ -0,0 +1,18 @@
+// Test the case where the `Self` type has a bound lifetime that must
+// be adjusted in the fn signature. Issue #19537.
+
+use std::collections::HashMap;
+
+struct Foo<'a> {
+    map: HashMap<usize, &'a str>
+}
+
+impl<'a> Foo<'a> {
+    fn new() -> Foo<'a> { panic!() }
+    fn insert(&'a mut self) { }
+}
+fn main() {
+    let mut foo = Foo::new();
+    foo.insert();
+    foo.insert(); //~ ERROR cannot borrow
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr
new file mode 100644 (file)
index 0000000..fa391ec
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0499]: cannot borrow `foo` as mutable more than once at a time
+  --> $DIR/hrtb-debruijn-in-receiver.rs:17:5
+   |
+LL |     foo.insert();
+   |     ------------ first mutable borrow occurs here
+LL |     foo.insert();
+   |     ^^^^^^^^^^^^
+   |     |
+   |     second mutable borrow occurs here
+   |     first borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs
new file mode 100644 (file)
index 0000000..5678023
--- /dev/null
@@ -0,0 +1,18 @@
+// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile!
+//
+// In particular, we test this pattern in trait solving, where it is not connected
+// to any part of the source code.
+
+fn foo<'a>() -> fn(&'a u32) {
+    panic!()
+}
+
+fn main() {
+    // Here, proving that `fn(&'a u32) <: for<'b> fn(&'b u32)`:
+    //
+    // - instantiates `'b` with a placeholder `!b`,
+    // - requires that `&!b u32 <: &'a u32` and hence that `!b: 'a`,
+    // - but we can never know this.
+
+    let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr
new file mode 100644 (file)
index 0000000..9914783
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/hrtb-exists-forall-fn.rs:17:34
+   |
+LL |     let _: for<'b> fn(&'b u32) = foo();
+   |                                  ^^^^^ one type is more general than the other
+   |
+   = note: expected fn pointer `for<'b> fn(&'b u32)`
+              found fn pointer `fn(&u32)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs
new file mode 100644 (file)
index 0000000..9210619
--- /dev/null
@@ -0,0 +1,36 @@
+// Test a case where variance and higher-ranked types interact in surprising ways.
+//
+// In particular, we test this pattern in trait solving, where it is not connected
+// to any part of the source code.
+
+trait Trait<T> {}
+
+fn foo<T>()
+where
+    T: Trait<for<'b> fn(&'b u32)>,
+{
+}
+
+impl<'a> Trait<fn(&'a u32)> for () {}
+
+fn main() {
+    // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
+    //
+    // - The impl provides the clause `forall<'a> { (): Trait<fn(&'a u32)> }`
+    // - We instantiate `'a` existentially to get `(): Trait<fn(&?a u32)>`
+    // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` -- this does a
+    //   "bidirectional" subtyping check, so we wind up with:
+    //   - `fn(&?a u32) <: for<'b> fn(&'b u32)` :-
+    //     - `&'!b u32 <: &?a u32`
+    //     - `!'b: ?a` -- solveable if `?a` is inferred to `'empty`
+    //   - `for<'b> fn(&'b u32) <: fn(&?a u32)` :-
+    //     - `&?a u32 u32 <: &?b u32`
+    //     - `?a: ?b` -- solveable if `?b` is also inferred to `'empty`
+    // - So the subtyping check succeeds, somewhat surprisingly.
+    //   This is because we can use `'empty`.
+    //
+    // NB. *However*, the reinstated leak-check gives an error here.
+
+    foo::<()>();
+    //~^ ERROR implementation of `Trait` is not general enough
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr
new file mode 100644 (file)
index 0000000..364b613
--- /dev/null
@@ -0,0 +1,11 @@
+error: implementation of `Trait` is not general enough
+  --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
+   |
+LL |     foo::<()>();
+   |     ^^^^^^^^^^^ implementation of `Trait` is not general enough
+   |
+   = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
+   = note: ...but it actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs
new file mode 100644 (file)
index 0000000..f95496a
--- /dev/null
@@ -0,0 +1,37 @@
+// Test a case where variance and higher-ranked types interact in surprising ways.
+//
+// In particular, we test this pattern in trait solving, where it is not connected
+// to any part of the source code.
+//
+// check-pass
+
+trait Trait<T> {}
+
+fn foo<T>()
+where
+    T: Trait<for<'b> fn(fn(&'b u32))>,
+{
+}
+
+impl<'a> Trait<fn(fn(&'a u32))> for () {}
+
+fn main() {
+    // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
+    //
+    // - The impl provides the clause `forall<'a> { (): Trait<fn(fn(&'a u32))> }`
+    // - We instantiate `'a` existentially to get `(): Trait<fn(fn(&?a u32))>`
+    // - We unify `fn(fn(&?a u32))` with `for<'b> fn(fn(&'b u32))` -- this does a
+    //   "bidirectional" subtyping check, so we wind up with:
+    //   - `fn(fn(&?a u32)) <: for<'b> fn(fn(&'b u32))` :-
+    //     - `fn(&!b u32) <: fn(&?a u32)`
+    //       - `&?a u32 <: &!b u32`
+    //         - `?a: !'b` -- solveable if `?a` is inferred to `'static`
+    //   - `for<'b> fn(fn(&'b u32)) <: fn(fn(&?a u32))` :-
+    //     - `fn(&?a u32) <: fn(&?b u32)`
+    //       - `&?b u32 <: &?a u32`
+    //         - `?b: ?a` -- solveable if `?b` is inferred to `'static`
+    // - So the subtyping check succeeds, somewhat surprisingly.
+    //   This is because we can use `'static`.
+
+    foo::<()>();
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs
new file mode 100644 (file)
index 0000000..9b9e449
--- /dev/null
@@ -0,0 +1,29 @@
+// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile!
+//
+// In particular, we test this pattern in trait solving, where it is not connected
+// to any part of the source code.
+
+use std::cell::Cell;
+
+trait Trait<T> {}
+
+fn foo<T>()
+where
+    T: Trait<for<'b> fn(Cell<&'b u32>)>,
+{
+}
+
+impl<'a> Trait<fn(Cell<&'a u32>)> for () {}
+
+fn main() {
+    // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
+    //
+    // - The impl provides the clause `forall<'a> { (): Trait<fn(&'a u32)> }`
+    // - We instantiate `'a` existentially to get `(): Trait<fn(&?a u32)>`
+    // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)`
+    //   - This requires (among other things) instantiating `'b` universally,
+    //     yielding `fn(&!b u32)`, in a fresh universe U1
+    //   - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`.
+
+    foo::<()>(); //~ ERROR implementation of `Trait` is not general enough
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr
new file mode 100644 (file)
index 0000000..cb2ce8a
--- /dev/null
@@ -0,0 +1,11 @@
+error: implementation of `Trait` is not general enough
+  --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
+   |
+LL |     foo::<()>();
+   |     ^^^^^^^^^^^ implementation of `Trait` is not general enough
+   |
+   = note: `()` must implement `Trait<for<'b> fn(Cell<&'b u32>)>`
+   = note: ...but it actually implements `Trait<fn(Cell<&'0 u32>)>`, for some specific lifetime `'0`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs
new file mode 100644 (file)
index 0000000..f9ae142
--- /dev/null
@@ -0,0 +1,50 @@
+// Test HRTB supertraits with several levels of expansion required.
+
+trait Foo<'tcx>
+{
+    fn foo(&'tcx self) -> &'tcx isize;
+}
+
+trait Bar<'ccx>
+    : for<'tcx> Foo<'tcx>
+{
+    fn bar(&'ccx self) -> &'ccx isize;
+}
+
+trait Baz
+    : for<'ccx> Bar<'ccx>
+{
+    fn dummy(&self);
+}
+
+trait Qux
+    : Bar<'static>
+{
+    fn dummy(&self);
+}
+
+fn want_foo_for_any_tcx<F>(f: &F)
+    where F : for<'tcx> Foo<'tcx>
+{
+}
+
+fn want_bar_for_any_ccx<B>(b: &B)
+    where B : for<'ccx> Bar<'ccx>
+{
+}
+
+fn want_baz<B>(b: &B)
+    where B : Baz
+{
+    want_foo_for_any_tcx(b);
+    want_bar_for_any_ccx(b);
+}
+
+fn want_qux<B>(b: &B)
+    where B : Qux
+{
+    want_foo_for_any_tcx(b);
+    want_bar_for_any_ccx(b); //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
new file mode 100644 (file)
index 0000000..8cda76b
--- /dev/null
@@ -0,0 +1,23 @@
+error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
+  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
+   |
+LL |     want_bar_for_any_ccx(b);
+   |     -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `want_bar_for_any_ccx`
+  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15
+   |
+LL | fn want_bar_for_any_ccx<B>(b: &B)
+   |    -------------------- required by a bound in this
+LL |     where B : for<'ccx> Bar<'ccx>
+   |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
+help: consider further restricting this bound
+   |
+LL |     where B : Qux + for<'ccx> Bar<'ccx>
+   |                   +++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs
new file mode 100644 (file)
index 0000000..48ebe50
--- /dev/null
@@ -0,0 +1,48 @@
+// Test a trait (`Bar`) with a higher-ranked supertrait.
+
+trait Foo<'tcx>
+{
+    fn foo(&'tcx self) -> &'tcx isize;
+}
+
+trait Bar<'ccx>
+    : for<'tcx> Foo<'tcx>
+{
+    fn bar(&'ccx self) -> &'ccx isize;
+}
+
+fn want_foo_for_some_tcx<'x,F>(f: &'x F)
+    where F : Foo<'x>
+{
+    want_foo_for_some_tcx(f);
+    want_foo_for_any_tcx(f); //~ ERROR not satisfied
+}
+
+fn want_foo_for_any_tcx<F>(f: &F)
+    where F : for<'tcx> Foo<'tcx>
+{
+    want_foo_for_some_tcx(f);
+    want_foo_for_any_tcx(f);
+}
+
+fn want_bar_for_some_ccx<'x,B>(b: &B)
+    where B : Bar<'x>
+{
+    want_foo_for_some_tcx(b);
+    want_foo_for_any_tcx(b);
+
+    want_bar_for_some_ccx(b);
+    want_bar_for_any_ccx(b); //~ ERROR not satisfied
+}
+
+fn want_bar_for_any_ccx<B>(b: &B)
+    where B : for<'ccx> Bar<'ccx>
+{
+    want_foo_for_some_tcx(b);
+    want_foo_for_any_tcx(b);
+
+    want_bar_for_some_ccx(b);
+    want_bar_for_any_ccx(b);
+}
+
+fn main() {}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr
new file mode 100644 (file)
index 0000000..88793a1
--- /dev/null
@@ -0,0 +1,43 @@
+error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
+   |
+LL |     want_foo_for_any_tcx(f);
+   |     -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `want_foo_for_any_tcx`
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15
+   |
+LL | fn want_foo_for_any_tcx<F>(f: &F)
+   |    -------------------- required by a bound in this
+LL |     where F : for<'tcx> Foo<'tcx>
+   |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx`
+help: consider further restricting this bound
+   |
+LL |     where F : Foo<'x> + for<'tcx> Foo<'tcx>
+   |                       +++++++++++++++++++++
+
+error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
+   |
+LL |     want_bar_for_any_ccx(b);
+   |     -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `want_bar_for_any_ccx`
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15
+   |
+LL | fn want_bar_for_any_ccx<B>(b: &B)
+   |    -------------------- required by a bound in this
+LL |     where B : for<'ccx> Bar<'ccx>
+   |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
+help: consider further restricting this bound
+   |
+LL |     where B : Bar<'x> + for<'ccx> Bar<'ccx>
+   |                       +++++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs
new file mode 100644 (file)
index 0000000..89fc470
--- /dev/null
@@ -0,0 +1,26 @@
+// Test that the `'a` in the where clause correctly links the region
+// of the output to the region of the input.
+
+trait FnLike<A,R> {
+    fn call(&self, arg: A) -> R;
+}
+
+fn call_repeatedly<F>(f: F)
+    where F : for<'a> FnLike<&'a isize, &'a isize>
+{
+    // Result is stored: cannot re-assign `x`
+    let mut x = 3;
+    let y = f.call(&x);
+    x = 5; //~ ERROR cannot assign to `x` because it is borrowed
+
+    // Result is not stored: can re-assign `x`
+    let mut x = 3;
+    f.call(&x);
+    f.call(&x);
+    f.call(&x);
+    x = 5;
+    drop(y);
+}
+
+fn main() {
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr
new file mode 100644 (file)
index 0000000..4886a3c
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0506]: cannot assign to `x` because it is borrowed
+  --> $DIR/hrtb-identity-fn-borrows.rs:14:5
+   |
+LL |     let y = f.call(&x);
+   |                    -- borrow of `x` occurs here
+LL |     x = 5;
+   |     ^^^^^ assignment to borrowed `x` occurs here
+...
+LL |     drop(y);
+   |          - borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0506`.
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs
new file mode 100644 (file)
index 0000000..8fb4218
--- /dev/null
@@ -0,0 +1,35 @@
+// Test a case where you have an impl of `Foo<X>` for all `X` that
+// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
+
+trait Foo<X> {
+    fn foo(&self, x: X) { }
+}
+
+fn want_hrtb<T>()
+    where T : for<'a> Foo<&'a isize>
+{
+}
+
+// AnyInt implements Foo<&'a isize> for any 'a, so it is a match.
+struct AnyInt;
+impl<'a> Foo<&'a isize> for AnyInt { }
+fn give_any() {
+    want_hrtb::<AnyInt>()
+}
+
+// StaticInt only implements Foo<&'static isize>, so it is an error.
+struct StaticInt;
+impl Foo<&'static isize> for StaticInt { }
+fn give_static() {
+    want_hrtb::<StaticInt>() //~ ERROR
+}
+
+// &'a u32 only implements Foo<&'a isize> for specific 'a, so it is an error.
+impl<'a> Foo<&'a isize> for &'a u32 { }
+fn give_some<'a>() {
+    want_hrtb::<&'a u32>()
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR implementation of `Foo` is not general enough
+}
+
+fn main() { }
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr
new file mode 100644 (file)
index 0000000..b431209
--- /dev/null
@@ -0,0 +1,28 @@
+error: implementation of `Foo` is not general enough
+  --> $DIR/hrtb-just-for-static.rs:24:5
+   |
+LL |     want_hrtb::<StaticInt>()
+   |     ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Foo<&'static isize>`
+
+error: lifetime may not live long enough
+  --> $DIR/hrtb-just-for-static.rs:30:5
+   |
+LL | fn give_some<'a>() {
+   |              -- lifetime `'a` defined here
+LL |     want_hrtb::<&'a u32>()
+   |     ^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: implementation of `Foo` is not general enough
+  --> $DIR/hrtb-just-for-static.rs:30:5
+   |
+LL |     want_hrtb::<&'a u32>()
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo<&'0 isize>` would have to be implemented for the type `&u32`, for any lifetime `'0`...
+   = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr
new file mode 100644 (file)
index 0000000..a94c80e
--- /dev/null
@@ -0,0 +1,71 @@
+warning: function cannot return without recursing
+  --> $DIR/hrtb-perfect-forwarding.rs:16:1
+   |
+LL | / fn no_hrtb<'b, T>(mut t: T)
+LL | | where
+LL | |     T: Bar<&'b isize>,
+LL | | {
+...  |
+LL | |     no_hrtb(&mut t);
+   | |     --------------- recursive call site
+LL | | }
+   | |_^ cannot return without recursing
+   |
+   = note: `#[warn(unconditional_recursion)]` on by default
+   = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+  --> $DIR/hrtb-perfect-forwarding.rs:25:1
+   |
+LL | / fn bar_hrtb<T>(mut t: T)
+LL | | where
+LL | |     T: for<'b> Bar<&'b isize>,
+LL | | {
+...  |
+LL | |     bar_hrtb(&mut t);
+   | |     ---------------- recursive call site
+LL | | }
+   | |_^ cannot return without recursing
+   |
+   = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+  --> $DIR/hrtb-perfect-forwarding.rs:35:1
+   |
+LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
+LL | | where
+LL | |     T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
+LL | | {
+...  |
+LL | |     foo_hrtb_bar_not(&mut t);
+   | |     ------------------------ recursive call site
+LL | |
+LL | |
+LL | | }
+   | |_^ cannot return without recursing
+   |
+   = help: a `loop` may express intention better if this is on purpose
+
+error: higher-ranked subtype error
+  --> $DIR/hrtb-perfect-forwarding.rs:43:5
+   |
+LL |     foo_hrtb_bar_not(&mut t);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: function cannot return without recursing
+  --> $DIR/hrtb-perfect-forwarding.rs:48:1
+   |
+LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
+LL | | where
+LL | |     T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
+LL | | {
+LL | |     // OK -- now we have `T : for<'b> Bar<&'b isize>`.
+LL | |     foo_hrtb_bar_hrtb(&mut t);
+   | |     ------------------------- recursive call site
+LL | | }
+   | |_^ cannot return without recursing
+   |
+   = help: a `loop` may express intention better if this is on purpose
+
+error: aborting due to previous error; 4 warnings emitted
+
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs
new file mode 100644 (file)
index 0000000..d45fa18
--- /dev/null
@@ -0,0 +1,56 @@
+// Test a case where you have an impl of `Foo<X>` for all `X` that
+// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
+
+trait Foo<X> {
+    fn foo(&mut self, x: X) {}
+}
+
+trait Bar<X> {
+    fn bar(&mut self, x: X) {}
+}
+
+impl<'a, X, F> Foo<X> for &'a mut F where F: Foo<X> + Bar<X> {}
+
+impl<'a, X, F> Bar<X> for &'a mut F where F: Bar<X> {}
+
+fn no_hrtb<'b, T>(mut t: T) //~ WARN function cannot return
+where
+    T: Bar<&'b isize>,
+{
+    // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
+    // `&mut T : Bar<&'b isize>`.
+    no_hrtb(&mut t);
+}
+
+fn bar_hrtb<T>(mut t: T) //~ WARN function cannot return
+where
+    T: for<'b> Bar<&'b isize>,
+{
+    // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
+    // ensures that `&mut T : for<'b> Bar<&'b isize>`.  This is an
+    // example of a "perfect forwarding" impl.
+    bar_hrtb(&mut t);
+}
+
+fn foo_hrtb_bar_not<'b, T>(mut t: T) //~ WARN function cannot return
+where
+    T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
+{
+    // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
+    // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a
+    // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where
+    // clause only specifies `T : Bar<&'b isize>`.
+    foo_hrtb_bar_not(&mut t);
+    //~^ ERROR implementation of `Bar` is not general enough
+    //~^^ ERROR lifetime may not live long enough
+}
+
+fn foo_hrtb_bar_hrtb<T>(mut t: T) //~ WARN function cannot return
+where
+    T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
+{
+    // OK -- now we have `T : for<'b> Bar<&'b isize>`.
+    foo_hrtb_bar_hrtb(&mut t);
+}
+
+fn main() {}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr
new file mode 100644 (file)
index 0000000..1461e7f
--- /dev/null
@@ -0,0 +1,73 @@
+warning: function cannot return without recursing
+  --> $DIR/hrtb-perfect-forwarding.rs:16:1
+   |
+LL | / fn no_hrtb<'b, T>(mut t: T)
+LL | | where
+LL | |     T: Bar<&'b isize>,
+   | |______________________^ cannot return without recursing
+...
+LL |       no_hrtb(&mut t);
+   |       --------------- recursive call site
+   |
+   = note: `#[warn(unconditional_recursion)]` on by default
+   = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+  --> $DIR/hrtb-perfect-forwarding.rs:25:1
+   |
+LL | / fn bar_hrtb<T>(mut t: T)
+LL | | where
+LL | |     T: for<'b> Bar<&'b isize>,
+   | |______________________________^ cannot return without recursing
+...
+LL |       bar_hrtb(&mut t);
+   |       ---------------- recursive call site
+   |
+   = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+  --> $DIR/hrtb-perfect-forwarding.rs:35:1
+   |
+LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
+LL | | where
+LL | |     T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
+   | |_______________________________________________^ cannot return without recursing
+...
+LL |       foo_hrtb_bar_not(&mut t);
+   |       ------------------------ recursive call site
+   |
+   = help: a `loop` may express intention better if this is on purpose
+
+error: lifetime may not live long enough
+  --> $DIR/hrtb-perfect-forwarding.rs:43:5
+   |
+LL | fn foo_hrtb_bar_not<'b, T>(mut t: T)
+   |                     -- lifetime `'b` defined here
+...
+LL |     foo_hrtb_bar_not(&mut t);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
+
+error: implementation of `Bar` is not general enough
+  --> $DIR/hrtb-perfect-forwarding.rs:43:5
+   |
+LL |     foo_hrtb_bar_not(&mut t);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
+   |
+   = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1`
+
+warning: function cannot return without recursing
+  --> $DIR/hrtb-perfect-forwarding.rs:48:1
+   |
+LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
+LL | | where
+LL | |     T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
+   | |_______________________________________________________^ cannot return without recursing
+...
+LL |       foo_hrtb_bar_hrtb(&mut t);
+   |       ------------------------- recursive call site
+   |
+   = help: a `loop` may express intention better if this is on purpose
+
+error: aborting due to 2 previous errors; 4 warnings emitted
+
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-30786.rs b/src/test/ui/higher-rank-trait-bounds/issue-30786.rs
new file mode 100644 (file)
index 0000000..e5f46f7
--- /dev/null
@@ -0,0 +1,134 @@
+// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
+// should act as assertion that item does not borrow from its stream;
+// but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
+// have such an item.
+//
+// This tests double-checks that we do not allow such behavior to leak
+// through again.
+
+pub trait Stream {
+    type Item;
+    fn next(self) -> Option<Self::Item>;
+}
+
+// Example stream
+pub struct Repeat(u64);
+
+impl<'a> Stream for &'a mut Repeat {
+    type Item = &'a u64;
+    fn next(self) -> Option<Self::Item> {
+        Some(&self.0)
+    }
+}
+
+pub struct Map<S, F> {
+    stream: S,
+    func: F,
+}
+
+impl<'a, A, F, T> Stream for &'a mut Map<A, F>
+where
+    &'a mut A: Stream,
+    F: FnMut(<&'a mut A as Stream>::Item) -> T,
+{
+    type Item = T;
+    fn next(self) -> Option<T> {
+        match self.stream.next() {
+            Some(item) => Some((self.func)(item)),
+            None => None,
+        }
+    }
+}
+
+pub struct Filter<S, F> {
+    stream: S,
+    func: F,
+}
+
+impl<'a, A, F, T> Stream for &'a mut Filter<A, F>
+where
+    for<'b> &'b mut A: Stream<Item = T>, // <---- BAD
+    F: FnMut(&T) -> bool,
+{
+    type Item = <&'a mut A as Stream>::Item;
+    fn next(self) -> Option<Self::Item> {
+        while let Some(item) = self.stream.next() {
+            if (self.func)(&item) {
+                return Some(item);
+            }
+        }
+        None
+    }
+}
+
+pub trait StreamExt
+where
+    for<'b> &'b mut Self: Stream,
+{
+    fn mapx<F>(self, func: F) -> Map<Self, F>
+    where
+        Self: Sized,
+        for<'a> &'a mut Map<Self, F>: Stream,
+    {
+        Map { func: func, stream: self }
+    }
+
+    fn filterx<F>(self, func: F) -> Filter<Self, F>
+    where
+        Self: Sized,
+        for<'a> &'a mut Filter<Self, F>: Stream,
+    {
+        Filter { func: func, stream: self }
+    }
+
+    fn countx(mut self) -> usize
+    where
+        Self: Sized,
+    {
+        let mut count = 0;
+        while let Some(_) = self.next() {
+            count += 1;
+        }
+        count
+    }
+}
+
+impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
+
+fn identity<T>(x: &T) -> &T {
+    x
+}
+
+fn variant1() {
+    let source = Repeat(10);
+
+    // Here, the call to `mapx` returns a type `T` to which `StreamExt`
+    // is not applicable, because `for<'b> &'b mut T: Stream`) doesn't hold.
+    //
+    // More concretely, the type `T` is `Map<Repeat, Closure>`, and
+    // the where clause doesn't hold because the signature of the
+    // closure gets inferred to a signature like `|&'_ Stream| -> &'_`
+    // for some specific `'_`, rather than a more generic
+    // signature.
+    //
+    // Why *exactly* we opt for this signature is a bit unclear to me,
+    // we deduce it somehow from a reuqirement that `Map: Stream` I
+    // guess.
+    let map = source.mapx(|x: &_| x);
+    let filter = map.filterx(|x: &_| true);
+    //~^ ERROR the method
+}
+
+fn variant2() {
+    let source = Repeat(10);
+
+    // Here, we use a function, which is not subject to the vagaries
+    // of closure signature inference. In this case, we get the error
+    // on `countx` as, I think, the test originally expected.
+    let map = source.mapx(identity);
+    let filter = map.filterx(|x: &_| true);
+    let count = filter.countx();
+    //~^ ERROR the method
+}
+
+fn main() {}
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-30786.stderr b/src/test/ui/higher-rank-trait-bounds/issue-30786.stderr
new file mode 100644 (file)
index 0000000..ffe3d7b
--- /dev/null
@@ -0,0 +1,45 @@
+error[E0599]: the method `filterx` exists for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>`, but its trait bounds were not satisfied
+  --> $DIR/issue-30786.rs:118:22
+   |
+LL | pub struct Map<S, F> {
+   | --------------------
+   | |
+   | method `filterx` not found for this struct
+   | doesn't satisfy `_: StreamExt`
+...
+LL |     let filter = map.filterx(|x: &_| true);
+   |                      ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>` due to unsatisfied trait bounds
+   |
+note: the following trait bounds were not satisfied:
+      `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
+      `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
+      `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
+  --> $DIR/issue-30786.rs:96:50
+   |
+LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
+   |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
+
+error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>`, but its trait bounds were not satisfied
+  --> $DIR/issue-30786.rs:130:24
+   |
+LL | pub struct Filter<S, F> {
+   | -----------------------
+   | |
+   | method `countx` not found for this struct
+   | doesn't satisfy `_: StreamExt`
+...
+LL |     let count = filter.countx();
+   |                        ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>` due to unsatisfied trait bounds
+   |
+note: the following trait bounds were not satisfied:
+      `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
+      `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
+      `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
+  --> $DIR/issue-30786.rs:96:50
+   |
+LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
+   |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-46989.rs b/src/test/ui/higher-rank-trait-bounds/issue-46989.rs
new file mode 100644 (file)
index 0000000..4a09f4b
--- /dev/null
@@ -0,0 +1,40 @@
+// Regression test for #46989:
+//
+// In the move to universes, this test started passing.
+// It is not necessarily WRONG to do so, but it was a bit
+// surprising. The reason that it passed is that when we were
+// asked to prove that
+//
+//     for<'a> fn(&'a i32): Foo
+//
+// we were able to use the impl below to prove
+//
+//     fn(&'empty i32): Foo
+//
+// and then we were able to prove that
+//
+//     fn(&'empty i32) = for<'a> fn(&'a i32)
+//
+// This last fact is somewhat surprising, but essentially "falls out"
+// from handling variance correctly. In particular, consider the subtyping
+// relations. First:
+//
+//     fn(&'empty i32) <: for<'a> fn(&'a i32)
+//
+// This holds because -- intuitively -- a fn that takes a reference but doesn't use
+// it can be given a reference with any lifetime. Similarly, the opposite direction:
+//
+//     for<'a> fn(&'a i32) <: fn(&'empty i32)
+//
+// holds because 'a can be instantiated to 'empty.
+
+trait Foo {}
+
+impl<A> Foo for fn(A) {}
+
+fn assert_foo<T: Foo>() {}
+
+fn main() {
+    assert_foo::<fn(&i32)>();
+    //~^ ERROR implementation of `Foo` is not general enough
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-46989.stderr b/src/test/ui/higher-rank-trait-bounds/issue-46989.stderr
new file mode 100644 (file)
index 0000000..309e1a6
--- /dev/null
@@ -0,0 +1,11 @@
+error: implementation of `Foo` is not general enough
+  --> $DIR/issue-46989.rs:38:5
+   |
+LL |     assert_foo::<fn(&i32)>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r i32)`
+   = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-57639.rs b/src/test/ui/higher-rank-trait-bounds/issue-57639.rs
new file mode 100644 (file)
index 0000000..392e723
--- /dev/null
@@ -0,0 +1,29 @@
+// Regression test for #57639:
+//
+// In the move to universes, this test stopped working. The problem
+// was that when the trait solver was asked to prove `for<'a> T::Item:
+// Foo<'a>` as part of WF checking, it wound up "eagerly committing"
+// to the where clause, which says that `T::Item: Foo<'a>`, but it
+// should instead have been using the bound found in the trait
+// declaration. Pre-universe, this used to work out ok because we got
+// "eager errors" due to the leak check.
+//
+// See [this comment on GitHub][c] for more details.
+//
+// check-pass
+//
+// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861
+
+trait Foo<'a> {}
+
+trait Bar {
+    type Item: for<'a> Foo<'a>;
+}
+
+fn foo<'a, T>(_: T)
+where
+    T: Bar,
+    T::Item: Foo<'a>,
+{}
+
+fn main() { }
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-58451.rs b/src/test/ui/higher-rank-trait-bounds/issue-58451.rs
new file mode 100644 (file)
index 0000000..f36d549
--- /dev/null
@@ -0,0 +1,13 @@
+// Regression test for #58451:
+//
+// Error reporting here encountered an ICE in the shift to universes.
+
+fn f<I>(i: I)
+where
+    I: IntoIterator,
+    I::Item: for<'a> Into<&'a ()>,
+{}
+
+fn main() {
+    f(&[f()]); //~ ERROR this function takes 1 argument
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-58451.stderr b/src/test/ui/higher-rank-trait-bounds/issue-58451.stderr
new file mode 100644 (file)
index 0000000..22ba63c
--- /dev/null
@@ -0,0 +1,19 @@
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+  --> $DIR/issue-58451.rs:12:9
+   |
+LL |     f(&[f()]);
+   |         ^-- an argument is missing
+   |
+note: function defined here
+  --> $DIR/issue-58451.rs:5:4
+   |
+LL | fn f<I>(i: I)
+   |    ^    ----
+help: provide the argument
+   |
+LL |     f(&[f(/* value */)]);
+   |         ~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs
new file mode 100644 (file)
index 0000000..e70f6fc
--- /dev/null
@@ -0,0 +1,54 @@
+trait T0<'a, A> {
+    type O;
+}
+
+struct L<T> {
+    f: T,
+}
+
+// explicitly named variants of what one would normally denote by the
+// unit type `()`. Why do this? So that we can differentiate them in
+// the diagnostic output.
+struct Unit1;
+struct Unit2;
+struct Unit3;
+struct Unit4;
+
+impl<'a, A, T> T0<'a, A> for L<T>
+where
+    T: FnMut(A) -> Unit3,
+{
+    type O = T::Output;
+}
+
+trait T1: for<'r> Ty<'r> {
+    fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
+    where
+        F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
+    {
+        unimplemented!();
+    }
+}
+
+trait Ty<'a> {
+    type V;
+}
+
+fn main() {
+    let v = Unit2.m(
+        L {
+            //~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4`
+            //~| ERROR type mismatch
+            f: |x| {
+                drop(x);
+                Unit4
+            },
+        },
+    );
+}
+
+impl<'a> Ty<'a> for Unit2 {
+    type V = &'a u8;
+}
+
+impl T1 for Unit2 {}
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
new file mode 100644 (file)
index 0000000..51017ff
--- /dev/null
@@ -0,0 +1,63 @@
+error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
+  --> $DIR/issue-62203-hrtb-ice.rs:39:9
+   |
+LL |       let v = Unit2.m(
+   |                     - required by a bound introduced by this call
+LL | /         L {
+LL | |
+LL | |
+LL | |             f: |x| {
+...  |
+LL | |             },
+LL | |         },
+   | |_________^ type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
+   |
+note: expected this to be `<_ as Ty<'_>>::V`
+  --> $DIR/issue-62203-hrtb-ice.rs:21:14
+   |
+LL |     type O = T::Output;
+   |              ^^^^^^^^^
+   = note: expected associated type `<_ as Ty<'_>>::V`
+                       found struct `Unit4`
+   = help: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` or calling a method that returns `<_ as Ty<'_>>::V`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+note: required by a bound in `T1::m`
+  --> $DIR/issue-62203-hrtb-ice.rs:27:51
+   |
+LL |     fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
+   |        - required by a bound in this
+LL |     where
+LL |         F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
+   |                                                   ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
+
+error[E0271]: expected `[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]` to be a closure that returns `Unit3`, but it returns `Unit4`
+  --> $DIR/issue-62203-hrtb-ice.rs:39:9
+   |
+LL |       let v = Unit2.m(
+   |                     - required by a bound introduced by this call
+LL | /         L {
+LL | |
+LL | |
+LL | |             f: |x| {
+...  |
+LL | |             },
+LL | |         },
+   | |_________^ expected struct `Unit3`, found struct `Unit4`
+   |
+note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>`
+  --> $DIR/issue-62203-hrtb-ice.rs:17:16
+   |
+LL | impl<'a, A, T> T0<'a, A> for L<T>
+   |                ^^^^^^^^^     ^^^^
+note: required by a bound in `T1::m`
+  --> $DIR/issue-62203-hrtb-ice.rs:27:12
+   |
+LL |     fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
+   |        - required by a bound in this
+LL |     where
+LL |         F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-88446.rs b/src/test/ui/higher-rank-trait-bounds/issue-88446.rs
new file mode 100644 (file)
index 0000000..571b853
--- /dev/null
@@ -0,0 +1,35 @@
+// check-pass
+
+trait Yokeable<'a> {
+    type Output: 'a;
+}
+impl<'a> Yokeable<'a> for () {
+    type Output = ();
+}
+
+trait DataMarker<'data> {
+    type Yokeable: for<'a> Yokeable<'a>;
+}
+impl<'data> DataMarker<'data> for () {
+    type Yokeable = ();
+}
+
+struct DataPayload<'data, M>(&'data M);
+
+impl DataPayload<'static, ()> {
+    pub fn map_project_with_capture<M2, T>(
+        _: for<'a> fn(
+            capture: T,
+            std::marker::PhantomData<&'a ()>,
+        ) -> <M2::Yokeable as Yokeable<'a>>::Output,
+    ) -> DataPayload<'static, M2>
+    where
+        M2: DataMarker<'static>,
+    {
+        todo!()
+    }
+}
+
+fn main() {
+    let _: DataPayload<()> = DataPayload::<()>::map_project_with_capture::<_, &()>(|_, _| todo!());
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-90177.rs b/src/test/ui/higher-rank-trait-bounds/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/higher-rank-trait-bounds/issue-95034.rs b/src/test/ui/higher-rank-trait-bounds/issue-95034.rs
new file mode 100644 (file)
index 0000000..d8edbe7
--- /dev/null
@@ -0,0 +1,98 @@
+// known-bug: #95034
+// failure-status: 101
+// compile-flags: --edition=2021 --crate-type=lib
+// rustc-env:RUST_BACKTRACE=0
+
+// normalize-stderr-test "thread 'rustc' panicked.*" -> "thread 'rustc' panicked"
+// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
+// normalize-stderr-test "query stack during panic:\n" -> ""
+// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> ""
+// normalize-stderr-test "end of query stack\n" -> ""
+// normalize-stderr-test "#.*\n" -> ""
+
+// This should not ICE.
+
+// Refer to the issue for more minimized versions.
+
+use std::{
+    future::Future,
+    marker::PhantomData,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+mod object {
+    use super::*;
+
+    pub trait Object<'a> {
+        type Error;
+        type Future: Future<Output = Self>;
+        fn create() -> Self::Future;
+    }
+
+    impl<'a> Object<'a> for u8 {
+        type Error = ();
+        type Future = Pin<Box<dyn Future<Output = Self>>>;
+        fn create() -> Self::Future {
+            unimplemented!()
+        }
+    }
+
+    impl<'a, E, A: Object<'a, Error = E>> Object<'a> for (A,) {
+        type Error = ();
+        type Future = CustomFut<'a, E, A>;
+        fn create() -> Self::Future {
+            unimplemented!()
+        }
+    }
+
+    pub struct CustomFut<'f, E, A: Object<'f, Error = E>> {
+        ph: PhantomData<(A::Future,)>,
+    }
+
+    impl<'f, E, A: Object<'f, Error = E>> Future for CustomFut<'f, E, A> {
+        type Output = (A,);
+        fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
+            unimplemented!()
+        }
+    }
+}
+
+mod async_fn {
+    use super::*;
+
+    pub trait AsyncFn {
+        type Future: Future<Output = ()>;
+        fn call(&self) -> Self::Future;
+    }
+
+    impl<F, Fut> AsyncFn for F
+    where
+        F: Fn() -> Fut,
+        Fut: Future<Output = ()>,
+    {
+        type Future = Fut;
+        fn call(&self) -> Self::Future {
+            (self)()
+        }
+    }
+}
+
+pub async fn test() {
+    use self::{async_fn::AsyncFn, object::Object};
+
+    async fn create<T: Object<'static>>() {
+        T::create().await;
+    }
+
+    async fn call_async_fn(inner: impl AsyncFn) {
+        inner.call().await;
+    }
+
+    call_async_fn(create::<(u8,)>).await;
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-95034.stderr b/src/test/ui/higher-rank-trait-bounds/issue-95034.stderr
new file mode 100644 (file)
index 0000000..1d83291
--- /dev/null
@@ -0,0 +1 @@
+thread 'rustc' panicked
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-95230.rs b/src/test/ui/higher-rank-trait-bounds/issue-95230.rs
new file mode 100644 (file)
index 0000000..92c506e
--- /dev/null
@@ -0,0 +1,7 @@
+// check-pass
+
+pub struct Bar
+where
+    for<'a> &'a mut Self:;
+
+fn main() {}
diff --git a/src/test/ui/hrtb/complex.rs b/src/test/ui/hrtb/complex.rs
deleted file mode 100644 (file)
index 8cdfe24..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// check-pass
-
-trait A<'a> {}
-trait B<'b> {}
-fn foo<T>() where for<'a> T: A<'a> + 'a {}
-trait C<'c>: for<'a> A<'a> + for<'b> B<'b> {
-    type As;
-}
-struct D<T> where T: for<'c> C<'c, As=&'c ()> {
-    t: std::marker::PhantomData<T>,
-}
-trait E<'e, 'g> {
-    type As;
-}
-trait F<'f>: for<'a> A<'a> + for<'e> E<'e, 'f> {}
-struct G<T> where T: for<'f> F<'f, As=&'f ()> {
-    t: std::marker::PhantomData<T>,
-}
-trait H<'a, 'b> {
-    type As;
-}
-trait I<'a>: for<'b> H<'a, 'b> {}
-
-struct J<T> where T: for<'i> I<'i, As=&'i ()> {
-    t: std::marker::PhantomData<T>,
-}
-
-fn main() {}
diff --git a/src/test/ui/hrtb/due-to-where-clause.rs b/src/test/ui/hrtb/due-to-where-clause.rs
deleted file mode 100644 (file)
index 1afd156..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-fn main() {
-    test::<FooS>(&mut 42); //~ ERROR implementation of `Foo` is not general enough
-}
-
-trait Foo<'a> {}
-
-struct FooS<'a> {
-    data: &'a mut u32,
-}
-
-impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {}
-
-fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {}
diff --git a/src/test/ui/hrtb/due-to-where-clause.stderr b/src/test/ui/hrtb/due-to-where-clause.stderr
deleted file mode 100644 (file)
index 520938a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error: implementation of `Foo` is not general enough
-  --> $DIR/due-to-where-clause.rs:2:5
-   |
-LL |     test::<FooS>(&mut 42);
-   |     ^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
-   = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.rs b/src/test/ui/hrtb/hrtb-cache-issue-54302.rs
deleted file mode 100644 (file)
index a20d03c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Regression test for #54302.
-//
-// We were incorrectly using the "evaluation cache" (which ignored
-// region results) to conclude that `&'static str: Deserialize`, even
-// though it would require that `for<'de> 'de: 'static`, which is
-// clearly false.
-
-trait Deserialize<'de> {}
-
-trait DeserializeOwned: for<'de> Deserialize<'de> {}
-impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
-
-// Based on this impl, `&'static str` only implements Deserialize<'static>.
-// It does not implement for<'de> Deserialize<'de>.
-impl<'de: 'a, 'a> Deserialize<'de> for &'a str {}
-
-fn main() {
-    fn assert_deserialize_owned<T: DeserializeOwned>() {}
-    assert_deserialize_owned::<&'static str>(); //~ ERROR
-
-    // It correctly does not implement for<'de> Deserialize<'de>.
-    // fn assert_hrtb<T: for<'de> Deserialize<'de>>() {}
-    // assert_hrtb::<&'static str>();
-}
diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr
deleted file mode 100644 (file)
index f014eab..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error: implementation of `Deserialize` is not general enough
-  --> $DIR/hrtb-cache-issue-54302.rs:19:5
-   |
-LL |     assert_deserialize_owned::<&'static str>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
-   |
-   = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
-   = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.rs b/src/test/ui/hrtb/hrtb-conflate-regions.rs
deleted file mode 100644 (file)
index e836864..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// Test that an impl with only one bound region `'a` cannot be used to
-// satisfy a constraint where there are two bound regions.
-
-trait Foo<X> {
-    fn foo(&self, x: X) { }
-}
-
-fn want_foo2<T>()
-    where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
-{
-}
-
-fn want_foo1<T>()
-    where T : for<'z> Foo<(&'z isize, &'z isize)>
-{
-}
-
-// Expressed as a where clause
-
-struct SomeStruct;
-
-impl<'a> Foo<(&'a isize, &'a isize)> for SomeStruct
-{
-}
-
-fn a() { want_foo1::<SomeStruct>(); } // OK -- foo wants just one region
-fn b() { want_foo2::<SomeStruct>(); }
-//~^ ERROR implementation of
-//~| ERROR implementation of
-
-fn main() { }
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
deleted file mode 100644 (file)
index 46f5308..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error: implementation of `Foo` is not general enough
-  --> $DIR/hrtb-conflate-regions.rs:27:10
-   |
-LL | fn b() { want_foo2::<SomeStruct>(); }
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
-
-error: implementation of `Foo` is not general enough
-  --> $DIR/hrtb-conflate-regions.rs:27:10
-   |
-LL | fn b() { want_foo2::<SomeStruct>(); }
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/hrtb/hrtb-debruijn-in-receiver.rs b/src/test/ui/hrtb/hrtb-debruijn-in-receiver.rs
deleted file mode 100644 (file)
index 05d3e1a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Test the case where the `Self` type has a bound lifetime that must
-// be adjusted in the fn signature. Issue #19537.
-
-use std::collections::HashMap;
-
-struct Foo<'a> {
-    map: HashMap<usize, &'a str>
-}
-
-impl<'a> Foo<'a> {
-    fn new() -> Foo<'a> { panic!() }
-    fn insert(&'a mut self) { }
-}
-fn main() {
-    let mut foo = Foo::new();
-    foo.insert();
-    foo.insert(); //~ ERROR cannot borrow
-}
diff --git a/src/test/ui/hrtb/hrtb-debruijn-in-receiver.stderr b/src/test/ui/hrtb/hrtb-debruijn-in-receiver.stderr
deleted file mode 100644 (file)
index fa391ec..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0499]: cannot borrow `foo` as mutable more than once at a time
-  --> $DIR/hrtb-debruijn-in-receiver.rs:17:5
-   |
-LL |     foo.insert();
-   |     ------------ first mutable borrow occurs here
-LL |     foo.insert();
-   |     ^^^^^^^^^^^^
-   |     |
-   |     second mutable borrow occurs here
-   |     first borrow later used here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0499`.
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.rs b/src/test/ui/hrtb/hrtb-exists-forall-fn.rs
deleted file mode 100644 (file)
index 5678023..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile!
-//
-// In particular, we test this pattern in trait solving, where it is not connected
-// to any part of the source code.
-
-fn foo<'a>() -> fn(&'a u32) {
-    panic!()
-}
-
-fn main() {
-    // Here, proving that `fn(&'a u32) <: for<'b> fn(&'b u32)`:
-    //
-    // - instantiates `'b` with a placeholder `!b`,
-    // - requires that `&!b u32 <: &'a u32` and hence that `!b: 'a`,
-    // - but we can never know this.
-
-    let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types
-}
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr b/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr
deleted file mode 100644 (file)
index 9914783..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/hrtb-exists-forall-fn.rs:17:34
-   |
-LL |     let _: for<'b> fn(&'b u32) = foo();
-   |                                  ^^^^^ one type is more general than the other
-   |
-   = note: expected fn pointer `for<'b> fn(&'b u32)`
-              found fn pointer `fn(&u32)`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs
deleted file mode 100644 (file)
index 9210619..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// Test a case where variance and higher-ranked types interact in surprising ways.
-//
-// In particular, we test this pattern in trait solving, where it is not connected
-// to any part of the source code.
-
-trait Trait<T> {}
-
-fn foo<T>()
-where
-    T: Trait<for<'b> fn(&'b u32)>,
-{
-}
-
-impl<'a> Trait<fn(&'a u32)> for () {}
-
-fn main() {
-    // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
-    //
-    // - The impl provides the clause `forall<'a> { (): Trait<fn(&'a u32)> }`
-    // - We instantiate `'a` existentially to get `(): Trait<fn(&?a u32)>`
-    // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` -- this does a
-    //   "bidirectional" subtyping check, so we wind up with:
-    //   - `fn(&?a u32) <: for<'b> fn(&'b u32)` :-
-    //     - `&'!b u32 <: &?a u32`
-    //     - `!'b: ?a` -- solveable if `?a` is inferred to `'empty`
-    //   - `for<'b> fn(&'b u32) <: fn(&?a u32)` :-
-    //     - `&?a u32 u32 <: &?b u32`
-    //     - `?a: ?b` -- solveable if `?b` is also inferred to `'empty`
-    // - So the subtyping check succeeds, somewhat surprisingly.
-    //   This is because we can use `'empty`.
-    //
-    // NB. *However*, the reinstated leak-check gives an error here.
-
-    foo::<()>();
-    //~^ ERROR implementation of `Trait` is not general enough
-}
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
deleted file mode 100644 (file)
index 364b613..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error: implementation of `Trait` is not general enough
-  --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
-   |
-LL |     foo::<()>();
-   |     ^^^^^^^^^^^ implementation of `Trait` is not general enough
-   |
-   = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
-   = note: ...but it actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs
deleted file mode 100644 (file)
index f95496a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Test a case where variance and higher-ranked types interact in surprising ways.
-//
-// In particular, we test this pattern in trait solving, where it is not connected
-// to any part of the source code.
-//
-// check-pass
-
-trait Trait<T> {}
-
-fn foo<T>()
-where
-    T: Trait<for<'b> fn(fn(&'b u32))>,
-{
-}
-
-impl<'a> Trait<fn(fn(&'a u32))> for () {}
-
-fn main() {
-    // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
-    //
-    // - The impl provides the clause `forall<'a> { (): Trait<fn(fn(&'a u32))> }`
-    // - We instantiate `'a` existentially to get `(): Trait<fn(fn(&?a u32))>`
-    // - We unify `fn(fn(&?a u32))` with `for<'b> fn(fn(&'b u32))` -- this does a
-    //   "bidirectional" subtyping check, so we wind up with:
-    //   - `fn(fn(&?a u32)) <: for<'b> fn(fn(&'b u32))` :-
-    //     - `fn(&!b u32) <: fn(&?a u32)`
-    //       - `&?a u32 <: &!b u32`
-    //         - `?a: !'b` -- solveable if `?a` is inferred to `'static`
-    //   - `for<'b> fn(fn(&'b u32)) <: fn(fn(&?a u32))` :-
-    //     - `fn(&?a u32) <: fn(&?b u32)`
-    //       - `&?b u32 <: &?a u32`
-    //         - `?b: ?a` -- solveable if `?b` is inferred to `'static`
-    // - So the subtyping check succeeds, somewhat surprisingly.
-    //   This is because we can use `'static`.
-
-    foo::<()>();
-}
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs
deleted file mode 100644 (file)
index 9b9e449..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile!
-//
-// In particular, we test this pattern in trait solving, where it is not connected
-// to any part of the source code.
-
-use std::cell::Cell;
-
-trait Trait<T> {}
-
-fn foo<T>()
-where
-    T: Trait<for<'b> fn(Cell<&'b u32>)>,
-{
-}
-
-impl<'a> Trait<fn(Cell<&'a u32>)> for () {}
-
-fn main() {
-    // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
-    //
-    // - The impl provides the clause `forall<'a> { (): Trait<fn(&'a u32)> }`
-    // - We instantiate `'a` existentially to get `(): Trait<fn(&?a u32)>`
-    // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)`
-    //   - This requires (among other things) instantiating `'b` universally,
-    //     yielding `fn(&!b u32)`, in a fresh universe U1
-    //   - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`.
-
-    foo::<()>(); //~ ERROR implementation of `Trait` is not general enough
-}
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
deleted file mode 100644 (file)
index cb2ce8a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error: implementation of `Trait` is not general enough
-  --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
-   |
-LL |     foo::<()>();
-   |     ^^^^^^^^^^^ implementation of `Trait` is not general enough
-   |
-   = note: `()` must implement `Trait<for<'b> fn(Cell<&'b u32>)>`
-   = note: ...but it actually implements `Trait<fn(Cell<&'0 u32>)>`, for some specific lifetime `'0`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs
deleted file mode 100644 (file)
index f9ae142..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// Test HRTB supertraits with several levels of expansion required.
-
-trait Foo<'tcx>
-{
-    fn foo(&'tcx self) -> &'tcx isize;
-}
-
-trait Bar<'ccx>
-    : for<'tcx> Foo<'tcx>
-{
-    fn bar(&'ccx self) -> &'ccx isize;
-}
-
-trait Baz
-    : for<'ccx> Bar<'ccx>
-{
-    fn dummy(&self);
-}
-
-trait Qux
-    : Bar<'static>
-{
-    fn dummy(&self);
-}
-
-fn want_foo_for_any_tcx<F>(f: &F)
-    where F : for<'tcx> Foo<'tcx>
-{
-}
-
-fn want_bar_for_any_ccx<B>(b: &B)
-    where B : for<'ccx> Bar<'ccx>
-{
-}
-
-fn want_baz<B>(b: &B)
-    where B : Baz
-{
-    want_foo_for_any_tcx(b);
-    want_bar_for_any_ccx(b);
-}
-
-fn want_qux<B>(b: &B)
-    where B : Qux
-{
-    want_foo_for_any_tcx(b);
-    want_bar_for_any_ccx(b); //~ ERROR
-}
-
-fn main() {}
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
deleted file mode 100644 (file)
index 8cda76b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
-   |
-LL |     want_bar_for_any_ccx(b);
-   |     -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
-   |     |
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `want_bar_for_any_ccx`
-  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15
-   |
-LL | fn want_bar_for_any_ccx<B>(b: &B)
-   |    -------------------- required by a bound in this
-LL |     where B : for<'ccx> Bar<'ccx>
-   |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
-help: consider further restricting this bound
-   |
-LL |     where B : Qux + for<'ccx> Bar<'ccx>
-   |                   +++++++++++++++++++++
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs
deleted file mode 100644 (file)
index 48ebe50..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-// Test a trait (`Bar`) with a higher-ranked supertrait.
-
-trait Foo<'tcx>
-{
-    fn foo(&'tcx self) -> &'tcx isize;
-}
-
-trait Bar<'ccx>
-    : for<'tcx> Foo<'tcx>
-{
-    fn bar(&'ccx self) -> &'ccx isize;
-}
-
-fn want_foo_for_some_tcx<'x,F>(f: &'x F)
-    where F : Foo<'x>
-{
-    want_foo_for_some_tcx(f);
-    want_foo_for_any_tcx(f); //~ ERROR not satisfied
-}
-
-fn want_foo_for_any_tcx<F>(f: &F)
-    where F : for<'tcx> Foo<'tcx>
-{
-    want_foo_for_some_tcx(f);
-    want_foo_for_any_tcx(f);
-}
-
-fn want_bar_for_some_ccx<'x,B>(b: &B)
-    where B : Bar<'x>
-{
-    want_foo_for_some_tcx(b);
-    want_foo_for_any_tcx(b);
-
-    want_bar_for_some_ccx(b);
-    want_bar_for_any_ccx(b); //~ ERROR not satisfied
-}
-
-fn want_bar_for_any_ccx<B>(b: &B)
-    where B : for<'ccx> Bar<'ccx>
-{
-    want_foo_for_some_tcx(b);
-    want_foo_for_any_tcx(b);
-
-    want_bar_for_some_ccx(b);
-    want_bar_for_any_ccx(b);
-}
-
-fn main() {}
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
deleted file mode 100644 (file)
index 88793a1..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
-   |
-LL |     want_foo_for_any_tcx(f);
-   |     -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
-   |     |
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `want_foo_for_any_tcx`
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15
-   |
-LL | fn want_foo_for_any_tcx<F>(f: &F)
-   |    -------------------- required by a bound in this
-LL |     where F : for<'tcx> Foo<'tcx>
-   |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx`
-help: consider further restricting this bound
-   |
-LL |     where F : Foo<'x> + for<'tcx> Foo<'tcx>
-   |                       +++++++++++++++++++++
-
-error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
-   |
-LL |     want_bar_for_any_ccx(b);
-   |     -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
-   |     |
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `want_bar_for_any_ccx`
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15
-   |
-LL | fn want_bar_for_any_ccx<B>(b: &B)
-   |    -------------------- required by a bound in this
-LL |     where B : for<'ccx> Bar<'ccx>
-   |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
-help: consider further restricting this bound
-   |
-LL |     where B : Bar<'x> + for<'ccx> Bar<'ccx>
-   |                       +++++++++++++++++++++
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/hrtb/hrtb-identity-fn-borrows.rs b/src/test/ui/hrtb/hrtb-identity-fn-borrows.rs
deleted file mode 100644 (file)
index 89fc470..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Test that the `'a` in the where clause correctly links the region
-// of the output to the region of the input.
-
-trait FnLike<A,R> {
-    fn call(&self, arg: A) -> R;
-}
-
-fn call_repeatedly<F>(f: F)
-    where F : for<'a> FnLike<&'a isize, &'a isize>
-{
-    // Result is stored: cannot re-assign `x`
-    let mut x = 3;
-    let y = f.call(&x);
-    x = 5; //~ ERROR cannot assign to `x` because it is borrowed
-
-    // Result is not stored: can re-assign `x`
-    let mut x = 3;
-    f.call(&x);
-    f.call(&x);
-    f.call(&x);
-    x = 5;
-    drop(y);
-}
-
-fn main() {
-}
diff --git a/src/test/ui/hrtb/hrtb-identity-fn-borrows.stderr b/src/test/ui/hrtb/hrtb-identity-fn-borrows.stderr
deleted file mode 100644 (file)
index 4886a3c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0506]: cannot assign to `x` because it is borrowed
-  --> $DIR/hrtb-identity-fn-borrows.rs:14:5
-   |
-LL |     let y = f.call(&x);
-   |                    -- borrow of `x` occurs here
-LL |     x = 5;
-   |     ^^^^^ assignment to borrowed `x` occurs here
-...
-LL |     drop(y);
-   |          - borrow later used here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0506`.
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.rs b/src/test/ui/hrtb/hrtb-just-for-static.rs
deleted file mode 100644 (file)
index 8fb4218..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// Test a case where you have an impl of `Foo<X>` for all `X` that
-// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
-
-trait Foo<X> {
-    fn foo(&self, x: X) { }
-}
-
-fn want_hrtb<T>()
-    where T : for<'a> Foo<&'a isize>
-{
-}
-
-// AnyInt implements Foo<&'a isize> for any 'a, so it is a match.
-struct AnyInt;
-impl<'a> Foo<&'a isize> for AnyInt { }
-fn give_any() {
-    want_hrtb::<AnyInt>()
-}
-
-// StaticInt only implements Foo<&'static isize>, so it is an error.
-struct StaticInt;
-impl Foo<&'static isize> for StaticInt { }
-fn give_static() {
-    want_hrtb::<StaticInt>() //~ ERROR
-}
-
-// &'a u32 only implements Foo<&'a isize> for specific 'a, so it is an error.
-impl<'a> Foo<&'a isize> for &'a u32 { }
-fn give_some<'a>() {
-    want_hrtb::<&'a u32>()
-    //~^ ERROR lifetime may not live long enough
-    //~| ERROR implementation of `Foo` is not general enough
-}
-
-fn main() { }
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr
deleted file mode 100644 (file)
index b431209..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-error: implementation of `Foo` is not general enough
-  --> $DIR/hrtb-just-for-static.rs:24:5
-   |
-LL |     want_hrtb::<StaticInt>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
-   = note: ...but it actually implements `Foo<&'static isize>`
-
-error: lifetime may not live long enough
-  --> $DIR/hrtb-just-for-static.rs:30:5
-   |
-LL | fn give_some<'a>() {
-   |              -- lifetime `'a` defined here
-LL |     want_hrtb::<&'a u32>()
-   |     ^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
-
-error: implementation of `Foo` is not general enough
-  --> $DIR/hrtb-just-for-static.rs:30:5
-   |
-LL |     want_hrtb::<&'a u32>()
-   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `Foo<&'0 isize>` would have to be implemented for the type `&u32`, for any lifetime `'0`...
-   = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
-
-error: aborting due to 3 previous errors
-
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr
deleted file mode 100644 (file)
index a94c80e..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:16:1
-   |
-LL | / fn no_hrtb<'b, T>(mut t: T)
-LL | | where
-LL | |     T: Bar<&'b isize>,
-LL | | {
-...  |
-LL | |     no_hrtb(&mut t);
-   | |     --------------- recursive call site
-LL | | }
-   | |_^ cannot return without recursing
-   |
-   = note: `#[warn(unconditional_recursion)]` on by default
-   = help: a `loop` may express intention better if this is on purpose
-
-warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:25:1
-   |
-LL | / fn bar_hrtb<T>(mut t: T)
-LL | | where
-LL | |     T: for<'b> Bar<&'b isize>,
-LL | | {
-...  |
-LL | |     bar_hrtb(&mut t);
-   | |     ---------------- recursive call site
-LL | | }
-   | |_^ cannot return without recursing
-   |
-   = help: a `loop` may express intention better if this is on purpose
-
-warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:35:1
-   |
-LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
-LL | | where
-LL | |     T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
-LL | | {
-...  |
-LL | |     foo_hrtb_bar_not(&mut t);
-   | |     ------------------------ recursive call site
-LL | |
-LL | |
-LL | | }
-   | |_^ cannot return without recursing
-   |
-   = help: a `loop` may express intention better if this is on purpose
-
-error: higher-ranked subtype error
-  --> $DIR/hrtb-perfect-forwarding.rs:43:5
-   |
-LL |     foo_hrtb_bar_not(&mut t);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:48:1
-   |
-LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
-LL | | where
-LL | |     T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
-LL | | {
-LL | |     // OK -- now we have `T : for<'b> Bar<&'b isize>`.
-LL | |     foo_hrtb_bar_hrtb(&mut t);
-   | |     ------------------------- recursive call site
-LL | | }
-   | |_^ cannot return without recursing
-   |
-   = help: a `loop` may express intention better if this is on purpose
-
-error: aborting due to previous error; 4 warnings emitted
-
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs
deleted file mode 100644 (file)
index d45fa18..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// Test a case where you have an impl of `Foo<X>` for all `X` that
-// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
-
-trait Foo<X> {
-    fn foo(&mut self, x: X) {}
-}
-
-trait Bar<X> {
-    fn bar(&mut self, x: X) {}
-}
-
-impl<'a, X, F> Foo<X> for &'a mut F where F: Foo<X> + Bar<X> {}
-
-impl<'a, X, F> Bar<X> for &'a mut F where F: Bar<X> {}
-
-fn no_hrtb<'b, T>(mut t: T) //~ WARN function cannot return
-where
-    T: Bar<&'b isize>,
-{
-    // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
-    // `&mut T : Bar<&'b isize>`.
-    no_hrtb(&mut t);
-}
-
-fn bar_hrtb<T>(mut t: T) //~ WARN function cannot return
-where
-    T: for<'b> Bar<&'b isize>,
-{
-    // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
-    // ensures that `&mut T : for<'b> Bar<&'b isize>`.  This is an
-    // example of a "perfect forwarding" impl.
-    bar_hrtb(&mut t);
-}
-
-fn foo_hrtb_bar_not<'b, T>(mut t: T) //~ WARN function cannot return
-where
-    T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
-{
-    // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
-    // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a
-    // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where
-    // clause only specifies `T : Bar<&'b isize>`.
-    foo_hrtb_bar_not(&mut t);
-    //~^ ERROR implementation of `Bar` is not general enough
-    //~^^ ERROR lifetime may not live long enough
-}
-
-fn foo_hrtb_bar_hrtb<T>(mut t: T) //~ WARN function cannot return
-where
-    T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
-{
-    // OK -- now we have `T : for<'b> Bar<&'b isize>`.
-    foo_hrtb_bar_hrtb(&mut t);
-}
-
-fn main() {}
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr
deleted file mode 100644 (file)
index 1461e7f..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:16:1
-   |
-LL | / fn no_hrtb<'b, T>(mut t: T)
-LL | | where
-LL | |     T: Bar<&'b isize>,
-   | |______________________^ cannot return without recursing
-...
-LL |       no_hrtb(&mut t);
-   |       --------------- recursive call site
-   |
-   = note: `#[warn(unconditional_recursion)]` on by default
-   = help: a `loop` may express intention better if this is on purpose
-
-warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:25:1
-   |
-LL | / fn bar_hrtb<T>(mut t: T)
-LL | | where
-LL | |     T: for<'b> Bar<&'b isize>,
-   | |______________________________^ cannot return without recursing
-...
-LL |       bar_hrtb(&mut t);
-   |       ---------------- recursive call site
-   |
-   = help: a `loop` may express intention better if this is on purpose
-
-warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:35:1
-   |
-LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
-LL | | where
-LL | |     T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
-   | |_______________________________________________^ cannot return without recursing
-...
-LL |       foo_hrtb_bar_not(&mut t);
-   |       ------------------------ recursive call site
-   |
-   = help: a `loop` may express intention better if this is on purpose
-
-error: lifetime may not live long enough
-  --> $DIR/hrtb-perfect-forwarding.rs:43:5
-   |
-LL | fn foo_hrtb_bar_not<'b, T>(mut t: T)
-   |                     -- lifetime `'b` defined here
-...
-LL |     foo_hrtb_bar_not(&mut t);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
-
-error: implementation of `Bar` is not general enough
-  --> $DIR/hrtb-perfect-forwarding.rs:43:5
-   |
-LL |     foo_hrtb_bar_not(&mut t);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
-   |
-   = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`...
-   = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1`
-
-warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:48:1
-   |
-LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
-LL | | where
-LL | |     T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
-   | |_______________________________________________________^ cannot return without recursing
-...
-LL |       foo_hrtb_bar_hrtb(&mut t);
-   |       ------------------------- recursive call site
-   |
-   = help: a `loop` may express intention better if this is on purpose
-
-error: aborting due to 2 previous errors; 4 warnings emitted
-
diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/hrtb/issue-30786.rs
deleted file mode 100644 (file)
index e5f46f7..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
-// should act as assertion that item does not borrow from its stream;
-// but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
-// have such an item.
-//
-// This tests double-checks that we do not allow such behavior to leak
-// through again.
-
-pub trait Stream {
-    type Item;
-    fn next(self) -> Option<Self::Item>;
-}
-
-// Example stream
-pub struct Repeat(u64);
-
-impl<'a> Stream for &'a mut Repeat {
-    type Item = &'a u64;
-    fn next(self) -> Option<Self::Item> {
-        Some(&self.0)
-    }
-}
-
-pub struct Map<S, F> {
-    stream: S,
-    func: F,
-}
-
-impl<'a, A, F, T> Stream for &'a mut Map<A, F>
-where
-    &'a mut A: Stream,
-    F: FnMut(<&'a mut A as Stream>::Item) -> T,
-{
-    type Item = T;
-    fn next(self) -> Option<T> {
-        match self.stream.next() {
-            Some(item) => Some((self.func)(item)),
-            None => None,
-        }
-    }
-}
-
-pub struct Filter<S, F> {
-    stream: S,
-    func: F,
-}
-
-impl<'a, A, F, T> Stream for &'a mut Filter<A, F>
-where
-    for<'b> &'b mut A: Stream<Item = T>, // <---- BAD
-    F: FnMut(&T) -> bool,
-{
-    type Item = <&'a mut A as Stream>::Item;
-    fn next(self) -> Option<Self::Item> {
-        while let Some(item) = self.stream.next() {
-            if (self.func)(&item) {
-                return Some(item);
-            }
-        }
-        None
-    }
-}
-
-pub trait StreamExt
-where
-    for<'b> &'b mut Self: Stream,
-{
-    fn mapx<F>(self, func: F) -> Map<Self, F>
-    where
-        Self: Sized,
-        for<'a> &'a mut Map<Self, F>: Stream,
-    {
-        Map { func: func, stream: self }
-    }
-
-    fn filterx<F>(self, func: F) -> Filter<Self, F>
-    where
-        Self: Sized,
-        for<'a> &'a mut Filter<Self, F>: Stream,
-    {
-        Filter { func: func, stream: self }
-    }
-
-    fn countx(mut self) -> usize
-    where
-        Self: Sized,
-    {
-        let mut count = 0;
-        while let Some(_) = self.next() {
-            count += 1;
-        }
-        count
-    }
-}
-
-impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
-
-fn identity<T>(x: &T) -> &T {
-    x
-}
-
-fn variant1() {
-    let source = Repeat(10);
-
-    // Here, the call to `mapx` returns a type `T` to which `StreamExt`
-    // is not applicable, because `for<'b> &'b mut T: Stream`) doesn't hold.
-    //
-    // More concretely, the type `T` is `Map<Repeat, Closure>`, and
-    // the where clause doesn't hold because the signature of the
-    // closure gets inferred to a signature like `|&'_ Stream| -> &'_`
-    // for some specific `'_`, rather than a more generic
-    // signature.
-    //
-    // Why *exactly* we opt for this signature is a bit unclear to me,
-    // we deduce it somehow from a reuqirement that `Map: Stream` I
-    // guess.
-    let map = source.mapx(|x: &_| x);
-    let filter = map.filterx(|x: &_| true);
-    //~^ ERROR the method
-}
-
-fn variant2() {
-    let source = Repeat(10);
-
-    // Here, we use a function, which is not subject to the vagaries
-    // of closure signature inference. In this case, we get the error
-    // on `countx` as, I think, the test originally expected.
-    let map = source.mapx(identity);
-    let filter = map.filterx(|x: &_| true);
-    let count = filter.countx();
-    //~^ ERROR the method
-}
-
-fn main() {}
diff --git a/src/test/ui/hrtb/issue-30786.stderr b/src/test/ui/hrtb/issue-30786.stderr
deleted file mode 100644 (file)
index ffe3d7b..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-error[E0599]: the method `filterx` exists for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>`, but its trait bounds were not satisfied
-  --> $DIR/issue-30786.rs:118:22
-   |
-LL | pub struct Map<S, F> {
-   | --------------------
-   | |
-   | method `filterx` not found for this struct
-   | doesn't satisfy `_: StreamExt`
-...
-LL |     let filter = map.filterx(|x: &_| true);
-   |                      ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>` due to unsatisfied trait bounds
-   |
-note: the following trait bounds were not satisfied:
-      `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
-      `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
-      `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
-  --> $DIR/issue-30786.rs:96:50
-   |
-LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
-   |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
-
-error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>`, but its trait bounds were not satisfied
-  --> $DIR/issue-30786.rs:130:24
-   |
-LL | pub struct Filter<S, F> {
-   | -----------------------
-   | |
-   | method `countx` not found for this struct
-   | doesn't satisfy `_: StreamExt`
-...
-LL |     let count = filter.countx();
-   |                        ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>` due to unsatisfied trait bounds
-   |
-note: the following trait bounds were not satisfied:
-      `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
-      `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
-      `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
-  --> $DIR/issue-30786.rs:96:50
-   |
-LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
-   |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/hrtb/issue-46989.rs b/src/test/ui/hrtb/issue-46989.rs
deleted file mode 100644 (file)
index 4a09f4b..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// Regression test for #46989:
-//
-// In the move to universes, this test started passing.
-// It is not necessarily WRONG to do so, but it was a bit
-// surprising. The reason that it passed is that when we were
-// asked to prove that
-//
-//     for<'a> fn(&'a i32): Foo
-//
-// we were able to use the impl below to prove
-//
-//     fn(&'empty i32): Foo
-//
-// and then we were able to prove that
-//
-//     fn(&'empty i32) = for<'a> fn(&'a i32)
-//
-// This last fact is somewhat surprising, but essentially "falls out"
-// from handling variance correctly. In particular, consider the subtyping
-// relations. First:
-//
-//     fn(&'empty i32) <: for<'a> fn(&'a i32)
-//
-// This holds because -- intuitively -- a fn that takes a reference but doesn't use
-// it can be given a reference with any lifetime. Similarly, the opposite direction:
-//
-//     for<'a> fn(&'a i32) <: fn(&'empty i32)
-//
-// holds because 'a can be instantiated to 'empty.
-
-trait Foo {}
-
-impl<A> Foo for fn(A) {}
-
-fn assert_foo<T: Foo>() {}
-
-fn main() {
-    assert_foo::<fn(&i32)>();
-    //~^ ERROR implementation of `Foo` is not general enough
-}
diff --git a/src/test/ui/hrtb/issue-46989.stderr b/src/test/ui/hrtb/issue-46989.stderr
deleted file mode 100644 (file)
index 309e1a6..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error: implementation of `Foo` is not general enough
-  --> $DIR/issue-46989.rs:38:5
-   |
-LL |     assert_foo::<fn(&i32)>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r i32)`
-   = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/hrtb/issue-57639.rs b/src/test/ui/hrtb/issue-57639.rs
deleted file mode 100644 (file)
index 392e723..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Regression test for #57639:
-//
-// In the move to universes, this test stopped working. The problem
-// was that when the trait solver was asked to prove `for<'a> T::Item:
-// Foo<'a>` as part of WF checking, it wound up "eagerly committing"
-// to the where clause, which says that `T::Item: Foo<'a>`, but it
-// should instead have been using the bound found in the trait
-// declaration. Pre-universe, this used to work out ok because we got
-// "eager errors" due to the leak check.
-//
-// See [this comment on GitHub][c] for more details.
-//
-// check-pass
-//
-// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861
-
-trait Foo<'a> {}
-
-trait Bar {
-    type Item: for<'a> Foo<'a>;
-}
-
-fn foo<'a, T>(_: T)
-where
-    T: Bar,
-    T::Item: Foo<'a>,
-{}
-
-fn main() { }
diff --git a/src/test/ui/hrtb/issue-58451.rs b/src/test/ui/hrtb/issue-58451.rs
deleted file mode 100644 (file)
index f36d549..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Regression test for #58451:
-//
-// Error reporting here encountered an ICE in the shift to universes.
-
-fn f<I>(i: I)
-where
-    I: IntoIterator,
-    I::Item: for<'a> Into<&'a ()>,
-{}
-
-fn main() {
-    f(&[f()]); //~ ERROR this function takes 1 argument
-}
diff --git a/src/test/ui/hrtb/issue-58451.stderr b/src/test/ui/hrtb/issue-58451.stderr
deleted file mode 100644 (file)
index 22ba63c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0061]: this function takes 1 argument but 0 arguments were supplied
-  --> $DIR/issue-58451.rs:12:9
-   |
-LL |     f(&[f()]);
-   |         ^-- an argument is missing
-   |
-note: function defined here
-  --> $DIR/issue-58451.rs:5:4
-   |
-LL | fn f<I>(i: I)
-   |    ^    ----
-help: provide the argument
-   |
-LL |     f(&[f(/* value */)]);
-   |         ~~~~~~~~~~~~~~
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.rs b/src/test/ui/hrtb/issue-62203-hrtb-ice.rs
deleted file mode 100644 (file)
index ae21dbc..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-trait T0<'a, A> {
-    type O;
-}
-
-struct L<T> {
-    f: T,
-}
-
-// explicitly named variants of what one would normally denote by the
-// unit type `()`. Why do this? So that we can differentiate them in
-// the diagnostic output.
-struct Unit1;
-struct Unit2;
-struct Unit3;
-struct Unit4;
-
-impl<'a, A, T> T0<'a, A> for L<T>
-where
-    T: FnMut(A) -> Unit3,
-{
-    type O = T::Output;
-}
-
-trait T1: for<'r> Ty<'r> {
-    fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
-    where
-        F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
-    {
-        unimplemented!();
-    }
-}
-
-trait Ty<'a> {
-    type V;
-}
-
-fn main() {
-    let v = Unit2.m(
-        //~^ ERROR type mismatch
-        L {
-            //~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4`
-            f: |x| {
-                drop(x);
-                Unit4
-            },
-        },
-    );
-}
-
-impl<'a> Ty<'a> for Unit2 {
-    type V = &'a u8;
-}
-
-impl T1 for Unit2 {}
diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
deleted file mode 100644 (file)
index 8365fd0..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
-  --> $DIR/issue-62203-hrtb-ice.rs:38:19
-   |
-LL |     let v = Unit2.m(
-   |                   ^ type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
-   |
-note: expected this to be `<_ as Ty<'_>>::V`
-  --> $DIR/issue-62203-hrtb-ice.rs:21:14
-   |
-LL |     type O = T::Output;
-   |              ^^^^^^^^^
-   = note: expected associated type `<_ as Ty<'_>>::V`
-                       found struct `Unit4`
-   = help: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` or calling a method that returns `<_ as Ty<'_>>::V`
-   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
-note: required by a bound in `T1::m`
-  --> $DIR/issue-62203-hrtb-ice.rs:27:51
-   |
-LL |     fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
-   |        - required by a bound in this
-LL |     where
-LL |         F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
-   |                                                   ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
-
-error[E0271]: expected `[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]` to be a closure that returns `Unit3`, but it returns `Unit4`
-  --> $DIR/issue-62203-hrtb-ice.rs:40:9
-   |
-LL |       let v = Unit2.m(
-   |                     - required by a bound introduced by this call
-LL |
-LL | /         L {
-LL | |
-LL | |             f: |x| {
-LL | |                 drop(x);
-LL | |                 Unit4
-LL | |             },
-LL | |         },
-   | |_________^ expected struct `Unit3`, found struct `Unit4`
-   |
-note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>`
-  --> $DIR/issue-62203-hrtb-ice.rs:17:16
-   |
-LL | impl<'a, A, T> T0<'a, A> for L<T>
-   |                ^^^^^^^^^     ^^^^
-note: required by a bound in `T1::m`
-  --> $DIR/issue-62203-hrtb-ice.rs:27:12
-   |
-LL |     fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
-   |        - required by a bound in this
-LL |     where
-LL |         F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/hrtb/issue-88446.rs b/src/test/ui/hrtb/issue-88446.rs
deleted file mode 100644 (file)
index 571b853..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// check-pass
-
-trait Yokeable<'a> {
-    type Output: 'a;
-}
-impl<'a> Yokeable<'a> for () {
-    type Output = ();
-}
-
-trait DataMarker<'data> {
-    type Yokeable: for<'a> Yokeable<'a>;
-}
-impl<'data> DataMarker<'data> for () {
-    type Yokeable = ();
-}
-
-struct DataPayload<'data, M>(&'data M);
-
-impl DataPayload<'static, ()> {
-    pub fn map_project_with_capture<M2, T>(
-        _: for<'a> fn(
-            capture: T,
-            std::marker::PhantomData<&'a ()>,
-        ) -> <M2::Yokeable as Yokeable<'a>>::Output,
-    ) -> DataPayload<'static, M2>
-    where
-        M2: DataMarker<'static>,
-    {
-        todo!()
-    }
-}
-
-fn main() {
-    let _: DataPayload<()> = DataPayload::<()>::map_project_with_capture::<_, &()>(|_, _| todo!());
-}
diff --git a/src/test/ui/hrtb/issue-90177.rs b/src/test/ui/hrtb/issue-90177.rs
deleted file mode 100644 (file)
index b151a9d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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/hrtb/issue-95034.rs b/src/test/ui/hrtb/issue-95034.rs
deleted file mode 100644 (file)
index d8edbe7..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// known-bug: #95034
-// failure-status: 101
-// compile-flags: --edition=2021 --crate-type=lib
-// rustc-env:RUST_BACKTRACE=0
-
-// normalize-stderr-test "thread 'rustc' panicked.*" -> "thread 'rustc' panicked"
-// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
-// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
-// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
-// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
-// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
-// normalize-stderr-test "query stack during panic:\n" -> ""
-// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> ""
-// normalize-stderr-test "end of query stack\n" -> ""
-// normalize-stderr-test "#.*\n" -> ""
-
-// This should not ICE.
-
-// Refer to the issue for more minimized versions.
-
-use std::{
-    future::Future,
-    marker::PhantomData,
-    pin::Pin,
-    task::{Context, Poll},
-};
-
-mod object {
-    use super::*;
-
-    pub trait Object<'a> {
-        type Error;
-        type Future: Future<Output = Self>;
-        fn create() -> Self::Future;
-    }
-
-    impl<'a> Object<'a> for u8 {
-        type Error = ();
-        type Future = Pin<Box<dyn Future<Output = Self>>>;
-        fn create() -> Self::Future {
-            unimplemented!()
-        }
-    }
-
-    impl<'a, E, A: Object<'a, Error = E>> Object<'a> for (A,) {
-        type Error = ();
-        type Future = CustomFut<'a, E, A>;
-        fn create() -> Self::Future {
-            unimplemented!()
-        }
-    }
-
-    pub struct CustomFut<'f, E, A: Object<'f, Error = E>> {
-        ph: PhantomData<(A::Future,)>,
-    }
-
-    impl<'f, E, A: Object<'f, Error = E>> Future for CustomFut<'f, E, A> {
-        type Output = (A,);
-        fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
-            unimplemented!()
-        }
-    }
-}
-
-mod async_fn {
-    use super::*;
-
-    pub trait AsyncFn {
-        type Future: Future<Output = ()>;
-        fn call(&self) -> Self::Future;
-    }
-
-    impl<F, Fut> AsyncFn for F
-    where
-        F: Fn() -> Fut,
-        Fut: Future<Output = ()>,
-    {
-        type Future = Fut;
-        fn call(&self) -> Self::Future {
-            (self)()
-        }
-    }
-}
-
-pub async fn test() {
-    use self::{async_fn::AsyncFn, object::Object};
-
-    async fn create<T: Object<'static>>() {
-        T::create().await;
-    }
-
-    async fn call_async_fn(inner: impl AsyncFn) {
-        inner.call().await;
-    }
-
-    call_async_fn(create::<(u8,)>).await;
-}
diff --git a/src/test/ui/hrtb/issue-95034.stderr b/src/test/ui/hrtb/issue-95034.stderr
deleted file mode 100644 (file)
index 1d83291..0000000
+++ /dev/null
@@ -1 +0,0 @@
-thread 'rustc' panicked
diff --git a/src/test/ui/hrtb/issue-95230.rs b/src/test/ui/hrtb/issue-95230.rs
deleted file mode 100644 (file)
index 92c506e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// check-pass
-
-pub struct Bar
-where
-    for<'a> &'a mut Self:;
-
-fn main() {}
index e7b7e4a4a910c85d9251fc6e32959f6a1c0a7ee1..1a761ad5441cea3887270de031594c2bb21cc138 100644 (file)
@@ -52,10 +52,12 @@ LL |     G: FnOnce<ARG, Output = RET> + ~const Destruct,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
 
 error[E0271]: expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
-  --> $DIR/const-eval-select-bad.rs:29:5
+  --> $DIR/const-eval-select-bad.rs:29:34
    |
 LL |     const_eval_select((1,), foo, bar);
-   |     ^^^^^^^^^^^^^^^^^ expected `i32`, found `bool`
+   |     -----------------            ^^^ expected `i32`, found `bool`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
index 3a1d43310e2fc30d3b8b5992e45392d233191ca7..15b2bbeb7c29526b1bfb1a223ff465cf227dbca0 100644 (file)
@@ -14,7 +14,7 @@ note: associated function defined here
   --> $DIR/issue-11374.rs:13:12
    |
 LL |     pub fn read_to(&mut self, vec: &mut [u8]) {
-   |            ^^^^^^^ ---------  --------------
+   |            ^^^^^^^            --------------
 
 error: aborting due to previous error
 
index 6499dd0d81b1c67c08b09fc1c355ff952d3a2977..e499d0572f607c278f7f6ad8334de0d29e3e34fb 100644 (file)
@@ -2,11 +2,13 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/issue-18819.rs:16:5
    |
 LL |     print_x(X);
-   |     ^^^^^^^---
-   |            ||
-   |            |expected reference, found struct `X`
-   |            an argument of type `&str` is missing
+   |     ^^^^^^^--- an argument of type `&str` is missing
    |
+note: expected reference, found struct `X`
+  --> $DIR/issue-18819.rs:16:13
+   |
+LL |     print_x(X);
+   |             ^
    = note: expected reference `&dyn Foo<Item = bool>`
                  found struct `X`
 note: function defined here
index 4909398bb848f6b6ce02b9597b7c806b1e46fca8..731615a6bd8d4d37e5540d9fee4683d391306e98 100644 (file)
@@ -1,3 +1,12 @@
+error[E0191]: the value of the associated type `Output` (from trait `Add`) must be specified
+  --> $DIR/issue-21950.rs:10:25
+   |
+LL |     type Output;
+   |     ----------- `Output` defined here
+...
+LL |     let x = &10 as &dyn Add;
+   |                         ^^^ help: specify the associated type: `Add<Output = Type>`
+
 error[E0393]: the type parameter `Rhs` must be explicitly specified
   --> $DIR/issue-21950.rs:10:25
    |
@@ -9,15 +18,6 @@ LL |     let x = &10 as &dyn Add;
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types
 
-error[E0191]: the value of the associated type `Output` (from trait `Add`) must be specified
-  --> $DIR/issue-21950.rs:10:25
-   |
-LL |     type Output;
-   |     ----------- `Output` defined here
-...
-LL |     let x = &10 as &dyn Add;
-   |                         ^^^ help: specify the associated type: `Add<Output = Type>`
-
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0191, E0393.
diff --git a/src/test/ui/let-else/issue-94176.rs b/src/test/ui/let-else/issue-94176.rs
new file mode 100644 (file)
index 0000000..e35bbd8
--- /dev/null
@@ -0,0 +1,10 @@
+// Issue #94176: wrong span for the error message of a mismatched type error,
+// if the function uses a `let else` construct.
+#![feature(let_else)]
+
+pub fn test(a: Option<u32>) -> Option<u32> { //~ ERROR mismatched types
+    let Some(_) = a else { return None; };
+    println!("Foo");
+}
+
+fn main() {}
diff --git a/src/test/ui/let-else/issue-94176.stderr b/src/test/ui/let-else/issue-94176.stderr
new file mode 100644 (file)
index 0000000..0cb97ac
--- /dev/null
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-94176.rs:5:32
+   |
+LL | pub fn test(a: Option<u32>) -> Option<u32> {
+   |        ----                    ^^^^^^^^^^^ expected enum `Option`, found `()`
+   |        |
+   |        implicitly returns `()` as its body has no tail or `return` expression
+   |
+   = note:   expected enum `Option<u32>`
+           found unit type `()`
+help: consider returning the local binding `a`
+   |
+LL ~     println!("Foo");
+LL +     a
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/let-else/let-else-then-diverge.rs b/src/test/ui/let-else/let-else-then-diverge.rs
new file mode 100644 (file)
index 0000000..49633d9
--- /dev/null
@@ -0,0 +1,19 @@
+//
+// popped up in in #94012, where an alternative desugaring was
+// causing unreachable code errors
+
+#![feature(let_else)]
+#![deny(unused_variables)]
+#![deny(unreachable_code)]
+
+fn let_else_diverge() -> bool {
+    let Some(_) = Some("test") else {
+        let x = 5; //~ ERROR unused variable: `x`
+        return false;
+    };
+    return true;
+}
+
+fn main() {
+    let_else_diverge();
+}
diff --git a/src/test/ui/let-else/let-else-then-diverge.stderr b/src/test/ui/let-else/let-else-then-diverge.stderr
new file mode 100644 (file)
index 0000000..ceb6102
--- /dev/null
@@ -0,0 +1,14 @@
+error: unused variable: `x`
+  --> $DIR/let-else-then-diverge.rs:11:13
+   |
+LL |         let x = 5;
+   |             ^ help: if this is intentional, prefix it with an underscore: `_x`
+   |
+note: the lint level is defined here
+  --> $DIR/let-else-then-diverge.rs:6:9
+   |
+LL | #![deny(unused_variables)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/lint-attr-everywhere-early.rs b/src/test/ui/lint/lint-attr-everywhere-early.rs
new file mode 100644 (file)
index 0000000..fd0c4b4
--- /dev/null
@@ -0,0 +1,176 @@
+// Tests that lint levels can be set for early lints.
+#![allow(non_camel_case_types, unsafe_code, while_true, unused_parens)]
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+fn verify_no_warnings() {
+    type non_camel_type = i32; // non_camel_case_types
+    struct NON_CAMEL_IS_ALLOWED; // non_camel_case_types
+    unsafe {} // unsafe_code
+    enum Enum {
+        VARIANT_CAMEL // non_camel_case_types
+    }
+    fn generics<foo>() {} // non_camel_case_types
+    while true {} // while_true
+    type T = (i32); // unused_parens
+}
+
+
+// ################## Types
+
+#[deny(non_camel_case_types)]
+type type_outer = i32; //~ ERROR type `type_outer` should have an upper camel case name
+
+type BareFnPtr = fn(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+// There aren't any early lints that currently apply to the variadic spot.
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(non_camel_case_types)]
+struct ITEM_OUTER; //~ ERROR type `ITEM_OUTER` should have an upper camel case name
+
+mod module_inner {
+    #![deny(unsafe_code)]
+    fn f() {
+        unsafe {} //~ ERROR usage of an `unsafe` block
+    }
+}
+
+struct Associated;
+impl Associated {
+    #![deny(unsafe_code)]
+
+    fn inherent_denied_from_inner() { unsafe {} } //~ usage of an `unsafe` block
+
+    #[deny(while_true)]
+    fn inherent_fn() { while true {} } //~ ERROR denote infinite loops with
+
+    #[deny(while_true)]
+    const INHERENT_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+}
+
+trait trait_inner { //~ ERROR trait `trait_inner` should have an upper camel case name
+    #![deny(non_camel_case_types)]
+}
+
+trait AssociatedTrait {
+    #![deny(unsafe_code)]
+
+    fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+    #[deny(while_true)]
+    fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+    #[deny(while_true)]
+    const ASSOC_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+
+    #[deny(non_camel_case_types)]
+    type assoc_type; //~ ERROR associated type `assoc_type` should have an upper camel case name
+}
+
+impl AssociatedTrait for Associated {
+    #![deny(unsafe_code)]
+
+    fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+    #[deny(while_true)]
+    fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+    #[deny(while_true)]
+    const ASSOC_CONST: i32 = {while true {} 1};  //~ ERROR denote infinite loops with
+
+    #[deny(unused_parens)]
+    type assoc_type = (i32); //~ ERROR unnecessary parentheses around type
+}
+
+struct StructFields {
+    #[deny(unused_parens)]f1: (i32), //~ ERROR unnecessary parentheses around type
+}
+struct StructTuple(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+
+enum Enum {
+    #[deny(non_camel_case_types)]
+    VARIANT_CAMEL, //~ ERROR variant `VARIANT_CAMEL` should have an upper camel case name
+}
+
+extern "C" {
+    #![deny(unused_parens)]
+
+    fn foreign_denied_from_inner(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+extern "C" {
+    #[deny(unused_parens)]
+    fn foreign_denied_from_outer(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+fn function(#[deny(unused_parens)] param: (i32)) {} //~ ERROR unnecessary parentheses around type
+
+fn generics<#[deny(non_camel_case_types)]foo>() {} //~ ERROR type parameter `foo` should have an upper camel case name
+
+
+// ################## Statements
+fn statements() {
+    #[deny(unused_parens)]
+    let x = (1); //~ ERROR unnecessary parentheses around assigned value
+}
+
+
+// ################## Expressions
+fn expressions() {
+    let closure = |#[deny(unused_parens)] param: (i32)| {}; //~ ERROR unnecessary parentheses around type
+
+    struct Match{f1: i32}
+    // Strangely unused_parens doesn't fire with {f1: (123)}
+    let f = Match{#[deny(unused_parens)]f1: {(123)}}; //~ ERROR unnecessary parentheses around block return value
+
+    match f {
+        #![deny(unsafe_code)]
+
+        #[deny(while_true)]
+        Match{f1} => {
+            unsafe {} //~ ERROR usage of an `unsafe` block
+            while true {} //~ ERROR denote infinite loops with
+        }
+    }
+
+    // Statement Block
+    {
+        #![deny(unsafe_code)]
+        unsafe {} //~ ERROR usage of an `unsafe` block
+    }
+    let block_tail = {
+        #[deny(unsafe_code)]
+        unsafe {} //~ ERROR usage of an `unsafe` block
+    };
+
+    // Before expression as a statement.
+    #[deny(unsafe_code)]
+    unsafe {}; //~ ERROR usage of an `unsafe` block
+
+    [#[deny(unsafe_code)] unsafe {123}]; //~ ERROR usage of an `unsafe` block
+    (#[deny(unsafe_code)] unsafe {123},); //~ ERROR usage of an `unsafe` block
+    fn call(p: i32) {}
+    call(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+    struct TupleStruct(i32);
+    TupleStruct(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+}
+
+
+// ################## Patterns
+fn patterns() {
+    struct PatField{f1: i32, f2: i32};
+    let f = PatField{f1: 1, f2: 2};
+    match f {
+        PatField {
+            #[deny(ellipsis_inclusive_range_patterns)]
+            f1: 0...100,
+            //~^ ERROR range patterns are deprecated
+            //~| WARNING this is accepted in the current edition
+            ..
+        } => {}
+        _ => {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-attr-everywhere-early.stderr b/src/test/ui/lint/lint-attr-everywhere-early.stderr
new file mode 100644 (file)
index 0000000..1d6e3cd
--- /dev/null
@@ -0,0 +1,486 @@
+error: type `type_outer` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:22:6
+   |
+LL | type type_outer = i32;
+   |      ^^^^^^^^^^ help: convert the identifier to upper camel case: `TypeOuter`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:21:8
+   |
+LL | #[deny(non_camel_case_types)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:24:43
+   |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+   |                                           ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:24:28
+   |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+   |                            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL - type BareFnPtr = fn(#[deny(unused_parens)](i32));
+LL + type BareFnPtr = fn(#[deny(unused_parens)]i32);
+   |
+
+error: type `ITEM_OUTER` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:30:8
+   |
+LL | struct ITEM_OUTER;
+   |        ^^^^^^^^^^ help: convert the identifier to upper camel case: `ItemOuter`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:29:8
+   |
+LL | #[deny(non_camel_case_types)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:35:9
+   |
+LL |         unsafe {}
+   |         ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:33:13
+   |
+LL |     #![deny(unsafe_code)]
+   |             ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:43:39
+   |
+LL |     fn inherent_denied_from_inner() { unsafe {} }
+   |                                       ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:41:13
+   |
+LL |     #![deny(unsafe_code)]
+   |             ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:46:24
+   |
+LL |     fn inherent_fn() { while true {} }
+   |                        ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:45:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:49:34
+   |
+LL |     const INHERENT_CONST: i32 = {while true {} 1};
+   |                                  ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:48:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: trait `trait_inner` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:52:7
+   |
+LL | trait trait_inner {
+   |       ^^^^^^^^^^^ help: convert the identifier to upper camel case: `TraitInner`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:53:13
+   |
+LL |     #![deny(non_camel_case_types)]
+   |             ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:59:30
+   |
+LL |     fn denied_from_inner() { unsafe {} }
+   |                              ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:57:13
+   |
+LL |     #![deny(unsafe_code)]
+   |             ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:62:21
+   |
+LL |     fn assoc_fn() { while true {} }
+   |                     ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:61:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:65:31
+   |
+LL |     const ASSOC_CONST: i32 = {while true {} 1};
+   |                               ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:64:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: associated type `assoc_type` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:68:10
+   |
+LL |     type assoc_type;
+   |          ^^^^^^^^^^ help: convert the identifier to upper camel case: `AssocType`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:67:12
+   |
+LL |     #[deny(non_camel_case_types)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:74:30
+   |
+LL |     fn denied_from_inner() { unsafe {} }
+   |                              ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:72:13
+   |
+LL |     #![deny(unsafe_code)]
+   |             ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:77:21
+   |
+LL |     fn assoc_fn() { while true {} }
+   |                     ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:76:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:80:31
+   |
+LL |     const ASSOC_CONST: i32 = {while true {} 1};
+   |                               ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:79:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:83:23
+   |
+LL |     type assoc_type = (i32);
+   |                       ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:82:12
+   |
+LL |     #[deny(unused_parens)]
+   |            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     type assoc_type = (i32);
+LL +     type assoc_type = i32;
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:87:31
+   |
+LL |     #[deny(unused_parens)]f1: (i32),
+   |                               ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:87:12
+   |
+LL |     #[deny(unused_parens)]f1: (i32),
+   |            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     #[deny(unused_parens)]f1: (i32),
+LL +     #[deny(unused_parens)]f1: i32,
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:89:42
+   |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+   |                                          ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:89:27
+   |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+   |                           ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL - struct StructTuple(#[deny(unused_parens)](i32));
+LL + struct StructTuple(#[deny(unused_parens)]i32);
+   |
+
+error: variant `VARIANT_CAMEL` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:93:5
+   |
+LL |     VARIANT_CAMEL,
+   |     ^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `VariantCamel`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:92:12
+   |
+LL |     #[deny(non_camel_case_types)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:99:37
+   |
+LL |     fn foreign_denied_from_inner(x: (i32));
+   |                                     ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:97:13
+   |
+LL |     #![deny(unused_parens)]
+   |             ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     fn foreign_denied_from_inner(x: (i32));
+LL +     fn foreign_denied_from_inner(x: i32);
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:104:37
+   |
+LL |     fn foreign_denied_from_outer(x: (i32));
+   |                                     ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:103:12
+   |
+LL |     #[deny(unused_parens)]
+   |            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     fn foreign_denied_from_outer(x: (i32));
+LL +     fn foreign_denied_from_outer(x: i32);
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:107:43
+   |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+   |                                           ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:107:20
+   |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+   |                    ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL - fn function(#[deny(unused_parens)] param: (i32)) {}
+LL + fn function(#[deny(unused_parens)] param: i32) {}
+   |
+
+error: type parameter `foo` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:109:42
+   |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+   |                                          ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:109:20
+   |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+   |                    ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around assigned value
+  --> $DIR/lint-attr-everywhere-early.rs:115:13
+   |
+LL |     let x = (1);
+   |             ^ ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:114:12
+   |
+LL |     #[deny(unused_parens)]
+   |            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let x = (1);
+LL +     let x = 1;
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:121:50
+   |
+LL |     let closure = |#[deny(unused_parens)] param: (i32)| {};
+   |                                                  ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:121:27
+   |
+LL |     let closure = |#[deny(unused_parens)] param: (i32)| {};
+   |                           ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let closure = |#[deny(unused_parens)] param: (i32)| {};
+LL +     let closure = |#[deny(unused_parens)] param: i32| {};
+   |
+
+error: unnecessary parentheses around block return value
+  --> $DIR/lint-attr-everywhere-early.rs:125:46
+   |
+LL |     let f = Match{#[deny(unused_parens)]f1: {(123)}};
+   |                                              ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:125:26
+   |
+LL |     let f = Match{#[deny(unused_parens)]f1: {(123)}};
+   |                          ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let f = Match{#[deny(unused_parens)]f1: {(123)}};
+LL +     let f = Match{#[deny(unused_parens)]f1: {123}};
+   |
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:132:13
+   |
+LL |             unsafe {}
+   |             ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:128:17
+   |
+LL |         #![deny(unsafe_code)]
+   |                 ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:133:13
+   |
+LL |             while true {}
+   |             ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:130:16
+   |
+LL |         #[deny(while_true)]
+   |                ^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:140:9
+   |
+LL |         unsafe {}
+   |         ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:139:17
+   |
+LL |         #![deny(unsafe_code)]
+   |                 ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:144:9
+   |
+LL |         unsafe {}
+   |         ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:143:16
+   |
+LL |         #[deny(unsafe_code)]
+   |                ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:149:5
+   |
+LL |     unsafe {};
+   |     ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:148:12
+   |
+LL |     #[deny(unsafe_code)]
+   |            ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:151:27
+   |
+LL |     [#[deny(unsafe_code)] unsafe {123}];
+   |                           ^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:151:13
+   |
+LL |     [#[deny(unsafe_code)] unsafe {123}];
+   |             ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:152:27
+   |
+LL |     (#[deny(unsafe_code)] unsafe {123},);
+   |                           ^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:152:13
+   |
+LL |     (#[deny(unsafe_code)] unsafe {123},);
+   |             ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:154:31
+   |
+LL |     call(#[deny(unsafe_code)] unsafe {123});
+   |                               ^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:154:17
+   |
+LL |     call(#[deny(unsafe_code)] unsafe {123});
+   |                 ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:156:38
+   |
+LL |     TupleStruct(#[deny(unsafe_code)] unsafe {123});
+   |                                      ^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:156:24
+   |
+LL |     TupleStruct(#[deny(unsafe_code)] unsafe {123});
+   |                        ^^^^^^^^^^^
+
+error: `...` range patterns are deprecated
+  --> $DIR/lint-attr-everywhere-early.rs:167:18
+   |
+LL |             f1: 0...100,
+   |                  ^^^ help: use `..=` for an inclusive range
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:166:20
+   |
+LL |             #[deny(ellipsis_inclusive_range_patterns)]
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = 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>
+
+error: aborting due to 36 previous errors
+
diff --git a/src/test/ui/lint/lint-attr-everywhere-late.rs b/src/test/ui/lint/lint-attr-everywhere-late.rs
new file mode 100644 (file)
index 0000000..1055157
--- /dev/null
@@ -0,0 +1,197 @@
+// Tests that lint levels can be set for late lints.
+#![allow(
+    non_snake_case,
+    overflowing_literals,
+    missing_docs,
+    dyn_drop,
+    enum_intrinsics_non_enums,
+    clashing_extern_declarations
+)]
+
+extern crate core;
+use core::mem::{Discriminant, discriminant};
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+pub fn missing_docs_allowed() {} // missing_docs
+fn dyn_drop_allowed(_x: Box<dyn Drop>) {} // dyn_drop
+fn verify_no_warnings() {
+    discriminant::<i32>(&123); // enum_intrinsics_non_enums
+    let x: u8 = 1000; // overflowing_literals
+    let NON_SNAKE_CASE = 1; // non_snake_case
+}
+mod clashing_extern_allowed {
+    extern "C" {
+        fn extern_allowed();
+    }
+}
+extern "C" {
+    fn extern_allowed(_: i32); // clashing_extern_declarations
+}
+
+// ################## Types
+
+#[deny(missing_docs)]
+pub type MissingDocType = i32; //~ ERROR missing documentation for a type alias
+
+// There aren't any late lints that I can find that can be easily used with types.
+// type BareFnPtr = fn(#[deny()]i32);
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(missing_docs)]
+pub struct ItemOuter; //~ ERROR missing documentation for a struct
+
+pub mod module_inner { //~ ERROR missing documentation for a module
+    #![deny(missing_docs)]
+    pub fn missing_inner() {} //~ ERROR missing documentation for a function
+}
+
+pub struct Associated;
+impl Associated {
+    #![deny(missing_docs)]
+
+    pub fn inherent_denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+impl Associated {
+    #[deny(missing_docs)]
+    pub fn inherent_fn() {} //~ ERROR missing documentation for an associated function
+
+    #[deny(missing_docs)]
+    pub const INHERENT_CONST: i32 = 1; //~ ERROR missing documentation for an associated constant
+}
+
+pub trait TraitInner { //~ ERROR missing documentation for a trait
+    #![deny(missing_docs)]
+}
+
+pub trait AssociatedTraitInner { //~ ERROR missing documentation for a trait
+    #![deny(missing_docs)]
+
+    fn denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+pub trait AssociatedTrait {
+    fn denied_from_inner(_x: Box<dyn Drop>) {} // Used below
+
+    #[deny(missing_docs)]
+    fn assoc_fn() {} //~ ERROR missing documentation for an associated function
+
+    #[deny(missing_docs)]
+    const ASSOC_CONST: u8 = 1; //~ ERROR missing documentation for an associated constant
+
+    #[deny(missing_docs)]
+    type AssocType; //~ ERROR missing documentation for an associated type
+}
+
+struct Foo;
+
+impl AssociatedTrait for Associated {
+    #![deny(dyn_drop)]
+
+    fn denied_from_inner(_x: Box<dyn Drop>) {} //~ ERROR types that do not implement `Drop`
+
+    #[deny(enum_intrinsics_non_enums)]
+    fn assoc_fn() { discriminant::<i32>(&123); } //~ ERROR the return value of
+
+    #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000; //~ ERROR literal out of range
+    type AssocType = i32;
+}
+
+
+// There aren't any late lints that can apply to a field that I can find.
+// non_snake_case doesn't work on fields
+// struct StructFields {
+//     #[deny()]f1: i32,
+// }
+// struct StructTuple(#[deny()]i32);
+
+pub enum Enum {
+    #[deny(missing_docs)]
+    Variant1, //~ ERROR missing documentation for a variant
+}
+
+mod clashing_extern {
+    extern "C" {
+        fn clashing1();
+        fn clashing2();
+    }
+}
+extern "C" {
+    #![deny(clashing_extern_declarations)]
+    fn clashing1(_: i32); //~ ERROR `clashing1` redeclared with a different signature
+}
+
+extern "C" {
+    #[deny(clashing_extern_declarations)]
+    fn clashing2(_: i32); //~ ERROR `clashing2` redeclared with a different signature
+}
+
+fn function(#[deny(non_snake_case)] PARAM: i32) {} //~ ERROR variable `PARAM` should have a snake case name
+// There aren't any late lints that can apply to generics that I can find.
+// fn generics<#[deny()]T>() {}
+
+
+// ################## Statements
+fn statements() {
+    #[deny(enum_intrinsics_non_enums)]
+    let _ = discriminant::<i32>(&123); //~ ERROR the return value of
+}
+
+
+// ################## Expressions
+fn expressions() {
+    let closure = |#[deny(non_snake_case)] PARAM: i32| {}; //~ ERROR variable `PARAM` should have a snake case name
+
+    struct Match{f1: i32}
+    // I can't find any late lints for patterns.
+    // let f = Match{#[deny()]f1: 123};
+
+    let f = Match{f1: 123};
+    match f {
+        #![deny(enum_intrinsics_non_enums)]
+        Match{f1} => {
+            discriminant::<i32>(&123); //~ ERROR the return value of
+        }
+    }
+    match f {
+        #[deny(enum_intrinsics_non_enums)]
+        Match{f1} => {
+            discriminant::<i32>(&123); //~ ERROR the return value of
+        }
+    }
+
+    // Statement Block
+    {
+        #![deny(enum_intrinsics_non_enums)]
+        discriminant::<i32>(&123); //~ ERROR the return value of
+    }
+    let block_tail = {
+        #[deny(enum_intrinsics_non_enums)]
+        discriminant::<i32>(&123); //~ ERROR the return value of
+    };
+
+    // Before expression as a statement.
+    #[deny(enum_intrinsics_non_enums)]
+    discriminant::<i32>(&123); //~ ERROR the return value of
+
+    [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)]; //~ ERROR the return value of
+    (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),); //~ ERROR the return value of
+    fn call(p: Discriminant<i32>) {}
+    call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+    struct TupleStruct(Discriminant<i32>);
+    TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+}
+
+
+// ################## Patterns
+fn patterns() {
+    // There aren't any late lints that I can find that apply to pattern fields.
+    //
+    // struct PatField{f1: i32, f2: i32};
+    // let f = PatField{f1: 1, f2: 2};
+    // let PatField{#[deny()]f1, #[deny()]..} = f;
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-attr-everywhere-late.stderr b/src/test/ui/lint/lint-attr-everywhere-late.stderr
new file mode 100644 (file)
index 0000000..9778439
--- /dev/null
@@ -0,0 +1,428 @@
+error: missing documentation for a type alias
+  --> $DIR/lint-attr-everywhere-late.rs:35:1
+   |
+LL | pub type MissingDocType = i32;
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:34:8
+   |
+LL | #[deny(missing_docs)]
+   |        ^^^^^^^^^^^^
+
+error: missing documentation for a struct
+  --> $DIR/lint-attr-everywhere-late.rs:43:1
+   |
+LL | pub struct ItemOuter;
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:42:8
+   |
+LL | #[deny(missing_docs)]
+   |        ^^^^^^^^^^^^
+
+error: missing documentation for a module
+  --> $DIR/lint-attr-everywhere-late.rs:45:1
+   |
+LL | pub mod module_inner {
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:46:13
+   |
+LL |     #![deny(missing_docs)]
+   |             ^^^^^^^^^^^^
+
+error: missing documentation for a function
+  --> $DIR/lint-attr-everywhere-late.rs:47:5
+   |
+LL |     pub fn missing_inner() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+  --> $DIR/lint-attr-everywhere-late.rs:54:5
+   |
+LL |     pub fn inherent_denied_from_inner() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:52:13
+   |
+LL |     #![deny(missing_docs)]
+   |             ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+  --> $DIR/lint-attr-everywhere-late.rs:59:5
+   |
+LL |     pub fn inherent_fn() {}
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:58:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+  --> $DIR/lint-attr-everywhere-late.rs:62:5
+   |
+LL |     pub const INHERENT_CONST: i32 = 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:61:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+  --> $DIR/lint-attr-everywhere-late.rs:65:1
+   |
+LL | pub trait TraitInner {
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:66:13
+   |
+LL |     #![deny(missing_docs)]
+   |             ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+  --> $DIR/lint-attr-everywhere-late.rs:69:1
+   |
+LL | pub trait AssociatedTraitInner {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:70:13
+   |
+LL |     #![deny(missing_docs)]
+   |             ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+  --> $DIR/lint-attr-everywhere-late.rs:72:5
+   |
+LL |     fn denied_from_inner() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+  --> $DIR/lint-attr-everywhere-late.rs:79:5
+   |
+LL |     fn assoc_fn() {}
+   |     ^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:78:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+  --> $DIR/lint-attr-everywhere-late.rs:82:5
+   |
+LL |     const ASSOC_CONST: u8 = 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:81:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for an associated type
+  --> $DIR/lint-attr-everywhere-late.rs:85:5
+   |
+LL |     type AssocType;
+   |     ^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:84:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for a variant
+  --> $DIR/lint-attr-everywhere-late.rs:112:5
+   |
+LL |     Variant1,
+   |     ^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:111:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: `clashing1` redeclared with a different signature
+  --> $DIR/lint-attr-everywhere-late.rs:123:5
+   |
+LL |         fn clashing1();
+   |         --------------- `clashing1` previously declared here
+...
+LL |     fn clashing1(_: i32);
+   |     ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:122:13
+   |
+LL |     #![deny(clashing_extern_declarations)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `unsafe extern "C" fn()`
+              found `unsafe extern "C" fn(i32)`
+
+error: `clashing2` redeclared with a different signature
+  --> $DIR/lint-attr-everywhere-late.rs:128:5
+   |
+LL |         fn clashing2();
+   |         --------------- `clashing2` previously declared here
+...
+LL |     fn clashing2(_: i32);
+   |     ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:127:12
+   |
+LL |     #[deny(clashing_extern_declarations)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `unsafe extern "C" fn()`
+              found `unsafe extern "C" fn(i32)`
+
+error: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped
+  --> $DIR/lint-attr-everywhere-late.rs:93:38
+   |
+LL |     fn denied_from_inner(_x: Box<dyn Drop>) {}
+   |                                      ^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:91:13
+   |
+LL |     #![deny(dyn_drop)]
+   |             ^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:96:21
+   |
+LL |     fn assoc_fn() { discriminant::<i32>(&123); }
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:95:12
+   |
+LL |     #[deny(enum_intrinsics_non_enums)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:96:41
+   |
+LL |     fn assoc_fn() { discriminant::<i32>(&123); }
+   |                                         ^^^^
+
+error: literal out of range for `u8`
+  --> $DIR/lint-attr-everywhere-late.rs:98:59
+   |
+LL |     #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+   |                                                           ^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:98:12
+   |
+LL |     #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+   |            ^^^^^^^^^^^^^^^^^^^^
+   = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255`
+
+error: variable `PARAM` should have a snake case name
+  --> $DIR/lint-attr-everywhere-late.rs:131:37
+   |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+   |                                     ^^^^^ help: convert the identifier to snake case: `param`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:131:20
+   |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+   |                    ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:139:13
+   |
+LL |     let _ = discriminant::<i32>(&123);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:138:12
+   |
+LL |     #[deny(enum_intrinsics_non_enums)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:139:33
+   |
+LL |     let _ = discriminant::<i32>(&123);
+   |                                 ^^^^
+
+error: variable `PARAM` should have a snake case name
+  --> $DIR/lint-attr-everywhere-late.rs:145:44
+   |
+LL |     let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+   |                                            ^^^^^ help: convert the identifier to snake case: `param`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:145:27
+   |
+LL |     let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+   |                           ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:155:13
+   |
+LL |             discriminant::<i32>(&123);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:153:17
+   |
+LL |         #![deny(enum_intrinsics_non_enums)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:155:33
+   |
+LL |             discriminant::<i32>(&123);
+   |                                 ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:161:13
+   |
+LL |             discriminant::<i32>(&123);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:159:16
+   |
+LL |         #[deny(enum_intrinsics_non_enums)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:161:33
+   |
+LL |             discriminant::<i32>(&123);
+   |                                 ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:168:9
+   |
+LL |         discriminant::<i32>(&123);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:167:17
+   |
+LL |         #![deny(enum_intrinsics_non_enums)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:168:29
+   |
+LL |         discriminant::<i32>(&123);
+   |                             ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:172:9
+   |
+LL |         discriminant::<i32>(&123);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:171:16
+   |
+LL |         #[deny(enum_intrinsics_non_enums)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:172:29
+   |
+LL |         discriminant::<i32>(&123);
+   |                             ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:177:5
+   |
+LL |     discriminant::<i32>(&123);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:176:12
+   |
+LL |     #[deny(enum_intrinsics_non_enums)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:177:25
+   |
+LL |     discriminant::<i32>(&123);
+   |                         ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:179:41
+   |
+LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:179:13
+   |
+LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:179:61
+   |
+LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+   |                                                             ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:180:41
+   |
+LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:180:13
+   |
+LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:180:61
+   |
+LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+   |                                                             ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:182:45
+   |
+LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:182:17
+   |
+LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:182:65
+   |
+LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                                                                 ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:184:52
+   |
+LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:184:24
+   |
+LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:184:72
+   |
+LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                                                                        ^^^^
+
+error: aborting due to 31 previous errors
+
index 1c4abb9491e00740c22324828d5de81fd442f9ff..51f868706b69b76402f5be9d07c6a27624409706 100644 (file)
@@ -122,4 +122,10 @@ fn main() {
         Some(res) => res,
         None => 0,
     };
+
+    struct PatternField {
+        foo: i32,
+    }
+    let s = PatternField { #[must_use]  foo: 123 }; //~ ERROR `#[must_use]` has no effect
+    let PatternField { #[must_use] foo } = s; //~ ERROR `#[must_use]` has no effect
 }
index 317d81c591d55cd5cdb0cec79b306eb14ae84376..dd112c23e5d9eba0b27a8b7efb93ebd7e2a3b1be 100644 (file)
@@ -105,6 +105,18 @@ error: `#[must_use]` has no effect when applied to an match arm
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
+error: `#[must_use]` has no effect when applied to a struct field
+  --> $DIR/unused_attributes-must_use.rs:129:28
+   |
+LL |     let s = PatternField { #[must_use]  foo: 123 };
+   |                            ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a pattern field
+  --> $DIR/unused_attributes-must_use.rs:130:24
+   |
+LL |     let PatternField { #[must_use] foo } = s;
+   |                        ^^^^^^^^^^^
+
 error: `#[must_use]` has no effect when applied to an associated const
   --> $DIR/unused_attributes-must_use.rs:68:5
    |
@@ -171,5 +183,5 @@ error: unused return value of `Use::get_four` that must be used
 LL |     ().get_four();
    |     ^^^^^^^^^^^^^^
 
-error: aborting due to 26 previous errors
+error: aborting due to 28 previous errors
 
index 690fe8fa7af1005d0e0e7eafd82ff8b405139ce1..e9b49c89bf162d519745cd1bbeadc824ac449e8d 100644 (file)
@@ -8,7 +8,7 @@ note: associated function defined here
   --> $DIR/method-call-err-msg.rs:5:8
    |
 LL |     fn zero(self) -> Foo { self }
-   |        ^^^^ ----
+   |        ^^^^
 help: remove the extra argument
    |
 LL |     x.zero()
@@ -24,7 +24,7 @@ note: associated function defined here
   --> $DIR/method-call-err-msg.rs:6:8
    |
 LL |     fn one(self, _: isize) -> Foo { self }
-   |        ^^^ ----  --------
+   |        ^^^       --------
 help: provide the argument
    |
 LL |      .one(/* isize */)
@@ -40,7 +40,7 @@ note: associated function defined here
   --> $DIR/method-call-err-msg.rs:7:8
    |
 LL |     fn two(self, _: isize, _: isize) -> Foo { self }
-   |        ^^^ ----  --------  --------
+   |        ^^^       --------  --------
 help: provide the argument
    |
 LL |      .two(0, /* isize */);
@@ -80,7 +80,7 @@ note: associated function defined here
   --> $DIR/method-call-err-msg.rs:8:8
    |
 LL |     fn three<T>(self, _: T, _: T, _: T) -> Foo { self }
-   |        ^^^^^    ----  ----  ----  ----
+   |        ^^^^^          ----  ----  ----
 help: provide the arguments
    |
 LL |     y.three::<usize>(/* usize */, /* usize */, /* usize */);
diff --git a/src/test/ui/parser/issue-100197-mut-let.fixed b/src/test/ui/parser/issue-100197-mut-let.fixed
new file mode 100644 (file)
index 0000000..5a89562
--- /dev/null
@@ -0,0 +1,6 @@
+// run-rustfix
+
+fn main() {
+    let mut _x = 123;
+    //~^ ERROR invalid variable declaration
+}
diff --git a/src/test/ui/parser/issue-100197-mut-let.rs b/src/test/ui/parser/issue-100197-mut-let.rs
new file mode 100644 (file)
index 0000000..7110381
--- /dev/null
@@ -0,0 +1,6 @@
+// run-rustfix
+
+fn main() {
+    mut let _x = 123;
+    //~^ ERROR invalid variable declaration
+}
diff --git a/src/test/ui/parser/issue-100197-mut-let.stderr b/src/test/ui/parser/issue-100197-mut-let.stderr
new file mode 100644 (file)
index 0000000..86658e4
--- /dev/null
@@ -0,0 +1,8 @@
+error: invalid variable declaration
+  --> $DIR/issue-100197-mut-let.rs:4:5
+   |
+LL |     mut let _x = 123;
+   |     ^^^^^^^ help: switch the order of `mut` and `let`: `let mut`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.fixed b/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.fixed
new file mode 100644 (file)
index 0000000..64ab6f6
--- /dev/null
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn main() {
+    const _FOO: i32 = 123;
+    //~^ ERROR const` and `let` are mutually exclusive
+    const _BAR: i32 = 123;
+    //~^ ERROR `const` and `let` are mutually exclusive
+}
diff --git a/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.rs b/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.rs
new file mode 100644 (file)
index 0000000..5052097
--- /dev/null
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn main() {
+    const let _FOO: i32 = 123;
+    //~^ ERROR const` and `let` are mutually exclusive
+    let const _BAR: i32 = 123;
+    //~^ ERROR `const` and `let` are mutually exclusive
+}
diff --git a/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.stderr b/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.stderr
new file mode 100644 (file)
index 0000000..72377fc
--- /dev/null
@@ -0,0 +1,14 @@
+error: `const` and `let` are mutually exclusive
+  --> $DIR/issue-99910-const-let-mutually-exclusive.rs:4:5
+   |
+LL |     const let _FOO: i32 = 123;
+   |     ^^^^^^^^^ help: remove `let`: `const`
+
+error: `const` and `let` are mutually exclusive
+  --> $DIR/issue-99910-const-let-mutually-exclusive.rs:6:5
+   |
+LL |     let const _BAR: i32 = 123;
+   |     ^^^^^^^^^ help: remove `let`: `const`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/struct-filed-with-attr.fixed b/src/test/ui/parser/struct-filed-with-attr.fixed
new file mode 100644 (file)
index 0000000..a799ec8
--- /dev/null
@@ -0,0 +1,18 @@
+// Issue: 100461, Try to give a helpful diagnostic even when the next struct field has an attribute.
+// run-rustfix
+
+struct Feelings {
+    owo: bool,
+    //~^ ERROR expected `,`, or `}`, found `#`
+    #[allow(unused)]
+    uwu: bool,
+}
+
+impl Feelings {
+    #[allow(unused)]
+    fn hmm(&self) -> bool {
+        self.owo
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/parser/struct-filed-with-attr.rs b/src/test/ui/parser/struct-filed-with-attr.rs
new file mode 100644 (file)
index 0000000..bfc78e1
--- /dev/null
@@ -0,0 +1,18 @@
+// Issue: 100461, Try to give a helpful diagnostic even when the next struct field has an attribute.
+// run-rustfix
+
+struct Feelings {
+    owo: bool
+    //~^ ERROR expected `,`, or `}`, found `#`
+    #[allow(unused)]
+    uwu: bool,
+}
+
+impl Feelings {
+    #[allow(unused)]
+    fn hmm(&self) -> bool {
+        self.owo
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/parser/struct-filed-with-attr.stderr b/src/test/ui/parser/struct-filed-with-attr.stderr
new file mode 100644 (file)
index 0000000..c2cd7e8
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected `,`, or `}`, found `#`
+  --> $DIR/struct-filed-with-attr.rs:5:14
+   |
+LL |     owo: bool
+   |              ^ help: try adding a comma: `,`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/suggest-const-for-global-var.rs b/src/test/ui/parser/suggest-const-for-global-var.rs
new file mode 100644 (file)
index 0000000..d6216cb
--- /dev/null
@@ -0,0 +1,6 @@
+let X: i32 = 12;
+//~^ ERROR expected item, found keyword `let`
+
+fn main() {
+    println!("{}", X);
+}
diff --git a/src/test/ui/parser/suggest-const-for-global-var.stderr b/src/test/ui/parser/suggest-const-for-global-var.stderr
new file mode 100644 (file)
index 0000000..94e44ec
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected item, found keyword `let`
+  --> $DIR/suggest-const-for-global-var.rs:1:1
+   |
+LL | let X: i32 = 12;
+   | ^^^ consider using `const` or `static` instead of `let` for global variables
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed b/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed
new file mode 100644 (file)
index 0000000..6370473
--- /dev/null
@@ -0,0 +1,7 @@
+// run-rustfix
+
+trait Foo {
+    fn bar() {} //~ ERROR non-item in item list
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs b/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs
new file mode 100644 (file)
index 0000000..4650b05
--- /dev/null
@@ -0,0 +1,7 @@
+// run-rustfix
+
+trait Foo {
+    fn bar() {}; //~ ERROR non-item in item list
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr b/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr
new file mode 100644 (file)
index 0000000..396e0c1
--- /dev/null
@@ -0,0 +1,15 @@
+error: non-item in item list
+  --> $DIR/suggest-removing-semicolon-after-impl-trait-items.rs:4:16
+   |
+LL | trait Foo {
+   |           - item list starts here
+LL |     fn bar() {};
+   |                ^
+   |                |
+   |                non-item starts here
+   |                help: consider removing this semicolon
+LL | }
+   | - item list ends here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/resolve/issue-100365.rs b/src/test/ui/resolve/issue-100365.rs
new file mode 100644 (file)
index 0000000..1d88350
--- /dev/null
@@ -0,0 +1,50 @@
+fn main() {
+    let addr = Into::<std::net::IpAddr>.into([127, 0, 0, 1]);
+    //~^ ERROR expected value, found trait `Into`
+    //~| HELP use the path separator
+
+    let _ = Into.into(());
+    //~^ ERROR expected value, found trait `Into`
+    //~| HELP use the path separator
+
+    let _ = Into::<()>.into;
+    //~^ ERROR expected value, found trait `Into`
+    //~| HELP use the path separator
+}
+
+macro_rules! Trait {
+    () => {
+        ::std::iter::Iterator
+        //~^ ERROR expected value, found trait `std::iter::Iterator`
+        //~| ERROR expected value, found trait `std::iter::Iterator`
+    };
+}
+
+macro_rules! create {
+    () => {
+        Into::<String>.into("")
+        //~^ ERROR expected value, found trait `Into`
+        //~| HELP use the path separator
+    };
+}
+
+fn interaction_with_macros() {
+    //
+    // Note that if the receiver is a macro call, we do not want to suggest to replace
+    // `.` with `::` as that would be a syntax error.
+    // Since the receiver is a trait and not a type, we cannot suggest to surround
+    // it with angle brackets. It would be interpreted as a trait object type void of
+    // `dyn` which is most likely not what the user intended to write.
+    // `<_ as Trait!()>::` is also not an option as it's equally syntactically invalid.
+    //
+
+    Trait!().map(std::convert::identity); // no `help` here!
+
+    Trait!().map; // no `help` here!
+
+    //
+    // Ensure that the suggestion is shown for expressions inside of macro definitions.
+    //
+
+    let _ = create!();
+}
diff --git a/src/test/ui/resolve/issue-100365.stderr b/src/test/ui/resolve/issue-100365.stderr
new file mode 100644 (file)
index 0000000..372d772
--- /dev/null
@@ -0,0 +1,54 @@
+error[E0423]: expected value, found trait `Into`
+  --> $DIR/issue-100365.rs:2:16
+   |
+LL |     let addr = Into::<std::net::IpAddr>.into([127, 0, 0, 1]);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found trait `Into`
+  --> $DIR/issue-100365.rs:6:13
+   |
+LL |     let _ = Into.into(());
+   |             ^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found trait `Into`
+  --> $DIR/issue-100365.rs:10:13
+   |
+LL |     let _ = Into::<()>.into;
+   |             ^^^^^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found trait `std::iter::Iterator`
+  --> $DIR/issue-100365.rs:17:9
+   |
+LL |         ::std::iter::Iterator
+   |         ^^^^^^^^^^^^^^^^^^^^^ not a value
+...
+LL |     Trait!().map(std::convert::identity); // no `help` here!
+   |     -------- in this macro invocation
+   |
+   = note: this error originates in the macro `Trait` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found trait `std::iter::Iterator`
+  --> $DIR/issue-100365.rs:17:9
+   |
+LL |         ::std::iter::Iterator
+   |         ^^^^^^^^^^^^^^^^^^^^^ not a value
+...
+LL |     Trait!().map; // no `help` here!
+   |     -------- in this macro invocation
+   |
+   = note: this error originates in the macro `Trait` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found trait `Into`
+  --> $DIR/issue-100365.rs:25:9
+   |
+LL |         Into::<String>.into("")
+   |         ^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
+...
+LL |     let _ = create!();
+   |             --------- in this macro invocation
+   |
+   = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0423`.
index 1d8f442221df9ef669bbaf4fced9801e54516812..31a76261408ef7021eecf5beac57e5dd24b35255 100644 (file)
@@ -1,3 +1,60 @@
 fn main() {
-    let _ = String.new(); //~ ERROR expected value, found struct `String`
+    let _ = String.new();
+    //~^ ERROR expected value, found struct `String`
+    //~| HELP use the path separator
+
+    let _ = String.default;
+    //~^ ERROR expected value, found struct `String`
+    //~| HELP use the path separator
+
+    let _ = Vec::<()>.with_capacity(1);
+    //~^ ERROR expected value, found struct `Vec`
+    //~| HELP use the path separator
+}
+
+macro_rules! Type {
+    () => {
+        ::std::cell::Cell
+        //~^ ERROR expected value, found struct `std::cell::Cell`
+        //~| ERROR expected value, found struct `std::cell::Cell`
+        //~| ERROR expected value, found struct `std::cell::Cell`
+    };
+}
+
+macro_rules! create {
+    (type method) => {
+        Vec.new()
+        //~^ ERROR expected value, found struct `Vec`
+        //~| HELP use the path separator
+    };
+    (type field) => {
+        Vec.new
+        //~^ ERROR expected value, found struct `Vec`
+        //~| HELP use the path separator
+    };
+    (macro method) => {
+        Type!().new(0)
+        //~^ HELP use the path separator
+    };
+}
+
+fn interaction_with_macros() {
+    //
+    // Verify that we do not only suggest to replace `.` with `::` if the receiver is a
+    // macro call but that we also correctly suggest to surround it with angle brackets.
+    //
+
+    Type!().get();
+    //~^ HELP use the path separator
+
+    Type! {}.get;
+    //~^ HELP use the path separator
+
+    //
+    // Ensure that the suggestion is shown for expressions inside of macro definitions.
+    //
+
+    let _ = create!(type method);
+    let _ = create!(type field);
+    let _ = create!(macro method);
 }
index e076419f68d47b9449960cdc01f2da6e7460324b..6962aa161e92a5e9ee096220163fa460d91ea1b7 100644 (file)
@@ -2,10 +2,87 @@ error[E0423]: expected value, found struct `String`
   --> $DIR/issue-22692.rs:2:13
    |
 LL |     let _ = String.new();
-   |             ^^^^^^----
-   |             |
-   |             help: use the path separator to refer to an item: `String::new`
+   |             ^^^^^^- help: use the path separator to refer to an item: `::`
 
-error: aborting due to previous error
+error[E0423]: expected value, found struct `String`
+  --> $DIR/issue-22692.rs:6:13
+   |
+LL |     let _ = String.default;
+   |             ^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found struct `Vec`
+  --> $DIR/issue-22692.rs:10:13
+   |
+LL |     let _ = Vec::<()>.with_capacity(1);
+   |             ^^^^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+  --> $DIR/issue-22692.rs:17:9
+   |
+LL |         ::std::cell::Cell
+   |         ^^^^^^^^^^^^^^^^^
+...
+LL |     Type!().get();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL |     <Type!()>::get();
+   |     ~~~~~~~~~~~
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+  --> $DIR/issue-22692.rs:17:9
+   |
+LL |         ::std::cell::Cell
+   |         ^^^^^^^^^^^^^^^^^
+...
+LL |     Type! {}.get;
+   |     -------- in this macro invocation
+   |
+   = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL |     <Type! {}>::get;
+   |     ~~~~~~~~~~~~
+
+error[E0423]: expected value, found struct `Vec`
+  --> $DIR/issue-22692.rs:26:9
+   |
+LL |         Vec.new()
+   |         ^^^- help: use the path separator to refer to an item: `::`
+...
+LL |     let _ = create!(type method);
+   |             -------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found struct `Vec`
+  --> $DIR/issue-22692.rs:31:9
+   |
+LL |         Vec.new
+   |         ^^^- help: use the path separator to refer to an item: `::`
+...
+LL |     let _ = create!(type field);
+   |             ------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+  --> $DIR/issue-22692.rs:17:9
+   |
+LL |         ::std::cell::Cell
+   |         ^^^^^^^^^^^^^^^^^
+...
+LL |     let _ = create!(macro method);
+   |             --------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL |         <Type!()>::new(0)
+   |         ~~~~~~~~~~~
+
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0423`.
index 957045ca74bb21049501376fe784bcb04a2901ab..4764cf2db20e86ccc94cba2f5baa037797851fc0 100644 (file)
@@ -2,17 +2,13 @@ error[E0423]: expected value, found struct `SomeTupleStruct`
   --> $DIR/suggest-path-for-tuple-struct.rs:22:13
    |
 LL |     let _ = SomeTupleStruct.new();
-   |             ^^^^^^^^^^^^^^^----
-   |             |
-   |             help: use the path separator to refer to an item: `SomeTupleStruct::new`
+   |             ^^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
 
 error[E0423]: expected value, found struct `SomeRegularStruct`
   --> $DIR/suggest-path-for-tuple-struct.rs:24:13
    |
 LL |     let _ = SomeRegularStruct.new();
-   |             ^^^^^^^^^^^^^^^^^----
-   |             |
-   |             help: use the path separator to refer to an item: `SomeRegularStruct::new`
+   |             ^^^^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
 
 error: aborting due to 2 previous errors
 
index 204a272402dd7a208f10cc8387e1420584ece99b..d5d6b13d62c284aaa400650e2e594fd233d8d058 100644 (file)
@@ -16,44 +16,96 @@ pub fn g() -> i32 { 4 }
 fn h1() -> i32 {
     a.I
     //~^ ERROR expected value, found module `a`
+    //~| HELP use the path separator
 }
 
 fn h2() -> i32 {
     a.g()
     //~^ ERROR expected value, found module `a`
+    //~| HELP use the path separator
 }
 
 fn h3() -> i32 {
     a.b.J
     //~^ ERROR expected value, found module `a`
+    //~| HELP use the path separator
 }
 
 fn h4() -> i32 {
     a::b.J
     //~^ ERROR expected value, found module `a::b`
+    //~| HELP a constant with a similar name exists
+    //~| HELP use the path separator
 }
 
 fn h5() {
     a.b.f();
     //~^ ERROR expected value, found module `a`
+    //~| HELP use the path separator
     let v = Vec::new();
     v.push(a::b);
     //~^ ERROR expected value, found module `a::b`
+    //~| HELP a constant with a similar name exists
 }
 
 fn h6() -> i32 {
     a::b.f()
     //~^ ERROR expected value, found module `a::b`
+    //~| HELP a constant with a similar name exists
+    //~| HELP use the path separator
 }
 
 fn h7() {
     a::b
     //~^ ERROR expected value, found module `a::b`
+    //~| HELP a constant with a similar name exists
 }
 
 fn h8() -> i32 {
     a::b()
     //~^ ERROR expected function, found module `a::b`
+    //~| HELP a constant with a similar name exists
+}
+
+macro_rules! module {
+    () => {
+        a
+        //~^ ERROR expected value, found module `a`
+        //~| ERROR expected value, found module `a`
+    };
+}
+
+macro_rules! create {
+    (method) => {
+        a.f()
+        //~^ ERROR expected value, found module `a`
+        //~| HELP use the path separator
+    };
+    (field) => {
+        a.f
+        //~^ ERROR expected value, found module `a`
+        //~| HELP use the path separator
+    };
+}
+
+fn h9() {
+    //
+    // Note that if the receiver is a macro call, we do not want to suggest to replace
+    // `.` with `::` as that would be a syntax error.
+    // Since the receiver is a module and not a type, we cannot suggest to surround
+    // it with angle brackets.
+    //
+
+    module!().g::<()>(); // no `help` here!
+
+    module!().g; // no `help` here!
+
+    //
+    // Ensure that the suggestion is shown for expressions inside of macro definitions.
+    //
+
+    let _ = create!(method);
+    let _ = create!(field);
 }
 
 fn main() {}
index 54b242123eb8f1bd82f5e984a319f7a7a020070a..a4ce0deeb70f59b5aee008a41222937340a549b0 100644 (file)
@@ -2,28 +2,22 @@ error[E0423]: expected value, found module `a`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:17:5
    |
 LL |     a.I
-   |     ^--
-   |     |
-   |     help: use the path separator to refer to an item: `a::I`
+   |     ^- help: use the path separator to refer to an item: `::`
 
 error[E0423]: expected value, found module `a`
-  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:22:5
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:23:5
    |
 LL |     a.g()
-   |     ^--
-   |     |
-   |     help: use the path separator to refer to an item: `a::g`
+   |     ^- help: use the path separator to refer to an item: `::`
 
 error[E0423]: expected value, found module `a`
-  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:29:5
    |
 LL |     a.b.J
-   |     ^--
-   |     |
-   |     help: use the path separator to refer to an item: `a::b`
+   |     ^- help: use the path separator to refer to an item: `::`
 
 error[E0423]: expected value, found module `a::b`
-  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:32:5
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:35:5
    |
 LL |     pub const I: i32 = 1;
    |     --------------------- similarly named constant `I` defined here
@@ -34,22 +28,20 @@ LL |     a::b.J
 help: use the path separator to refer to an item
    |
 LL |     a::b::J
-   |
+   |         ~~
 help: a constant with a similar name exists
    |
 LL |     a::I.J
    |        ~
 
 error[E0423]: expected value, found module `a`
-  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:37:5
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:42:5
    |
 LL |     a.b.f();
-   |     ^--
-   |     |
-   |     help: use the path separator to refer to an item: `a::b`
+   |     ^- help: use the path separator to refer to an item: `::`
 
 error[E0423]: expected value, found module `a::b`
-  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:40:12
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:46:12
    |
 LL |     pub const I: i32 = 1;
    |     --------------------- similarly named constant `I` defined here
@@ -60,7 +52,7 @@ LL |     v.push(a::b);
    |               help: a constant with a similar name exists: `I`
 
 error[E0423]: expected value, found module `a::b`
-  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:52:5
    |
 LL |     pub const I: i32 = 1;
    |     --------------------- similarly named constant `I` defined here
@@ -71,14 +63,14 @@ LL |     a::b.f()
 help: use the path separator to refer to an item
    |
 LL |     a::b::f()
-   |     ~~~~~~~
+   |         ~~
 help: a constant with a similar name exists
    |
 LL |     a::I.f()
    |        ~
 
 error[E0423]: expected value, found module `a::b`
-  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:50:5
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:59:5
    |
 LL |     pub const I: i32 = 1;
    |     --------------------- similarly named constant `I` defined here
@@ -89,7 +81,7 @@ LL |     a::b
    |        help: a constant with a similar name exists: `I`
 
 error[E0423]: expected function, found module `a::b`
-  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:55:5
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:65:5
    |
 LL |     pub const I: i32 = 1;
    |     --------------------- similarly named constant `I` defined here
@@ -99,6 +91,50 @@ LL |     a::b()
    |        |
    |        help: a constant with a similar name exists: `I`
 
-error: aborting due to 9 previous errors
+error[E0423]: expected value, found module `a`
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9
+   |
+LL |         a
+   |         ^ not a value
+...
+LL |     module!().g::<()>(); // no `help` here!
+   |     --------- in this macro invocation
+   |
+   = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found module `a`
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9
+   |
+LL |         a
+   |         ^ not a value
+...
+LL |     module!().g; // no `help` here!
+   |     --------- in this macro invocation
+   |
+   = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found module `a`
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:80:9
+   |
+LL |         a.f()
+   |         ^- help: use the path separator to refer to an item: `::`
+...
+LL |     let _ = create!(method);
+   |             --------------- in this macro invocation
+   |
+   = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found module `a`
+  --> $DIR/suggest-path-instead-of-mod-dot-item.rs:85:9
+   |
+LL |         a.f
+   |         ^- help: use the path separator to refer to an item: `::`
+...
+LL |     let _ = create!(field);
+   |             -------------- in this macro invocation
+   |
+   = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 13 previous errors
 
 For more information about this error, try `rustc --explain E0423`.
index b53f19a5b01aa6d2e2024990ef35a3b37b3d9f4b..83f79679c6e67f7b16d38f9bfce6f5ae5a6637e3 100644 (file)
@@ -6,7 +6,7 @@
 // run-fail
 // error-pattern: MemorySanitizer: use-of-uninitialized-value
 // error-pattern: Uninitialized value was created by an allocation
-// error-pattern: in the stack frame of function 'main'
+// error-pattern: in the stack frame
 //
 // This test case intentionally limits the usage of the std,
 // since it will be linked with an uninstrumented version of it.
index e676d7372e89133121c2128a816623b963703b49..28a911d0c5bfa2f45264f36f69c77948843a4485 100644 (file)
@@ -78,7 +78,7 @@ note: function defined here
   --> $DIR/issue-34264.rs:3:4
    |
 LL | fn bar(x, y: usize) {}
-   |    ^^^ -  --------
+   |    ^^^    --------
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/issue-34264.rs:10:5
index e68260e4a09407da1353a7f4f58d03c7b4e8fd98..d2afd277ecf79edd74633d9f74da968c2e2e4816 100644 (file)
@@ -72,7 +72,7 @@ note: associated function defined here
   --> $DIR/missing-unit-argument.rs:6:8
    |
 LL |     fn baz(self, (): ()) { }
-   |        ^^^ ----  ------
+   |        ^^^       ------
 help: provide the argument
    |
 LL |     S.baz(());
@@ -88,7 +88,7 @@ note: associated function defined here
   --> $DIR/missing-unit-argument.rs:7:8
    |
 LL |     fn generic<T>(self, _: T) { }
-   |        ^^^^^^^    ----  ----
+   |        ^^^^^^^          ----
 help: provide the argument
    |
 LL |     S.generic::<()>(());
diff --git a/src/test/ui/stability-attribute/auxiliary/ctor-stability.rs b/src/test/ui/stability-attribute/auxiliary/ctor-stability.rs
new file mode 100644 (file)
index 0000000..74c6023
--- /dev/null
@@ -0,0 +1,8 @@
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![stable(feature = "none", since = "1.0")]
+
+#[stable(feature = "none", since = "1.0")]
+pub enum Foo {
+    A,
+}
diff --git a/src/test/ui/stability-attribute/ctor-stability.rs b/src/test/ui/stability-attribute/ctor-stability.rs
new file mode 100644 (file)
index 0000000..fcab0cb
--- /dev/null
@@ -0,0 +1,8 @@
+// aux-build:ctor-stability.rs
+// check-pass
+
+extern crate ctor_stability;
+
+fn main() {
+    let _ = ctor_stability::Foo::A;
+}
index 805c75f464cd558200b0ec23d388fddd8cbd890a..4c952669cfafda9f0aae592cf2350f1178f3af00 100644 (file)
@@ -2,10 +2,13 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:6:34
    |
 LL |     let _: Option<(i32, bool)> = Some(1, 2);
-   |                                  ^^^^ -  - argument of type `{integer}` unexpected
-   |                                       |
-   |                                       expected tuple, found integer
+   |                                  ^^^^    - argument of type `{integer}` unexpected
    |
+note: expected tuple, found integer
+  --> $DIR/args-instead-of-tuple-errors.rs:6:39
+   |
+LL |     let _: Option<(i32, bool)> = Some(1, 2);
+   |                                       ^
    = note: expected tuple `(i32, bool)`
                found type `{integer}`
 note: tuple variant defined here
@@ -22,10 +25,13 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:8:5
    |
 LL |     int_bool(1, 2);
-   |     ^^^^^^^^ -  - argument of type `{integer}` unexpected
-   |              |
-   |              expected tuple, found integer
+   |     ^^^^^^^^    - argument of type `{integer}` unexpected
    |
+note: expected tuple, found integer
+  --> $DIR/args-instead-of-tuple-errors.rs:8:14
+   |
+LL |     int_bool(1, 2);
+   |              ^
    = note: expected tuple `(i32, bool)`
                found type `{integer}`
 note: function defined here
index 5e746ecb2f28fca8c2bf9e817eb3700dbaa34253..78e5634b2de2a46bfd612a98980a7d5bd2b64222 100644 (file)
@@ -2,9 +2,7 @@ error[E0423]: expected value, found struct `Mod::Foo`
   --> $DIR/assoc-const-as-field.rs:11:9
    |
 LL |     foo(Mod::Foo.Bar);
-   |         ^^^^^^^^----
-   |         |
-   |         help: use the path separator to refer to an item: `Mod::Foo::Bar`
+   |         ^^^^^^^^- help: use the path separator to refer to an item: `::`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/dont-try-removing-the-field.rs b/src/test/ui/suggestions/dont-try-removing-the-field.rs
new file mode 100644 (file)
index 0000000..948aa2b
--- /dev/null
@@ -0,0 +1,17 @@
+// run-pass
+
+#![allow(dead_code)]
+
+struct Foo {
+    foo: i32,
+    bar: i32,
+    baz: (),
+}
+
+fn use_foo(x: Foo) -> (i32, i32) {
+    let Foo { foo, bar, baz } = x; //~ WARNING unused variable: `baz`
+                                   //~| help: try ignoring the field
+    return (foo, bar);
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/dont-try-removing-the-field.stderr b/src/test/ui/suggestions/dont-try-removing-the-field.stderr
new file mode 100644 (file)
index 0000000..263171a
--- /dev/null
@@ -0,0 +1,10 @@
+warning: unused variable: `baz`
+  --> $DIR/dont-try-removing-the-field.rs:12:25
+   |
+LL |     let Foo { foo, bar, baz } = x;
+   |                         ^^^ help: try ignoring the field: `baz: _`
+   |
+   = note: `#[warn(unused_variables)]` on by default
+
+warning: 1 warning emitted
+
index 84cbc93571a710f4b8cbafe39bf245fb647a9dd6..17de49fbd841de4cb9aef08178564bd414095208 100644 (file)
@@ -10,14 +10,8 @@ LL | #[hello]
 note: function defined here
   --> $DIR/suggest-ref-macro.rs:8:1
    |
-LL |   #[hello]
-   |  _-^^^^^^^
-LL | | fn abc() {}
-LL | |
-LL | | fn x(_: &mut i32) {}
-LL | |
-LL | | macro_rules! bla {
-   | |_____________-
+LL | #[hello]
+   | ^^^^^^^^
    = note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0308]: mismatched types
diff --git a/src/test/ui/suggestions/try-removing-the-field.rs b/src/test/ui/suggestions/try-removing-the-field.rs
new file mode 100644 (file)
index 0000000..9d0573c
--- /dev/null
@@ -0,0 +1,17 @@
+// run-pass
+
+#![allow(dead_code)]
+
+struct Foo {
+    foo: i32,
+    bar: (),
+    baz: (),
+}
+
+fn use_foo(x: Foo) -> i32 {
+    let Foo { foo, bar, .. } = x; //~ WARNING unused variable: `bar`
+                                  //~| help: try removing the field
+    return foo;
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/try-removing-the-field.stderr b/src/test/ui/suggestions/try-removing-the-field.stderr
new file mode 100644 (file)
index 0000000..448a2c3
--- /dev/null
@@ -0,0 +1,12 @@
+warning: unused variable: `bar`
+  --> $DIR/try-removing-the-field.rs:12:20
+   |
+LL |     let Foo { foo, bar, .. } = x;
+   |                    ^^^-
+   |                    |
+   |                    help: try removing the field
+   |
+   = note: `#[warn(unused_variables)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/traits/alias/generic-default-in-dyn.rs b/src/test/ui/traits/alias/generic-default-in-dyn.rs
new file mode 100644 (file)
index 0000000..d44e1c2
--- /dev/null
@@ -0,0 +1,10 @@
+trait SendEqAlias<T> = PartialEq;
+//~^ ERROR trait aliases are experimental
+
+struct Foo<T>(dyn SendEqAlias<T>);
+//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393]
+
+struct Bar<T>(dyn SendEqAlias<T>, T);
+//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393]
+
+fn main() {}
diff --git a/src/test/ui/traits/alias/generic-default-in-dyn.stderr b/src/test/ui/traits/alias/generic-default-in-dyn.stderr
new file mode 100644 (file)
index 0000000..76a068e
--- /dev/null
@@ -0,0 +1,39 @@
+error[E0658]: trait aliases are experimental
+  --> $DIR/generic-default-in-dyn.rs:1:1
+   |
+LL | trait SendEqAlias<T> = PartialEq;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #41517 <https://github.com/rust-lang/rust/issues/41517> for more information
+   = help: add `#![feature(trait_alias)]` to the crate attributes to enable
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+  --> $DIR/generic-default-in-dyn.rs:4:19
+   |
+LL | struct Foo<T>(dyn SendEqAlias<T>);
+   |                   ^^^^^^^^^^^^^^ missing reference to `Rhs`
+   |
+  ::: $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL | pub trait PartialEq<Rhs: ?Sized = Self> {
+   | --------------------------------------- type parameter `Rhs` must be specified for this
+   |
+   = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+  --> $DIR/generic-default-in-dyn.rs:7:19
+   |
+LL | struct Bar<T>(dyn SendEqAlias<T>, T);
+   |                   ^^^^^^^^^^^^^^ missing reference to `Rhs`
+   |
+  ::: $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL | pub trait PartialEq<Rhs: ?Sized = Self> {
+   | --------------------------------------- type parameter `Rhs` must be specified for this
+   |
+   = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0393, E0658.
+For more information about an error, try `rustc --explain E0393`.
diff --git a/src/test/ui/traits/alias/self-in-generics.rs b/src/test/ui/traits/alias/self-in-generics.rs
new file mode 100644 (file)
index 0000000..6b99431
--- /dev/null
@@ -0,0 +1,8 @@
+#![feature(trait_alias)]
+
+pub trait SelfInput = Fn(&mut Self);
+
+pub fn f(_f: &dyn SelfInput) {}
+//~^ ERROR the trait alias `SelfInput` cannot be made into an object [E0038]
+
+fn main() {}
diff --git a/src/test/ui/traits/alias/self-in-generics.stderr b/src/test/ui/traits/alias/self-in-generics.stderr
new file mode 100644 (file)
index 0000000..a105687
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0038]: the trait alias `SelfInput` cannot be made into an object
+  --> $DIR/self-in-generics.rs:5:19
+   |
+LL | pub fn f(_f: &dyn SelfInput) {}
+   |                   ^^^^^^^^^
+   |
+   = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
index 4251c1a1ed6cd9d3572ec30e7b2f99d39c812c18..00fdb37534613cb828a21a770606928fc317c043 100644 (file)
@@ -1,8 +1,10 @@
 error[E0271]: type mismatch resolving `<i32 as Is>::T == i64`
-  --> $DIR/check-trait-object-bounds-5.rs:23:5
+  --> $DIR/check-trait-object-bounds-5.rs:23:12
    |
 LL |     is_obj(x)
-   |     ^^^^^^ type mismatch resolving `<i32 as Is>::T == i64`
+   |     ------ ^ type mismatch resolving `<i32 as Is>::T == i64`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: expected this to be `i64`
   --> $DIR/check-trait-object-bounds-5.rs:9:14
index 5b23a513eea9b96f77d6012a13f7bd7a4bc9464f..9b0975e5ed3c3532e38d2507ccbb1dad0cfb143a 100644 (file)
@@ -1,8 +1,10 @@
 error[E0271]: type mismatch resolving `<i32 as Is>::T == i64`
-  --> $DIR/check-trait-object-bounds-6.rs:20:5
+  --> $DIR/check-trait-object-bounds-6.rs:20:12
    |
 LL |     is_obj(x)
-   |     ^^^^^^ type mismatch resolving `<i32 as Is>::T == i64`
+   |     ------ ^ type mismatch resolving `<i32 as Is>::T == i64`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: expected this to be `i64`
   --> $DIR/check-trait-object-bounds-6.rs:9:14
index 8b6e610067be1f1d23dc44dbcb23ea2c1fc6d8f9..d58f1e2d9e59c47a03c75a359f4ae7c8098d8e1f 100644 (file)
@@ -10,7 +10,7 @@ note: function defined here
   --> $DIR/multidispatch-bad.rs:13:4
    |
 LL | fn test<T,U>(_: T, _: U)
-   |    ^^^^      ----  ----
+   |    ^^^^            ----
 help: change the type of the numeric literal from `i32` to `u32`
    |
 LL |     test(22i32, 44u32);
index eab42ca568a04b3c24f6c69cb575557d90a1d698..cbf09386654472d50aa65a437d43b7f696e4620a 100644 (file)
@@ -1,12 +1,12 @@
 error[E0271]: type mismatch resolving `<dyn Trait<B = B, A = A> as SuperTrait>::A == B`
-  --> $DIR/enforce-supertrait-projection.rs:9:5
+  --> $DIR/enforce-supertrait-projection.rs:9:17
    |
 LL | fn transmute<A, B>(x: A) -> B {
    |              -  - expected type parameter
    |              |
    |              found type parameter
 LL |     foo::<A, B, dyn Trait<A = A, B = B>>(x)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
    |
    = note: expected type parameter `B`
               found type parameter `A`
index 8456f84562ff2c1170b8b85011a6e87c9f790bac..0c3d7060dd7c30294ec93937ffa37993c7bf5485 100644 (file)
@@ -1,8 +1,8 @@
 error[E0271]: type mismatch resolving `<T as Pointee>::Metadata == ()`
-  --> $DIR/pointee-tail-is-generic-errors.rs:13:5
+  --> $DIR/pointee-tail-is-generic-errors.rs:13:15
    |
 LL |     is_thin::<T>();
-   |     ^^^^^^^^^^^^ expected `()`, found associated type
+   |               ^ expected `()`, found associated type
    |
    = note:    expected unit type `()`
            found associated type `<T as Pointee>::Metadata`
@@ -15,13 +15,13 @@ LL | fn is_thin<T: std::ptr::Pointee<Metadata = ()> + ?Sized>() {}
    |                                 ^^^^^^^^^^^^^ required by this bound in `is_thin`
 
 error[E0271]: type mismatch resolving `<Opaque as Pointee>::Metadata == ()`
-  --> $DIR/pointee-tail-is-generic-errors.rs:16:5
+  --> $DIR/pointee-tail-is-generic-errors.rs:16:15
    |
 LL | type Opaque = impl std::fmt::Debug + ?Sized;
    |               ----------------------------- the found opaque type
 ...
 LL |     is_thin::<Opaque>();
-   |     ^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |               ^^^^^^ expected `()`, found associated type
    |
    = note:    expected unit type `()`
            found associated type `<Opaque as Pointee>::Metadata`
diff --git a/src/test/ui/traits/unspecified-self-in-trait-ref.rs b/src/test/ui/traits/unspecified-self-in-trait-ref.rs
new file mode 100644 (file)
index 0000000..158b5a9
--- /dev/null
@@ -0,0 +1,30 @@
+pub trait Foo<A=Self> {
+    fn foo(&self);
+}
+
+pub trait Bar<X=usize, A=Self> {
+    fn foo(&self);
+}
+
+fn main() {
+    let a = Foo::lol();
+    //~^ ERROR no function or associated item named
+    //~| WARN trait objects without an explicit `dyn` are deprecated
+    //~| WARN this is accepted in the current edition
+    let b = Foo::<_>::lol();
+    //~^ ERROR no function or associated item named
+    //~| WARN trait objects without an explicit `dyn` are deprecated
+    //~| WARN this is accepted in the current edition
+    let c = Bar::lol();
+    //~^ ERROR no function or associated item named
+    //~| WARN trait objects without an explicit `dyn` are deprecated
+    //~| WARN this is accepted in the current edition
+    let d = Bar::<usize, _>::lol();
+    //~^ ERROR no function or associated item named
+    //~| WARN trait objects without an explicit `dyn` are deprecated
+    //~| WARN this is accepted in the current edition
+    let e = Bar::<usize>::lol();
+    //~^ ERROR must be explicitly specified
+    //~| WARN trait objects without an explicit `dyn` are deprecated
+    //~| WARN this is accepted in the current edition
+}
diff --git a/src/test/ui/traits/unspecified-self-in-trait-ref.stderr b/src/test/ui/traits/unspecified-self-in-trait-ref.stderr
new file mode 100644 (file)
index 0000000..7869176
--- /dev/null
@@ -0,0 +1,105 @@
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/unspecified-self-in-trait-ref.rs:10:13
+   |
+LL |     let a = Foo::lol();
+   |             ^^^
+   |
+   = note: `#[warn(bare_trait_objects)]` on by default
+   = 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>
+help: use `dyn`
+   |
+LL |     let a = <dyn Foo>::lol();
+   |             ++++    +
+
+error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope
+  --> $DIR/unspecified-self-in-trait-ref.rs:10:18
+   |
+LL |     let a = Foo::lol();
+   |                  ^^^ function or associated item not found in `dyn Foo<_>`
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/unspecified-self-in-trait-ref.rs:14:13
+   |
+LL |     let b = Foo::<_>::lol();
+   |             ^^^^^^^^
+   |
+   = 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>
+help: use `dyn`
+   |
+LL |     let b = <dyn Foo::<_>>::lol();
+   |             ++++         +
+
+error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope
+  --> $DIR/unspecified-self-in-trait-ref.rs:14:23
+   |
+LL |     let b = Foo::<_>::lol();
+   |                       ^^^ function or associated item not found in `dyn Foo<_>`
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/unspecified-self-in-trait-ref.rs:18:13
+   |
+LL |     let c = Bar::lol();
+   |             ^^^
+   |
+   = 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>
+help: use `dyn`
+   |
+LL |     let c = <dyn Bar>::lol();
+   |             ++++    +
+
+error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<_, _>` in the current scope
+  --> $DIR/unspecified-self-in-trait-ref.rs:18:18
+   |
+LL |     let c = Bar::lol();
+   |                  ^^^ function or associated item not found in `dyn Bar<_, _>`
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/unspecified-self-in-trait-ref.rs:22:13
+   |
+LL |     let d = Bar::<usize, _>::lol();
+   |             ^^^^^^^^^^^^^^^
+   |
+   = 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>
+help: use `dyn`
+   |
+LL |     let d = <dyn Bar::<usize, _>>::lol();
+   |             ++++                +
+
+error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<usize, _>` in the current scope
+  --> $DIR/unspecified-self-in-trait-ref.rs:22:30
+   |
+LL |     let d = Bar::<usize, _>::lol();
+   |                              ^^^ function or associated item not found in `dyn Bar<usize, _>`
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/unspecified-self-in-trait-ref.rs:26:13
+   |
+LL |     let e = Bar::<usize>::lol();
+   |             ^^^^^^^^^^^^
+   |
+   = 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>
+help: use `dyn`
+   |
+LL |     let e = <dyn Bar::<usize>>::lol();
+   |             ++++             +
+
+error[E0393]: the type parameter `A` must be explicitly specified
+  --> $DIR/unspecified-self-in-trait-ref.rs:26:13
+   |
+LL | pub trait Bar<X=usize, A=Self> {
+   | ------------------------------ type parameter `A` must be specified for this
+...
+LL |     let e = Bar::<usize>::lol();
+   |             ^^^^^^^^^^^^ missing reference to `A`
+   |
+   = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error: aborting due to 5 previous errors; 5 warnings emitted
+
+Some errors have detailed explanations: E0393, E0599.
+For more information about an error, try `rustc --explain E0393`.
index 95df96ca0dd4f2c09574f8b70cff237b97a06f5e..7029d298d71e276b670de443d15171106e47ceab 100644 (file)
@@ -8,7 +8,7 @@ note: function defined here
   --> $DIR/add-tuple-within-arguments.rs:1:4
    |
 LL | fn foo(s: &str, a: (i32, i32), s2: &str) {}
-   |    ^^^ -------  -------------  --------
+   |    ^^^          -------------
 help: wrap these arguments in parentheses to construct a tuple
    |
 LL |     foo("hi", (1, 2), "hi");
@@ -28,7 +28,7 @@ note: function defined here
   --> $DIR/add-tuple-within-arguments.rs:3:4
    |
 LL | fn bar(s: &str, a: (&str,), s2: &str) {}
-   |    ^^^ -------  ----------  --------
+   |    ^^^          ----------
 help: use a trailing comma to create a tuple with one element
    |
 LL |     bar("hi", ("hi",), "hi");
index 2733fb3149b55d1f8fcf87d9ca62091987fb4c6f..968cb75db7633582680eee04cd997990409bbc1e 100644 (file)
@@ -2,10 +2,13 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/wrong_argument_ice-3.rs:9:16
    |
 LL |         groups.push(new_group, vec![process]);
-   |                ^^^^ ---------  ------------- argument of type `Vec<&Process>` unexpected
-   |                     |
-   |                     expected tuple, found struct `Vec`
+   |                ^^^^            ------------- argument of type `Vec<&Process>` unexpected
    |
+note: expected tuple, found struct `Vec`
+  --> $DIR/wrong_argument_ice-3.rs:9:21
+   |
+LL |         groups.push(new_group, vec![process]);
+   |                     ^^^^^^^^^
    = note: expected tuple `(Vec<String>, Vec<Process>)`
              found struct `Vec<String>`
 note: associated function defined here
index 615fd2ccb04af04942a0d40d12aeffb7274f0a48..847bc517ea3d368a72d0e52ceec779df61c22357 100644 (file)
@@ -1,13 +1,13 @@
 error: function can not have more than 65535 arguments
-  --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:24
+  --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:22
    |
-LL |           fn _f($($t: ()),*) {}
-   |  ________________________^
-LL | |     }
-LL | }
-LL | |
-LL | | many_args!{[_]########## ######}
-   | |____________^
+LL |         fn _f($($t: ()),*) {}
+   |                      ^
+...
+LL | many_args!{[_]########## ######}
+   | -------------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `many_args` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
index 3241c9f8521c0811b9dae14916c3443f2c8b6ccf..455f83f5721bdfbb7a7f7974bfe15a3a47fe82fe 100644 (file)
@@ -6,11 +6,11 @@ LL |     let z = f(1_usize, 2);
    |             |
    |             arguments to this function are incorrect
    |
-note: closure defined here
-  --> $DIR/unboxed-closures-type-mismatch.rs:4:17
+note: closure parameter defined here
+  --> $DIR/unboxed-closures-type-mismatch.rs:4:18
    |
 LL |     let mut f = |x: isize, y: isize| -> isize { x + y };
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^
 help: change the type of the numeric literal from `usize` to `isize`
    |
 LL |     let z = f(1_isize, 2);
diff --git a/src/test/ui/unpretty/pretty-let-else.rs b/src/test/ui/unpretty/pretty-let-else.rs
new file mode 100644 (file)
index 0000000..5abfa25
--- /dev/null
@@ -0,0 +1,10 @@
+// compile-flags: -Zunpretty=hir
+// check-pass
+
+#![feature(let_else)]
+
+fn foo(x: Option<u32>) {
+    let Some(_) = x else { panic!() };
+}
+
+fn main() {}
diff --git a/src/test/ui/unpretty/pretty-let-else.stdout b/src/test/ui/unpretty/pretty-let-else.stdout
new file mode 100644 (file)
index 0000000..ffe1d16
--- /dev/null
@@ -0,0 +1,18 @@
+// compile-flags: -Zunpretty=hir
+// check-pass
+
+#![feature(let_else)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+fn foo(x:
+        Option<u32>) {
+        let Some(_) = x else
+            {
+
+            { ::std::rt::begin_panic("explicit panic") }
+        };
+    }
+fn main() { }
diff --git a/src/test/ui/unspecified-self-in-trait-ref.rs b/src/test/ui/unspecified-self-in-trait-ref.rs
deleted file mode 100644 (file)
index 158b5a9..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-pub trait Foo<A=Self> {
-    fn foo(&self);
-}
-
-pub trait Bar<X=usize, A=Self> {
-    fn foo(&self);
-}
-
-fn main() {
-    let a = Foo::lol();
-    //~^ ERROR no function or associated item named
-    //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-    let b = Foo::<_>::lol();
-    //~^ ERROR no function or associated item named
-    //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-    let c = Bar::lol();
-    //~^ ERROR no function or associated item named
-    //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-    let d = Bar::<usize, _>::lol();
-    //~^ ERROR no function or associated item named
-    //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-    let e = Bar::<usize>::lol();
-    //~^ ERROR must be explicitly specified
-    //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-}
diff --git a/src/test/ui/unspecified-self-in-trait-ref.stderr b/src/test/ui/unspecified-self-in-trait-ref.stderr
deleted file mode 100644 (file)
index 7869176..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/unspecified-self-in-trait-ref.rs:10:13
-   |
-LL |     let a = Foo::lol();
-   |             ^^^
-   |
-   = note: `#[warn(bare_trait_objects)]` on by default
-   = 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>
-help: use `dyn`
-   |
-LL |     let a = <dyn Foo>::lol();
-   |             ++++    +
-
-error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope
-  --> $DIR/unspecified-self-in-trait-ref.rs:10:18
-   |
-LL |     let a = Foo::lol();
-   |                  ^^^ function or associated item not found in `dyn Foo<_>`
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/unspecified-self-in-trait-ref.rs:14:13
-   |
-LL |     let b = Foo::<_>::lol();
-   |             ^^^^^^^^
-   |
-   = 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>
-help: use `dyn`
-   |
-LL |     let b = <dyn Foo::<_>>::lol();
-   |             ++++         +
-
-error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope
-  --> $DIR/unspecified-self-in-trait-ref.rs:14:23
-   |
-LL |     let b = Foo::<_>::lol();
-   |                       ^^^ function or associated item not found in `dyn Foo<_>`
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/unspecified-self-in-trait-ref.rs:18:13
-   |
-LL |     let c = Bar::lol();
-   |             ^^^
-   |
-   = 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>
-help: use `dyn`
-   |
-LL |     let c = <dyn Bar>::lol();
-   |             ++++    +
-
-error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<_, _>` in the current scope
-  --> $DIR/unspecified-self-in-trait-ref.rs:18:18
-   |
-LL |     let c = Bar::lol();
-   |                  ^^^ function or associated item not found in `dyn Bar<_, _>`
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/unspecified-self-in-trait-ref.rs:22:13
-   |
-LL |     let d = Bar::<usize, _>::lol();
-   |             ^^^^^^^^^^^^^^^
-   |
-   = 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>
-help: use `dyn`
-   |
-LL |     let d = <dyn Bar::<usize, _>>::lol();
-   |             ++++                +
-
-error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<usize, _>` in the current scope
-  --> $DIR/unspecified-self-in-trait-ref.rs:22:30
-   |
-LL |     let d = Bar::<usize, _>::lol();
-   |                              ^^^ function or associated item not found in `dyn Bar<usize, _>`
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/unspecified-self-in-trait-ref.rs:26:13
-   |
-LL |     let e = Bar::<usize>::lol();
-   |             ^^^^^^^^^^^^
-   |
-   = 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>
-help: use `dyn`
-   |
-LL |     let e = <dyn Bar::<usize>>::lol();
-   |             ++++             +
-
-error[E0393]: the type parameter `A` must be explicitly specified
-  --> $DIR/unspecified-self-in-trait-ref.rs:26:13
-   |
-LL | pub trait Bar<X=usize, A=Self> {
-   | ------------------------------ type parameter `A` must be specified for this
-...
-LL |     let e = Bar::<usize>::lol();
-   |             ^^^^^^^^^^^^ missing reference to `A`
-   |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
-
-error: aborting due to 5 previous errors; 5 warnings emitted
-
-Some errors have detailed explanations: E0393, E0599.
-For more information about an error, try `rustc --explain E0393`.
index ce40690a5e4e315d3dab0aae1eae69d0252c52ac..efd4ca3dc0b89929dc8c5f5c023d25978d76cb61 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ce40690a5e4e315d3dab0aae1eae69d0252c52ac
+Subproject commit efd4ca3dc0b89929dc8c5f5c023d25978d76cb61
index 8536e2429926a6b9b726b4498db635cfd64a2b1d..8a6bd1cbdf564b5bff3095f012adff97ce736884 100644 (file)
@@ -1,4 +1,3 @@
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(once_cell)]
 #![feature(rustc_private)]
index 5d41c63928dfb0daeb6cb3a2bb2eed9bd9e80af9..59f10247a11d4c98ea4821a3746ee2479c37aff9 100644 (file)
@@ -2,7 +2,7 @@
 use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
 use clippy_utils::ty::{expr_sig, peel_mid_ty_refs, ty_sig, variant_of_res};
-use clippy_utils::{get_parent_expr, is_lint_allowed, path_to_local, walk_to_expr_usage};
+use clippy_utils::{get_parent_expr, get_parent_expr_for_hir, is_lint_allowed, path_to_local, walk_to_expr_usage};
 use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Applicability;
@@ -699,6 +699,19 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
                 Some(ty_auto_deref_stability(cx, output, precedence).position_for_result(cx))
             },
 
+            Node::ExprField(field) if field.span.ctxt() == ctxt => match get_parent_expr_for_hir(cx, field.hir_id) {
+                Some(Expr {
+                    hir_id,
+                    kind: ExprKind::Struct(path, ..),
+                    ..
+                }) => variant_of_res(cx, cx.qpath_res(path, *hir_id))
+                    .and_then(|variant| variant.fields.iter().find(|f| f.name == field.ident.name))
+                    .map(|field_def| {
+                        ty_auto_deref_stability(cx, cx.tcx.type_of(field_def.did), precedence).position_for_arg()
+                    }),
+                _ => None,
+            },
+
             Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind {
                 ExprKind::Ret(_) => {
                     let owner_id = cx.tcx.hir().body_owner(cx.enclosing_body.unwrap());
@@ -788,17 +801,6 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
                         }
                     })
                 },
-                ExprKind::Struct(path, fields, _) => {
-                    let variant = variant_of_res(cx, cx.qpath_res(path, parent.hir_id));
-                    fields
-                        .iter()
-                        .find(|f| f.expr.hir_id == child_id)
-                        .zip(variant)
-                        .and_then(|(field, variant)| variant.fields.iter().find(|f| f.name == field.ident.name))
-                        .map(|field| {
-                            ty_auto_deref_stability(cx, cx.tcx.type_of(field.did), precedence).position_for_arg()
-                        })
-                },
                 ExprKind::Field(child, name) if child.hir_id == e.hir_id => Some(Position::FieldAccess(name.name)),
                 ExprKind::Unary(UnOp::Deref, child) if child.hir_id == e.hir_id => Some(Position::Deref),
                 ExprKind::Match(child, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar)
index 2975399a8bbbacca3e07ff1b7b42f05ee74ed7e3..e6a405f8170d8f0a8e06df0fb807942f9eaf22d4 100644 (file)
@@ -4,7 +4,6 @@
 #![feature(control_flow_enum)]
 #![feature(drain_filter)]
 #![feature(iter_intersperse)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(let_else)]
 #![feature(lint_reasons)]
 #![feature(never_type)]
index 2616a578bb884271153d00ca9c038efa6f730058..dc772e5efeef39cc8f9f333e3cdab59198cfc556 100644 (file)
@@ -2,7 +2,6 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(let_else)]
-#![cfg_attr(bootstrap, feature(let_chains))]
 #![feature(lint_reasons)]
 #![feature(once_cell)]
 #![feature(rustc_private)]
index c1ec2bd5bd665c659475866d3ba817ff37189aef..235eae5af1ec386e3f0c620bba77a21bc0e0afff 100644 (file)
@@ -95,7 +95,7 @@ struct ClippyCallbacks {
 
 impl rustc_driver::Callbacks for ClippyCallbacks {
     // JUSTIFICATION: necessary in clippy driver to set `mir_opt_level`
-    #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+    #[allow(rustc::bad_opt_access)]
     fn config(&mut self, config: &mut interface::Config) {
         let previous = config.register_lints.take();
         let clippy_args_var = self.clippy_args_var.take();
index ac6d80bb439b3b99e5931639ca9f9e110eaca689..0e2cc52a645bcbdc982476ecc0c723e39bf0bda7 100644 (file)
@@ -545,6 +545,8 @@ fn common_inputs_stamp(config: &Config) -> Stamp {
         stamp.add_path(&path);
     }
 
+    stamp.add_dir(&rust_src_dir.join("src/etc/natvis"));
+
     stamp.add_dir(&config.run_lib_path);
 
     if let Some(ref rustdoc_path) = config.rustdoc_path {
index 39ee5747153bf13324870c4a912acbf1f9bfde3f..50ef22af522f2545295090cc1ad3e4bd4aa8632c 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 39ee5747153bf13324870c4a912acbf1f9bfde3f
+Subproject commit 50ef22af522f2545295090cc1ad3e4bd4aa8632c
index 025b8ab9f0af5f620809e1121c22c7ac224e96c1..30903f56d93b03ffd1450538121e69a09cf220ee 100644 (file)
@@ -98,7 +98,7 @@ fn check_dir(dir: &Path) -> FilesystemSupport {
     pub fn check(path: &Path, bad: &mut bool) {
         use std::ffi::OsStr;
 
-        const ALLOWED: &[&str] = &["configure"];
+        const ALLOWED: &[&str] = &["configure", "x"];
 
         crate::walk_no_read(
             path,
diff --git a/x b/x
new file mode 100755 (executable)
index 0000000..704d0f7
--- /dev/null
+++ b/x
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# Modern Linux and macOS systems commonly only have a thing called `python3` and
+# not `python`, while Windows commonly does not have `python3`, so we cannot
+# directly use python in the x.py shebang and have it consistently work. Instead we
+# have a shell script to look for a python to run x.py.
+
+set -eu
+
+realpath() {
+    if [ -d "$1" ]; then
+        CDPATH='' command cd "$1" && pwd -P   
+    else
+        echo "$(realpath "$(dirname "$1")")/$(basename "$1")"
+    fi
+}
+
+xpy=$(dirname "$(realpath "$0")")/x.py
+
+# On Windows, `py -3` sometimes works. We need to try it first because `python3`
+# sometimes tries to launch the app store on Windows.
+for SEARCH_PYTHON in py python3 python python2; do
+    if python=$(command -v $SEARCH_PYTHON) && [ -x "$python" ]; then
+        if [ $SEARCH_PYTHON = py ]; then
+            extra_arg="-3"
+        else
+            extra_arg=""
+        fi
+        exec "$python" $extra_arg "$xpy" "$@"
+    fi
+done
+echo "$0: error: did not find python installed" >&2
+exit 1
diff --git a/x.ps1 b/x.ps1
index 1225443735f7b14627e2887e9467d954ca5785f1..86cea606591ba088e4643cd4b0bd2d29125d4c72 100755 (executable)
--- a/x.ps1
+++ b/x.ps1
@@ -1,6 +1,6 @@
 #!/usr/bin/env pwsh
 
-# See x.sh for why these scripts exist.
+# See ./x for why these scripts exist.
 
 $xpy = Join-Path $PSScriptRoot x.py
 # Start-Process for some reason splits arguments on spaces. (Isn't powershell supposed to be simpler than bash?)
diff --git a/x.py b/x.py
index 6c68907c581457c200050e841768c5763e06d6b3..6df4033d55d7273bd064cedbddf4c959ee1dd301 100755 (executable)
--- a/x.py
+++ b/x.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 # Some systems don't have `python3` in their PATH. This isn't supported by x.py directly;
-# they should use `x.sh` or `x.ps1` instead.
+# they should use `x` or `x.ps1` instead.
 
 # This file is only a "symlink" to bootstrap.py, all logic should go there.
 
diff --git a/x.sh b/x.sh
deleted file mode 100755 (executable)
index 704d0f7..0000000
--- a/x.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-# Modern Linux and macOS systems commonly only have a thing called `python3` and
-# not `python`, while Windows commonly does not have `python3`, so we cannot
-# directly use python in the x.py shebang and have it consistently work. Instead we
-# have a shell script to look for a python to run x.py.
-
-set -eu
-
-realpath() {
-    if [ -d "$1" ]; then
-        CDPATH='' command cd "$1" && pwd -P   
-    else
-        echo "$(realpath "$(dirname "$1")")/$(basename "$1")"
-    fi
-}
-
-xpy=$(dirname "$(realpath "$0")")/x.py
-
-# On Windows, `py -3` sometimes works. We need to try it first because `python3`
-# sometimes tries to launch the app store on Windows.
-for SEARCH_PYTHON in py python3 python python2; do
-    if python=$(command -v $SEARCH_PYTHON) && [ -x "$python" ]; then
-        if [ $SEARCH_PYTHON = py ]; then
-            extra_arg="-3"
-        else
-            extra_arg=""
-        fi
-        exec "$python" $extra_arg "$xpy" "$@"
-    fi
-done
-echo "$0: error: did not find python installed" >&2
-exit 1