]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #104581 - notriddle:notriddle/js-iife-2, r=GuillaumeGomez
authorMatthias Krüger <matthias.krueger@famsik.de>
Sun, 20 Nov 2022 22:50:28 +0000 (23:50 +0100)
committerGitHub <noreply@github.com>
Sun, 20 Nov 2022 22:50:28 +0000 (23:50 +0100)
rustdoc: remove unused JS IIFE from main.js

This [IIFE] made sense when it was added in deaf5e200e79a75ac57d3f0952f6758a38168e52 and there was a local variable scoped to it, but now it calls a function, but declares nothing.

[IIFE]: https://developer.mozilla.org/en-US/docs/Glossary/IIFE "immediately invoked function expression"

376 files changed:
Cargo.lock
compiler/rustc_ast/src/ast.rs
compiler/rustc_ast/src/attr/mod.rs
compiler/rustc_ast/src/mut_visit.rs
compiler/rustc_ast/src/util/classify.rs
compiler/rustc_ast/src/util/parser.rs
compiler/rustc_ast/src/visit.rs
compiler/rustc_ast_lowering/src/expr.rs
compiler/rustc_ast_lowering/src/item.rs
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_ast_lowering/src/path.rs
compiler/rustc_ast_pretty/src/pprust/state/expr.rs
compiler/rustc_baked_icu_data/Cargo.toml [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/data/any.rs [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1.rs [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/data/fallback/mod.rs [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/data/fallback/parents_v1.rs [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1.rs [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/data/fallback/supplement/mod.rs [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/data/list/and_v1.rs [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/data/list/mod.rs [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/data/mod.rs [new file with mode: 0644]
compiler/rustc_baked_icu_data/src/lib.rs [new file with mode: 0644]
compiler/rustc_borrowck/src/lib.rs
compiler/rustc_borrowck/src/nll.rs
compiler/rustc_borrowck/src/region_infer/opaque_types.rs
compiler/rustc_builtin_macros/src/assert/context.rs
compiler/rustc_codegen_cranelift/src/abi/mod.rs
compiler/rustc_codegen_cranelift/src/main_shim.rs
compiler/rustc_codegen_gcc/src/context.rs
compiler/rustc_codegen_gcc/src/declare.rs
compiler/rustc_codegen_llvm/src/abi.rs
compiler/rustc_codegen_llvm/src/context.rs
compiler/rustc_codegen_llvm/src/declare.rs
compiler/rustc_codegen_ssa/src/back/symbol_export.rs
compiler/rustc_const_eval/Cargo.toml
compiler/rustc_const_eval/src/const_eval/eval_queries.rs
compiler/rustc_const_eval/src/const_eval/machine.rs
compiler/rustc_const_eval/src/interpret/eval_context.rs
compiler/rustc_const_eval/src/interpret/intrinsics.rs
compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
compiler/rustc_const_eval/src/interpret/operand.rs
compiler/rustc_const_eval/src/interpret/place.rs
compiler/rustc_const_eval/src/interpret/projection.rs
compiler/rustc_const_eval/src/interpret/step.rs
compiler/rustc_const_eval/src/interpret/validity.rs
compiler/rustc_const_eval/src/transform/check_consts/mod.rs
compiler/rustc_const_eval/src/transform/validate.rs
compiler/rustc_const_eval/src/util/compare_types.rs [new file with mode: 0644]
compiler/rustc_const_eval/src/util/mod.rs
compiler/rustc_data_structures/src/functor.rs
compiler/rustc_driver/src/lib.rs
compiler/rustc_error_messages/Cargo.toml
compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl [new file with mode: 0644]
compiler/rustc_error_messages/locales/en-US/parser.ftl
compiler/rustc_error_messages/locales/en-US/resolve.ftl [new file with mode: 0644]
compiler/rustc_error_messages/src/lib.rs
compiler/rustc_errors/Cargo.toml
compiler/rustc_errors/src/diagnostic.rs
compiler/rustc_errors/src/diagnostic_impls.rs
compiler/rustc_errors/src/emitter.rs
compiler/rustc_errors/src/lib.rs
compiler/rustc_expand/Cargo.toml
compiler/rustc_expand/src/base.rs
compiler/rustc_expand/src/build.rs
compiler/rustc_expand/src/mbe/macro_rules.rs
compiler/rustc_expand/src/placeholders.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_hir/src/hir.rs
compiler/rustc_hir/src/lang_items.rs
compiler/rustc_hir_analysis/src/astconv/mod.rs
compiler/rustc_hir_analysis/src/check/check.rs
compiler/rustc_hir_analysis/src/check/compare_method.rs
compiler/rustc_hir_analysis/src/collect.rs
compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
compiler/rustc_hir_typeck/src/cast.rs
compiler/rustc_hir_typeck/src/coercion.rs
compiler/rustc_hir_typeck/src/demand.rs
compiler/rustc_hir_typeck/src/errors.rs
compiler/rustc_hir_typeck/src/expr.rs
compiler/rustc_hir_typeck/src/fallback.rs
compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
compiler/rustc_hir_typeck/src/lib.rs
compiler/rustc_hir_typeck/src/mem_categorization.rs
compiler/rustc_hir_typeck/src/method/suggest.rs
compiler/rustc_hir_typeck/src/op.rs
compiler/rustc_hir_typeck/src/pat.rs
compiler/rustc_hir_typeck/src/writeback.rs
compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_infer/src/infer/nll_relate/mod.rs
compiler/rustc_infer/src/infer/sub.rs
compiler/rustc_interface/Cargo.toml
compiler/rustc_lint/src/early.rs
compiler/rustc_lint/src/non_fmt_panic.rs
compiler/rustc_lint/src/unused.rs
compiler/rustc_log/Cargo.toml
compiler/rustc_log/src/lib.rs
compiler/rustc_macros/src/diagnostics/utils.rs
compiler/rustc_middle/Cargo.toml
compiler/rustc_middle/src/mir/interpret/allocation.rs
compiler/rustc_middle/src/mir/interpret/error.rs
compiler/rustc_middle/src/mir/interpret/value.rs
compiler/rustc_middle/src/query/mod.rs
compiler/rustc_middle/src/traits/mod.rs
compiler/rustc_middle/src/ty/error.rs
compiler/rustc_middle/src/ty/inhabitedness/mod.rs
compiler/rustc_middle/src/ty/instance.rs
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_mir_build/Cargo.toml
compiler/rustc_mir_build/src/build/matches/test.rs
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
compiler/rustc_mir_dataflow/src/value_analysis.rs
compiler/rustc_mir_transform/Cargo.toml
compiler/rustc_mir_transform/src/const_prop.rs
compiler/rustc_mir_transform/src/const_prop_lint.rs
compiler/rustc_mir_transform/src/inline.rs
compiler/rustc_monomorphize/src/collector.rs
compiler/rustc_parse/Cargo.toml
compiler/rustc_parse/src/errors.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/pat.rs
compiler/rustc_parse/src/parser/path.rs
compiler/rustc_passes/src/check_attr.rs
compiler/rustc_passes/src/dead.rs
compiler/rustc_resolve/Cargo.toml
compiler/rustc_resolve/src/def_collector.rs
compiler/rustc_resolve/src/diagnostics.rs
compiler/rustc_resolve/src/errors.rs [new file with mode: 0644]
compiler/rustc_resolve/src/late.rs
compiler/rustc_resolve/src/late/diagnostics.rs
compiler/rustc_resolve/src/lib.rs
compiler/rustc_session/src/session.rs
compiler/rustc_span/src/source_map.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_target/src/abi/call/mod.rs
compiler/rustc_target/src/json.rs
compiler/rustc_target/src/spec/mod.rs
compiler/rustc_trait_selection/src/traits/engine.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
compiler/rustc_trait_selection/src/traits/object_safety.rs
compiler/rustc_trait_selection/src/traits/project.rs
compiler/rustc_trait_selection/src/traits/query/normalize.rs
compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
compiler/rustc_trait_selection/src/traits/select/confirmation.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
compiler/rustc_traits/src/normalize_erasing_regions.rs
library/alloc/src/collections/vec_deque/mod.rs
library/alloc/src/lib.rs
library/alloc/src/rc.rs
library/alloc/src/slice.rs
library/alloc/src/string.rs
library/alloc/src/sync.rs
library/alloc/tests/arc.rs
library/alloc/tests/rc.rs
library/alloc/tests/vec_deque.rs
library/core/src/alloc/global.rs
library/core/src/alloc/mod.rs
library/core/src/cell/lazy.rs
library/core/src/cell/once.rs
library/core/src/fmt/mod.rs
library/core/src/intrinsics.rs
library/core/src/iter/mod.rs
library/core/src/iter/sources.rs
library/core/src/iter/sources/repeat_n.rs [new file with mode: 0644]
library/core/src/lib.rs
library/core/src/marker.rs
library/core/src/num/int_macros.rs
library/core/src/num/mod.rs
library/core/src/num/uint_macros.rs
library/core/src/ptr/const_ptr.rs
library/core/src/ptr/mod.rs
library/core/src/ptr/mut_ptr.rs
library/core/src/slice/mod.rs
library/core/tests/iter/sources.rs
library/core/tests/lib.rs
library/core/tests/ptr.rs
library/panic_unwind/src/lib.rs
library/std/src/f32.rs
library/std/src/f32/tests.rs
library/std/src/f64.rs
library/std/src/f64/tests.rs
library/std/src/sync/lazy_lock.rs
library/std/src/sync/once_lock.rs
library/std/src/sys/unix/time.rs
library/std/src/sys/windows/fs.rs
library/std/src/thread/mod.rs
library/std/src/time/tests.rs
library/unwind/src/libunwind.rs
src/bootstrap/Cargo.lock
src/bootstrap/Cargo.toml
src/bootstrap/compile.rs
src/bootstrap/config.rs
src/bootstrap/metrics.rs
src/bootstrap/test.rs
src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
src/librustdoc/Cargo.toml
src/librustdoc/config.rs
src/librustdoc/html/render/mod.rs
src/librustdoc/html/render/print_item.rs
src/librustdoc/html/sources.rs
src/librustdoc/html/static/css/rustdoc.css
src/librustdoc/html/static/css/themes/ayu.css
src/librustdoc/html/static/css/themes/dark.css
src/librustdoc/html/static/css/themes/light.css
src/librustdoc/html/static/js/main.js
src/librustdoc/html/static_files.rs
src/librustdoc/html/templates/page.html
src/librustdoc/lib.rs
src/test/assembly/is_aligned.rs [new file with mode: 0644]
src/test/codegen/iter-repeat-n-trivial-drop.rs [new file with mode: 0644]
src/test/codegen/unchecked_shifts.rs [new file with mode: 0644]
src/test/debuginfo/function-names.rs
src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir [new file with mode: 0644]
src/test/mir-opt/deref-patterns/string.rs [new file with mode: 0644]
src/test/rustdoc-gui/enum-variants.goml [new file with mode: 0644]
src/test/rustdoc-gui/help-page.goml
src/test/rustdoc-gui/notable-trait.goml
src/test/rustdoc-gui/scrape-examples-button-focus.goml [new file with mode: 0644]
src/test/rustdoc-gui/sidebar-source-code-display.goml
src/test/rustdoc-gui/sidebar-source-code.goml
src/test/rustdoc-gui/src/scrape_examples/Cargo.lock [new file with mode: 0644]
src/test/rustdoc-gui/src/scrape_examples/Cargo.toml [new file with mode: 0644]
src/test/rustdoc-gui/src/scrape_examples/examples/check.rs [new file with mode: 0644]
src/test/rustdoc-gui/src/scrape_examples/src/lib.rs [new file with mode: 0644]
src/test/rustdoc/issue-88600.rs
src/test/ui-fulldeps/pprust-expr-roundtrip.rs
src/test/ui/array-slice-vec/slice_is_sorted_by_borrow.rs [new file with mode: 0644]
src/test/ui/async-await/in-trait/object-safety.rs [new file with mode: 0644]
src/test/ui/async-await/in-trait/object-safety.stderr [new file with mode: 0644]
src/test/ui/blind-item-local-shadow.rs [deleted file]
src/test/ui/cast/cast-pointee-projection.rs [new file with mode: 0644]
src/test/ui/coherence/issue-100191-2.rs [deleted file]
src/test/ui/coherence/issue-100191-2.stderr [deleted file]
src/test/ui/coherence/issue-100191.rs [deleted file]
src/test/ui/coherence/issue-100191.stderr [deleted file]
src/test/ui/deref-patterns/basic.rs [new file with mode: 0644]
src/test/ui/deref-patterns/basic.run.stdout [new file with mode: 0644]
src/test/ui/deref-patterns/default-infer.rs [new file with mode: 0644]
src/test/ui/deref-patterns/gate.rs [new file with mode: 0644]
src/test/ui/deref-patterns/gate.stderr [new file with mode: 0644]
src/test/ui/deref-patterns/refs.rs [new file with mode: 0644]
src/test/ui/dyn-star/align.normal.stderr [new file with mode: 0644]
src/test/ui/dyn-star/align.over_aligned.stderr [new file with mode: 0644]
src/test/ui/dyn-star/align.rs [new file with mode: 0644]
src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs [new file with mode: 0644]
src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr [new file with mode: 0644]
src/test/ui/dyn-star/check-size-at-cast-polymorphic.rs [new file with mode: 0644]
src/test/ui/dyn-star/check-size-at-cast.rs [new file with mode: 0644]
src/test/ui/dyn-star/check-size-at-cast.stderr [new file with mode: 0644]
src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs [new file with mode: 0644]
src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs [new file with mode: 0644]
src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0275.rs
src/test/ui/error-codes/E0275.stderr
src/test/ui/impl-trait/in-trait/object-safety.stderr
src/test/ui/impl-trait/normalize-tait-in-const.rs [new file with mode: 0644]
src/test/ui/impl-trait/normalize-tait-in-const.stderr [new file with mode: 0644]
src/test/ui/infinite/infinite-instantiation.stderr
src/test/ui/issues/issue-20413.rs
src/test/ui/issues/issue-20413.stderr
src/test/ui/issues/issue-22638.stderr
src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
src/test/ui/issues/issue-52262.rs
src/test/ui/issues/issue-52262.stderr
src/test/ui/issues/issue-67552.stderr
src/test/ui/issues/issue-8727.stderr
src/test/ui/mir/important-higher-ranked-regions.rs [new file with mode: 0644]
src/test/ui/parser/issue-103381.fixed [new file with mode: 0644]
src/test/ui/parser/issue-103381.rs [new file with mode: 0644]
src/test/ui/parser/issue-103381.stderr [new file with mode: 0644]
src/test/ui/recursion/issue-83150.rs
src/test/ui/recursion/issue-83150.stderr
src/test/ui/recursion/recursion.stderr
src/test/ui/resolve/blind-item-local-shadow.rs [new file with mode: 0644]
src/test/ui/specialization/issue-43037.current.stderr [new file with mode: 0644]
src/test/ui/specialization/issue-43037.negative.stderr [new file with mode: 0644]
src/test/ui/specialization/issue-43037.rs
src/test/ui/specialization/issue-43037.stderr [deleted file]
src/test/ui/specialization/issue-45814.current.stderr [new file with mode: 0644]
src/test/ui/specialization/issue-45814.negative.stderr [new file with mode: 0644]
src/test/ui/specialization/issue-45814.rs
src/test/ui/specialization/issue-45814.stderr [deleted file]
src/test/ui/stats/hir-stats.stderr
src/test/ui/structs/multi-line-fru-suggestion.rs [new file with mode: 0644]
src/test/ui/structs/multi-line-fru-suggestion.stderr [new file with mode: 0644]
src/test/ui/structs/struct-record-suggestion.fixed
src/test/ui/structs/struct-record-suggestion.rs
src/test/ui/structs/struct-record-suggestion.stderr
src/test/ui/suggestions/issue-102354.stderr
src/test/ui/suggestions/issue-104287.rs [new file with mode: 0644]
src/test/ui/suggestions/issue-104287.stderr [new file with mode: 0644]
src/test/ui/traits/issue-91949-hangs-on-recursion.rs
src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
src/test/ui/type/issue-103271.rs
src/test/ui/type/issue-103271.stderr
src/test/ui/type_length_limit.rs
src/test/ui/type_length_limit.stderr
src/tools/cargo
src/tools/clippy/clippy_lints/src/double_parens.rs
src/tools/clippy/clippy_lints/src/format.rs
src/tools/clippy/clippy_lints/src/format_push_string.rs
src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
src/tools/clippy/clippy_lints/src/inherent_to_string.rs
src/tools/clippy/clippy_lints/src/manual_async_fn.rs
src/tools/clippy/clippy_lints/src/manual_retain.rs
src/tools/clippy/clippy_lints/src/manual_string_new.rs
src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs
src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs
src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs
src/tools/clippy/clippy_lints/src/methods/repeat_once.rs
src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs
src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs
src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
src/tools/clippy/clippy_lints/src/option_env_unwrap.rs
src/tools/clippy/clippy_lints/src/precedence.rs
src/tools/clippy/clippy_lints/src/ptr.rs
src/tools/clippy/clippy_lints/src/redundant_clone.rs
src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
src/tools/clippy/clippy_lints/src/strings.rs
src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
src/tools/clippy/clippy_lints/src/types/box_collection.rs
src/tools/clippy/clippy_lints/src/types/rc_buffer.rs
src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
src/tools/clippy/clippy_lints/src/unused_async.rs
src/tools/clippy/clippy_lints/src/unused_rounding.rs
src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
src/tools/clippy/clippy_utils/src/ast_utils.rs
src/tools/clippy/clippy_utils/src/lib.rs
src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr
src/tools/compiletest/src/common.rs
src/tools/compiletest/src/header/tests.rs
src/tools/compiletest/src/main.rs
src/tools/compiletest/src/runtest.rs
src/tools/miri/Cargo.lock
src/tools/miri/Cargo.toml
src/tools/miri/README.md
src/tools/miri/miri
src/tools/miri/rust-version
src/tools/miri/src/bin/miri.rs
src/tools/miri/src/shims/intrinsics/mod.rs
src/tools/miri/src/shims/mod.rs
src/tools/miri/src/shims/time.rs
src/tools/miri/src/shims/unix/foreign_items.rs
src/tools/miri/src/shims/unix/linux/foreign_items.rs
src/tools/miri/src/stacked_borrows/mod.rs
src/tools/miri/test-cargo-miri/run-test.py
src/tools/miri/tests/pass-dep/shims/libc-misc.rs
src/tools/miri/tests/pass/align_offset_symbolic.rs
src/tools/miri/tests/pass/issues/issue-miri-2433.rs [deleted file]
src/tools/miri/tests/pass/panic/catch_panic.rs
src/tools/miropt-test-tools/src/lib.rs
src/tools/rustfmt/src/attr.rs
src/tools/rustfmt/src/chains.rs
src/tools/rustfmt/src/closures.rs
src/tools/rustfmt/src/expr.rs
src/tools/rustfmt/src/patterns.rs
src/tools/rustfmt/src/types.rs
src/tools/rustfmt/src/utils.rs
src/tools/tidy/src/deps.rs

index c867bb4ceaa9ec6fb3e6ea2ea62e3fa082d386a8..fb6140e74fea4bb65d291a6c50706e75908b1927 100644 (file)
@@ -211,7 +211,7 @@ checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
 dependencies = [
  "lazy_static",
  "memchr",
- "regex-automata",
+ "regex-automata 0.1.10",
 ]
 
 [[package]]
@@ -222,7 +222,7 @@ checksum = "fca0852af221f458706eb0725c03e4ed6c46af9ac98e6a689d5e634215d594dd"
 dependencies = [
  "memchr",
  "once_cell",
- "regex-automata",
+ "regex-automata 0.1.10",
  "serde",
 ]
 
@@ -307,6 +307,7 @@ dependencies = [
  "glob",
  "hex 0.4.2",
  "home",
+ "http-auth",
  "humantime 2.0.1",
  "ignore",
  "im-rc",
@@ -349,11 +350,11 @@ dependencies = [
 
 [[package]]
 name = "cargo-credential"
-version = "0.1.0"
+version = "0.2.0"
 
 [[package]]
 name = "cargo-credential-1password"
-version = "0.1.0"
+version = "0.2.0"
 dependencies = [
  "cargo-credential",
  "serde",
@@ -362,7 +363,7 @@ dependencies = [
 
 [[package]]
 name = "cargo-credential-macos-keychain"
-version = "0.1.0"
+version = "0.2.0"
 dependencies = [
  "cargo-credential",
  "security-framework",
@@ -370,7 +371,7 @@ dependencies = [
 
 [[package]]
 name = "cargo-credential-wincred"
-version = "0.1.0"
+version = "0.2.0"
 dependencies = [
  "cargo-credential",
  "winapi",
@@ -1692,6 +1693,15 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "http-auth"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0b40b39d66c28829a0cf4d09f7e139ff8201f7500a5083732848ed3b4b4d850"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "humantime"
 version = "1.3.0"
@@ -1707,6 +1717,73 @@ version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a"
 
+[[package]]
+name = "icu_list"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c40218275f081c4493f190357c5395647b06734c2dc3dcb41cc099a0f60168b1"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_provider",
+ "regex-automata 0.2.0",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34b3de5d99a0e275fe6193b9586dbf37364daebc0d39c89b5cf8376a53b789e8"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f911086e3c521a8a824d4f8bfd87769645ced2f07ff913b521c0d793be07100"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_provider_macros",
+ "stable_deref_trait",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider_adapters"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "980c71d8a91b246ebbb97847178a4b816eea39d1d550c70ee566384555bb6545"
+dependencies = [
+ "icu_locid",
+ "icu_provider",
+ "tinystr",
+ "yoke",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider_macros"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38cf6f5b65cf81f0b4298da647101acbfe6ae0e25263f92bd7a22597e9d6d606"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "idna"
 version = "0.2.0"
@@ -2034,6 +2111,12 @@ dependencies = [
  "walkdir",
 ]
 
+[[package]]
+name = "litemap"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f34a3f4798fac63fb48cf277eefa38f94d3443baff555bb98e4f56bc9092368e"
+
 [[package]]
 name = "lld-wrapper"
 version = "0.1.0"
@@ -2100,7 +2183,7 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
 dependencies = [
- "regex-automata",
+ "regex-automata 0.1.10",
 ]
 
 [[package]]
@@ -2247,7 +2330,6 @@ dependencies = [
  "regex",
  "rustc-workspace-hack",
  "rustc_version",
- "shell-escape",
  "smallvec",
  "ui_test",
 ]
@@ -2927,6 +3009,15 @@ dependencies = [
  "regex-syntax",
 ]
 
+[[package]]
+name = "regex-automata"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9368763f5a9b804326f3af749e16f9abf378d227bcdee7634b13d8f17793782"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "regex-syntax"
 version = "0.6.26"
@@ -3202,6 +3293,18 @@ dependencies = [
  "rustc_span",
 ]
 
+[[package]]
+name = "rustc_baked_icu_data"
+version = "0.0.0"
+dependencies = [
+ "icu_list",
+ "icu_locid",
+ "icu_provider",
+ "icu_provider_adapters",
+ "litemap",
+ "zerovec",
+]
+
 [[package]]
 name = "rustc_borrowck"
 version = "0.0.0"
@@ -3330,6 +3433,7 @@ dependencies = [
 name = "rustc_const_eval"
 version = "0.0.0"
 dependencies = [
+ "either",
  "rustc_apfloat",
  "rustc_ast",
  "rustc_attr",
@@ -3422,13 +3526,18 @@ version = "0.0.0"
 dependencies = [
  "fluent-bundle",
  "fluent-syntax",
+ "icu_list",
+ "icu_locid",
+ "icu_provider_adapters",
  "intl-memoizer",
+ "rustc_baked_icu_data",
  "rustc_data_structures",
  "rustc_macros",
  "rustc_serialize",
  "rustc_span",
  "tracing",
  "unic-langid",
+ "writeable",
 ]
 
 [[package]]
@@ -3436,7 +3545,6 @@ name = "rustc_errors"
 version = "0.0.0"
 dependencies = [
  "annotate-snippets",
- "atty",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_data_structures",
@@ -3476,6 +3584,7 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "smallvec",
+ "thin-vec",
  "tracing",
 ]
 
@@ -3734,7 +3843,6 @@ dependencies = [
 name = "rustc_log"
 version = "0.0.0"
 dependencies = [
- "atty",
  "rustc_span",
  "tracing",
  "tracing-subscriber",
@@ -3820,6 +3928,7 @@ dependencies = [
 name = "rustc_mir_build"
 version = "0.0.0"
 dependencies = [
+ "either",
  "rustc_apfloat",
  "rustc_arena",
  "rustc_ast",
@@ -3866,6 +3975,7 @@ name = "rustc_mir_transform"
 version = "0.0.0"
 dependencies = [
  "coverage_test_macros",
+ "either",
  "itertools",
  "rustc_ast",
  "rustc_attr",
@@ -3916,6 +4026,7 @@ dependencies = [
  "rustc_macros",
  "rustc_session",
  "rustc_span",
+ "thin-vec",
  "tracing",
  "unicode-normalization",
  "unicode-width",
@@ -4045,12 +4156,14 @@ dependencies = [
  "rustc_feature",
  "rustc_hir",
  "rustc_index",
+ "rustc_macros",
  "rustc_metadata",
  "rustc_middle",
  "rustc_query_system",
  "rustc_session",
  "rustc_span",
  "smallvec",
+ "thin-vec",
  "tracing",
 ]
 
@@ -4286,7 +4399,6 @@ version = "0.0.0"
 dependencies = [
  "arrayvec",
  "askama",
- "atty",
  "expect-test",
  "itertools",
  "minifier",
@@ -4931,6 +5043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f8aeafdfd935e4a7fe16a91ab711fa52d54df84f9c8f7ca5837a9d1d902ef4c2"
 dependencies = [
  "displaydoc",
+ "zerovec",
 ]
 
 [[package]]
@@ -5543,6 +5656,12 @@ version = "0.42.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
 
+[[package]]
+name = "writeable"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8e6ab4f5da1b24daf2c590cfac801bacb27b15b4f050e84eb60149ea726f06b"
+
 [[package]]
 name = "xattr"
 version = "0.2.2"
@@ -5595,3 +5714,71 @@ checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1"
 dependencies = [
  "winapi",
 ]
+
+[[package]]
+name = "yoke"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fe1d55ca72c32d573bfbd5cb2f0ca65a497854c44762957a6d3da96041a5184"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1346e4cd025ae818b88566eac7eb65ab33a994ea55f355c86889af2e7e56b14e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79e9355fccf72b04b7deaa99ce7a0f6630530acf34045391b74460fcd714de54"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e8aa86add9ddbd2409c1ed01e033cd457d79b1b1229b64922c25095c595e829"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d919a74c17749ccb17beaf6405562e413cd94e98ba52ca1e64bbe7eefbd8b8"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "490e5f878c2856225e884c35927e7ea6db3c24cdb7229b72542c7526ad7ed49e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
index 5d9d0a5fecaccd133f2c69813eba5967278575ca..e6b72bd58c540f50d14a77a0ac3e6ae9ee8c44bc 100644 (file)
@@ -36,7 +36,7 @@
 use std::convert::TryFrom;
 use std::fmt;
 use std::mem;
-use thin_vec::ThinVec;
+use thin_vec::{thin_vec, ThinVec};
 
 /// A "Label" is an identifier of some point in sources,
 /// e.g. in the following code:
@@ -90,7 +90,7 @@ pub struct Path {
     pub span: Span,
     /// The segments in the path: the things separated by `::`.
     /// Global paths begin with `kw::PathRoot`.
-    pub segments: Vec<PathSegment>,
+    pub segments: ThinVec<PathSegment>,
     pub tokens: Option<LazyAttrTokenStream>,
 }
 
@@ -114,7 +114,7 @@ impl Path {
     // Convert a span and an identifier to the corresponding
     // one-segment path.
     pub fn from_ident(ident: Ident) -> Path {
-        Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
+        Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
     }
 
     pub fn is_global(&self) -> bool {
@@ -718,10 +718,10 @@ pub enum PatKind {
 
     /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
     /// The `bool` is `true` in the presence of a `..`.
-    Struct(Option<QSelf>, Path, Vec<PatField>, /* recovered */ bool),
+    Struct(Option<P<QSelf>>, Path, Vec<PatField>, /* recovered */ bool),
 
     /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
-    TupleStruct(Option<QSelf>, Path, Vec<P<Pat>>),
+    TupleStruct(Option<P<QSelf>>, Path, Vec<P<Pat>>),
 
     /// An or-pattern `A | B | C`.
     /// Invariant: `pats.len() >= 2`.
@@ -731,7 +731,7 @@ pub enum PatKind {
     /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
     /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
     /// only legally refer to associated constants.
-    Path(Option<QSelf>, Path),
+    Path(Option<P<QSelf>>, Path),
 
     /// A tuple pattern (`(a, b)`).
     Tuple(Vec<P<Pat>>),
@@ -1272,6 +1272,18 @@ pub fn is_approximately_pattern(&self) -> bool {
     }
 }
 
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct Closure {
+    pub binder: ClosureBinder,
+    pub capture_clause: CaptureBy,
+    pub asyncness: Async,
+    pub movability: Movability,
+    pub fn_decl: P<FnDecl>,
+    pub body: P<Expr>,
+    /// The span of the argument block `|...|`.
+    pub fn_decl_span: Span,
+}
+
 /// Limit types of a range (inclusive or exclusive)
 #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
 pub enum RangeLimits {
@@ -1281,6 +1293,20 @@ pub enum RangeLimits {
     Closed,
 }
 
+/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct MethodCall {
+    /// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`.
+    pub seg: PathSegment,
+    /// The receiver, e.g. `x`.
+    pub receiver: P<Expr>,
+    /// The arguments, e.g. `a, b, c`.
+    pub args: Vec<P<Expr>>,
+    /// The span of the function, without the dot and receiver e.g. `foo::<Bar,
+    /// Baz>(a, b, c)`.
+    pub span: Span,
+}
+
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum StructRest {
     /// `..x`.
@@ -1293,7 +1319,7 @@ pub enum StructRest {
 
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct StructExpr {
-    pub qself: Option<QSelf>,
+    pub qself: Option<P<QSelf>>,
     pub path: Path,
     pub fields: Vec<ExprField>,
     pub rest: StructRest,
@@ -1314,17 +1340,8 @@ pub enum ExprKind {
     /// This also represents calling the constructor of
     /// tuple-like ADTs such as tuple structs and enum variants.
     Call(P<Expr>, Vec<P<Expr>>),
-    /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
-    ///
-    /// The `PathSegment` represents the method name and its generic arguments
-    /// (within the angle brackets).
-    /// The standalone `Expr` is the receiver expression.
-    /// The vector of `Expr` is the arguments.
-    /// `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
-    /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d])`.
-    /// This `Span` is the span of the function, without the dot and receiver
-    /// (e.g. `foo(a, b)` in `x.foo(a, b)`
-    MethodCall(PathSegment, P<Expr>, Vec<P<Expr>>, Span),
+    /// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
+    MethodCall(Box<MethodCall>),
     /// A tuple (e.g., `(a, b, c, d)`).
     Tup(Vec<P<Expr>>),
     /// A binary operation (e.g., `a + b`, `a * b`).
@@ -1363,9 +1380,7 @@ pub enum ExprKind {
     /// A `match` block.
     Match(P<Expr>, Vec<Arm>),
     /// A closure (e.g., `move |a, b, c| a + b + c`).
-    ///
-    /// The final span is the span of the argument block `|...|`.
-    Closure(ClosureBinder, CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span),
+    Closure(Box<Closure>),
     /// A block (`'label: { ... }`).
     Block(P<Block>, Option<Label>),
     /// An async block (`async move { ... }`).
@@ -1403,7 +1418,7 @@ pub enum ExprKind {
     /// parameters (e.g., `foo::bar::<baz>`).
     ///
     /// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
-    Path(Option<QSelf>, Path),
+    Path(Option<P<QSelf>>, Path),
 
     /// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
     AddrOf(BorrowKind, Mutability, P<Expr>),
@@ -2006,7 +2021,7 @@ pub enum TyKind {
     /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
     ///
     /// Type parameters are stored in the `Path` itself.
-    Path(Option<QSelf>, Path),
+    Path(Option<P<QSelf>>, Path),
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
     TraitObject(GenericBounds, TraitObjectSyntax),
@@ -2138,7 +2153,7 @@ pub fn to_string(s: &[Self]) -> String {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct InlineAsmSym {
     pub id: NodeId,
-    pub qself: Option<QSelf>,
+    pub qself: Option<P<QSelf>>,
     pub path: Path,
 }
 
@@ -3031,28 +3046,28 @@ mod size_asserts {
     static_assert_size!(AssocItemKind, 32);
     static_assert_size!(Attribute, 32);
     static_assert_size!(Block, 48);
-    static_assert_size!(Expr, 104);
-    static_assert_size!(ExprKind, 72);
+    static_assert_size!(Expr, 72);
+    static_assert_size!(ExprKind, 40);
     static_assert_size!(Fn, 184);
     static_assert_size!(ForeignItem, 96);
     static_assert_size!(ForeignItemKind, 24);
     static_assert_size!(GenericArg, 24);
-    static_assert_size!(GenericBound, 88);
+    static_assert_size!(GenericBound, 72);
     static_assert_size!(Generics, 72);
-    static_assert_size!(Impl, 200);
+    static_assert_size!(Impl, 184);
     static_assert_size!(Item, 184);
     static_assert_size!(ItemKind, 112);
     static_assert_size!(Lit, 48);
     static_assert_size!(LitKind, 24);
     static_assert_size!(Local, 72);
     static_assert_size!(Param, 40);
-    static_assert_size!(Pat, 120);
-    static_assert_size!(Path, 40);
+    static_assert_size!(Pat, 88);
+    static_assert_size!(Path, 24);
     static_assert_size!(PathSegment, 24);
-    static_assert_size!(PatKind, 96);
+    static_assert_size!(PatKind, 64);
     static_assert_size!(Stmt, 32);
     static_assert_size!(StmtKind, 16);
-    static_assert_size!(Ty, 96);
-    static_assert_size!(TyKind, 72);
+    static_assert_size!(Ty, 64);
+    static_assert_size!(TyKind, 40);
     // tidy-alphabetical-end
 }
index 07f982b7e864bb3181f2917077b77a478ce7e662..09b08d5059c1c30e936ad6c2078abe2ede39449c 100644 (file)
 use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
 use crate::tokenstream::{LazyAttrTokenStream, TokenStream};
 use crate::util::comments;
-
 use rustc_data_structures::sync::WorkerLocal;
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_span::source_map::BytePos;
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
-
 use std::cell::Cell;
 use std::iter;
 #[cfg(debug_assertions)]
 use std::ops::BitXor;
 #[cfg(debug_assertions)]
 use std::sync::atomic::{AtomicU32, Ordering};
+use thin_vec::thin_vec;
 
 pub struct MarkedAttrs(GrowableBitSet<AttrId>);
 
@@ -471,12 +470,12 @@ fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
                         tokens.peek()
                     {
                         tokens.next();
-                        vec![PathSegment::from_ident(Ident::new(name, span))]
+                        thin_vec![PathSegment::from_ident(Ident::new(name, span))]
                     } else {
                         break 'arm Path::from_ident(Ident::new(name, span));
                     }
                 } else {
-                    vec![PathSegment::path_root(span)]
+                    thin_vec![PathSegment::path_root(span)]
                 };
                 loop {
                     if let Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
index 3ab8267263d116506ba99ab75cc0e7096675dfc6..ece4cb5556b47c78c8b86c28fa7eebf7dbb8722e 100644 (file)
@@ -194,7 +194,7 @@ fn visit_path(&mut self, p: &mut Path) {
         noop_visit_path(p, self);
     }
 
-    fn visit_qself(&mut self, qs: &mut Option<QSelf>) {
+    fn visit_qself(&mut self, qs: &mut Option<P<QSelf>>) {
         noop_visit_qself(qs, self);
     }
 
@@ -529,8 +529,9 @@ pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path
     visit_lazy_tts(tokens, vis);
 }
 
-pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) {
-    visit_opt(qself, |QSelf { ty, path_span, position: _ }| {
+pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<P<QSelf>>, vis: &mut T) {
+    visit_opt(qself, |qself| {
+        let QSelf { ty, path_span, position: _ } = &mut **qself;
         vis.visit_ty(ty);
         vis.visit_span(path_span);
     })
@@ -1303,12 +1304,17 @@ pub fn noop_visit_expr<T: MutVisitor>(
             vis.visit_expr(f);
             visit_exprs(args, vis);
         }
-        ExprKind::MethodCall(PathSegment { ident, id, args }, receiver, exprs, span) => {
+        ExprKind::MethodCall(box MethodCall {
+            seg: PathSegment { ident, id, args: seg_args },
+            receiver,
+            args: call_args,
+            span,
+        }) => {
             vis.visit_ident(ident);
             vis.visit_id(id);
-            visit_opt(args, |args| vis.visit_generic_args(args));
+            visit_opt(seg_args, |args| vis.visit_generic_args(args));
             vis.visit_method_receiver_expr(receiver);
-            visit_exprs(exprs, vis);
+            visit_exprs(call_args, vis);
             vis.visit_span(span);
         }
         ExprKind::Binary(_binop, lhs, rhs) => {
@@ -1353,12 +1359,20 @@ pub fn noop_visit_expr<T: MutVisitor>(
             vis.visit_expr(expr);
             arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
         }
-        ExprKind::Closure(binder, _capture_by, asyncness, _movability, decl, body, span) => {
+        ExprKind::Closure(box Closure {
+            binder,
+            capture_clause: _,
+            asyncness,
+            movability: _,
+            fn_decl,
+            body,
+            fn_decl_span,
+        }) => {
             vis.visit_closure_binder(binder);
             vis.visit_asyncness(asyncness);
-            vis.visit_fn_decl(decl);
+            vis.visit_fn_decl(fn_decl);
             vis.visit_expr(body);
-            vis.visit_span(span);
+            vis.visit_span(fn_decl_span);
         }
         ExprKind::Block(blk, label) => {
             vis.visit_block(blk);
index 6ea3db6d3037252c5a2c371e2a6dabe50aebbf26..fbb4cf43a954ccc08814d63fe49b2ec8d2063a10 100644 (file)
@@ -36,7 +36,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
             | Binary(_, _, e)
             | Box(e)
             | Break(_, Some(e))
-            | Closure(.., e, _)
             | Let(_, e, _)
             | Range(_, Some(e), _)
             | Ret(Some(e))
@@ -44,6 +43,9 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
             | Yield(Some(e)) => {
                 expr = e;
             }
+            Closure(closure) => {
+                expr = &closure.body;
+            }
             Async(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
             | TryBlock(..) | While(..) => break Some(expr),
             _ => break None,
index b40ad6f700e82e8abda0d851f2f241f830c4d2ce..30c55dffb180382b476378d48b4d07c80312bec6 100644 (file)
@@ -396,7 +396,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
             contains_exterior_struct_lit(&x)
         }
 
-        ast::ExprKind::MethodCall(_, ref receiver, _, _) => {
+        ast::ExprKind::MethodCall(box ast::MethodCall { ref receiver, .. }) => {
             // X { y: 1 }.bar(...)
             contains_exterior_struct_lit(&receiver)
         }
index da0545ce80c373f3e94ddd4c4a6c08b70333b2db..ad5a2116c424a485da6b3deeed939f6631bdbe6f 100644 (file)
@@ -798,10 +798,10 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
             visitor.visit_expr(callee_expression);
             walk_list!(visitor, visit_expr, arguments);
         }
-        ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _span) => {
-            visitor.visit_path_segment(segment);
+        ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, span: _ }) => {
+            visitor.visit_path_segment(seg);
             visitor.visit_expr(receiver);
-            walk_list!(visitor, visit_expr, arguments);
+            walk_list!(visitor, visit_expr, args);
         }
         ExprKind::Binary(_, ref left_expression, ref right_expression) => {
             visitor.visit_expr(left_expression);
@@ -842,8 +842,16 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
             visitor.visit_expr(subexpression);
             walk_list!(visitor, visit_arm, arms);
         }
-        ExprKind::Closure(ref binder, _, _, _, ref decl, ref body, _decl_span) => {
-            visitor.visit_fn(FnKind::Closure(binder, decl, body), expression.span, expression.id)
+        ExprKind::Closure(box Closure {
+            ref binder,
+            capture_clause: _,
+            asyncness: _,
+            movability: _,
+            ref fn_decl,
+            ref body,
+            fn_decl_span: _,
+        }) => {
+            visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), expression.span, expression.id)
         }
         ExprKind::Block(ref block, ref opt_label) => {
             walk_list!(visitor, visit_label, opt_label);
index 01716859a9ddf94b23d8aff4f6b8afa0372e5367..eaa5a38388afcc214214b4b4414ef1327c8dcaeb 100644 (file)
@@ -61,7 +61,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                         hir::ExprKind::Call(f, self.lower_exprs(args))
                     }
                 }
-                ExprKind::MethodCall(ref seg, ref receiver, ref args, span) => {
+                ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, span }) => {
                     let hir_seg = self.arena.alloc(self.lower_path_segment(
                         e.span,
                         seg,
@@ -172,22 +172,22 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                     };
                     self.lower_expr_await(dot_await_span, expr)
                 }
-                ExprKind::Closure(
+                ExprKind::Closure(box Closure {
                     ref binder,
                     capture_clause,
                     asyncness,
                     movability,
-                    ref decl,
+                    ref fn_decl,
                     ref body,
                     fn_decl_span,
-                ) => {
+                }) => {
                     if let Async::Yes { closure_id, .. } = asyncness {
                         self.lower_expr_async_closure(
                             binder,
                             capture_clause,
                             e.id,
                             closure_id,
-                            decl,
+                            fn_decl,
                             body,
                             fn_decl_span,
                         )
@@ -197,7 +197,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                             capture_clause,
                             e.id,
                             movability,
-                            decl,
+                            fn_decl,
                             body,
                             fn_decl_span,
                         )
@@ -1105,7 +1105,7 @@ fn is_ordinary(lower_ctx: &mut LoweringContext<'_, '_>, lhs: &Expr) -> bool {
     fn extract_tuple_struct_path<'a>(
         &mut self,
         expr: &'a Expr,
-    ) -> Option<(&'a Option<QSelf>, &'a Path)> {
+    ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
         if let ExprKind::Path(qself, path) = &expr.kind {
             // Does the path resolve to something disallowed in a tuple struct/variant pattern?
             if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
@@ -1125,7 +1125,7 @@ fn extract_tuple_struct_path<'a>(
     fn extract_unit_struct_path<'a>(
         &mut self,
         expr: &'a Expr,
-    ) -> Option<(&'a Option<QSelf>, &'a Path)> {
+    ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
         if let ExprKind::Path(qself, path) = &expr.kind {
             // Does the path resolve to something disallowed in a unit struct/variant pattern?
             if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
index 77c5ed6036e702caa2fea4bb6a3f99e7502f9540..05022c1a14c704eb34ab1b8e167df8481a340373 100644 (file)
@@ -19,8 +19,8 @@
 use rustc_span::{Span, Symbol};
 use rustc_target::spec::abi;
 use smallvec::{smallvec, SmallVec};
-
 use std::iter;
+use thin_vec::ThinVec;
 
 pub(super) struct ItemLowerer<'a, 'hir> {
     pub(super) tcx: TyCtxt<'hir>,
@@ -242,7 +242,7 @@ fn lower_item_kind(
             ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
             ItemKind::Use(ref use_tree) => {
                 // Start with an empty prefix.
-                let prefix = Path { segments: vec![], span: use_tree.span, tokens: None };
+                let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
 
                 self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
             }
index ecc2578dd2aa93bca7a8823167060e759aec19b5..e1703b0b02b0506bd1fe9358b7a88f041c2196de 100644 (file)
@@ -1208,7 +1208,7 @@ fn lower_ty(&mut self, t: &Ty, itctx: &ImplTraitContext) -> &'hir hir::Ty<'hir>
     fn lower_path_ty(
         &mut self,
         t: &Ty,
-        qself: &Option<QSelf>,
+        qself: &Option<ptr::P<QSelf>>,
         path: &Path,
         param_mode: ParamMode,
         itctx: &ImplTraitContext,
index c6955741fd4c2961be0d6b732910770783c9fbf9..83d459d899b5cff3e938b14296ce51263e3e18c0 100644 (file)
@@ -19,7 +19,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     pub(crate) fn lower_qpath(
         &mut self,
         id: NodeId,
-        qself: &Option<QSelf>,
+        qself: &Option<ptr::P<QSelf>>,
         p: &Path,
         param_mode: ParamMode,
         itctx: &ImplTraitContext,
index 86f1d6bfecd64931ba0a0382347246f5ea2ba021..1da40d2302e125b5dcfc0baa1979370f7dad4f52 100644 (file)
@@ -121,7 +121,7 @@ fn print_expr_repeat(&mut self, element: &ast::Expr, count: &ast::AnonConst) {
 
     fn print_expr_struct(
         &mut self,
-        qself: &Option<ast::QSelf>,
+        qself: &Option<P<ast::QSelf>>,
         path: &ast::Path,
         fields: &[ast::ExprField],
         rest: &ast::StructRest,
@@ -307,8 +307,13 @@ pub(super) fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline
             ast::ExprKind::Call(ref func, ref args) => {
                 self.print_expr_call(func, &args);
             }
-            ast::ExprKind::MethodCall(ref segment, ref receiver, ref args, _) => {
-                self.print_expr_method_call(segment, &receiver, &args);
+            ast::ExprKind::MethodCall(box ast::MethodCall {
+                ref seg,
+                ref receiver,
+                ref args,
+                ..
+            }) => {
+                self.print_expr_method_call(seg, &receiver, &args);
             }
             ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
                 self.print_expr_binary(op, lhs, rhs);
@@ -396,21 +401,21 @@ pub(super) fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline
                 let empty = attrs.is_empty() && arms.is_empty();
                 self.bclose(expr.span, empty);
             }
-            ast::ExprKind::Closure(
+            ast::ExprKind::Closure(box ast::Closure {
                 ref binder,
                 capture_clause,
                 asyncness,
                 movability,
-                ref decl,
+                ref fn_decl,
                 ref body,
-                _,
-            ) => {
+                fn_decl_span: _,
+            }) => {
                 self.print_closure_binder(binder);
                 self.print_movability(movability);
                 self.print_asyncness(asyncness);
                 self.print_capture_clause(capture_clause);
 
-                self.print_fn_params_and_ret(decl, true);
+                self.print_fn_params_and_ret(fn_decl, true);
                 self.space();
                 self.print_expr(body);
                 self.end(); // need to close a box
diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml
new file mode 100644 (file)
index 0000000..3477306
--- /dev/null
@@ -0,0 +1,15 @@
+[package]
+name = "rustc_baked_icu_data"
+version = "0.0.0"
+edition = "2021"
+
+[dependencies]
+icu_list = "1.0.0"
+icu_locid = "1.0.0"
+icu_provider = "1.0.1"
+icu_provider_adapters = "1.0.0"
+litemap = "0.6.0"
+zerovec = "0.9.0"
+
+[features]
+rustc_use_parallel_compiler = ['icu_provider/sync']
diff --git a/compiler/rustc_baked_icu_data/src/data/any.rs b/compiler/rustc_baked_icu_data/src/data/any.rs
new file mode 100644 (file)
index 0000000..e8e99be
--- /dev/null
@@ -0,0 +1,42 @@
+// @generated
+impl AnyProvider for BakedDataProvider {
+    fn load_any(&self, key: DataKey, req: DataRequest) -> Result<AnyResponse, DataError> {
+        const ANDLISTV1MARKER: ::icu_provider::DataKeyHash =
+            ::icu_list::provider::AndListV1Marker::KEY.hashed();
+        const COLLATIONFALLBACKSUPPLEMENTV1MARKER: ::icu_provider::DataKeyHash =
+            ::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker::KEY
+                .hashed();
+        const LOCALEFALLBACKLIKELYSUBTAGSV1MARKER: ::icu_provider::DataKeyHash =
+            ::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker::KEY
+                .hashed();
+        const LOCALEFALLBACKPARENTSV1MARKER: ::icu_provider::DataKeyHash =
+            ::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker::KEY
+                .hashed();
+        #[allow(clippy::match_single_binding)]
+        match key.hashed() {
+            ANDLISTV1MARKER => list::and_v1::DATA
+                .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
+                .copied()
+                .map(AnyPayload::from_static_ref)
+                .ok_or(DataErrorKind::MissingLocale),
+            COLLATIONFALLBACKSUPPLEMENTV1MARKER => fallback::supplement::co_v1::DATA
+                .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
+                .copied()
+                .map(AnyPayload::from_static_ref)
+                .ok_or(DataErrorKind::MissingLocale),
+            LOCALEFALLBACKLIKELYSUBTAGSV1MARKER => fallback::likelysubtags_v1::DATA
+                .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
+                .copied()
+                .map(AnyPayload::from_static_ref)
+                .ok_or(DataErrorKind::MissingLocale),
+            LOCALEFALLBACKPARENTSV1MARKER => fallback::parents_v1::DATA
+                .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
+                .copied()
+                .map(AnyPayload::from_static_ref)
+                .ok_or(DataErrorKind::MissingLocale),
+            _ => Err(DataErrorKind::MissingDataKey),
+        }
+        .map_err(|e| e.with_req(key, req))
+        .map(|payload| AnyResponse { payload: Some(payload), metadata: Default::default() })
+    }
+}
diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1.rs b/compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1.rs
new file mode 100644 (file)
index 0000000..0a90c83
--- /dev/null
@@ -0,0 +1,733 @@
+// @generated
+type DataStruct = < :: icu_provider_adapters :: fallback :: provider :: LocaleFallbackLikelySubtagsV1Marker as :: icu_provider :: DataMarker > :: Yokeable ;
+pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> =
+    litemap::LiteMap::from_sorted_store_unchecked(&[("und", UND)]);
+static UND: &DataStruct =
+    &::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1 {
+        l2s: unsafe {
+            #[allow(unused_unsafe)]
+            ::zerovec::ZeroMap::from_parts_unchecked(
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        97u8, 98u8, 0u8, 97u8, 98u8, 113u8, 97u8, 100u8, 112u8, 97u8, 100u8, 121u8,
+                        97u8, 101u8, 0u8, 97u8, 101u8, 98u8, 97u8, 104u8, 111u8, 97u8, 106u8,
+                        116u8, 97u8, 107u8, 107u8, 97u8, 108u8, 116u8, 97u8, 109u8, 0u8, 97u8,
+                        112u8, 99u8, 97u8, 112u8, 100u8, 97u8, 114u8, 0u8, 97u8, 114u8, 99u8, 97u8,
+                        114u8, 113u8, 97u8, 114u8, 115u8, 97u8, 114u8, 121u8, 97u8, 114u8, 122u8,
+                        97u8, 115u8, 0u8, 97u8, 115u8, 101u8, 97u8, 118u8, 0u8, 97u8, 118u8, 108u8,
+                        97u8, 119u8, 97u8, 98u8, 97u8, 0u8, 98u8, 97u8, 108u8, 98u8, 97u8, 112u8,
+                        98u8, 97u8, 120u8, 98u8, 99u8, 113u8, 98u8, 101u8, 0u8, 98u8, 101u8, 106u8,
+                        98u8, 102u8, 113u8, 98u8, 102u8, 116u8, 98u8, 102u8, 121u8, 98u8, 103u8,
+                        0u8, 98u8, 103u8, 99u8, 98u8, 103u8, 110u8, 98u8, 103u8, 120u8, 98u8,
+                        104u8, 98u8, 98u8, 104u8, 105u8, 98u8, 104u8, 111u8, 98u8, 106u8, 105u8,
+                        98u8, 106u8, 106u8, 98u8, 108u8, 116u8, 98u8, 110u8, 0u8, 98u8, 111u8, 0u8,
+                        98u8, 112u8, 121u8, 98u8, 113u8, 105u8, 98u8, 114u8, 97u8, 98u8, 114u8,
+                        104u8, 98u8, 114u8, 120u8, 98u8, 115u8, 113u8, 98u8, 115u8, 116u8, 98u8,
+                        116u8, 118u8, 98u8, 117u8, 97u8, 98u8, 121u8, 110u8, 99u8, 99u8, 112u8,
+                        99u8, 101u8, 0u8, 99u8, 104u8, 109u8, 99u8, 104u8, 114u8, 99u8, 106u8,
+                        97u8, 99u8, 106u8, 109u8, 99u8, 107u8, 98u8, 99u8, 109u8, 103u8, 99u8,
+                        111u8, 112u8, 99u8, 114u8, 0u8, 99u8, 114u8, 104u8, 99u8, 114u8, 107u8,
+                        99u8, 114u8, 108u8, 99u8, 115u8, 119u8, 99u8, 116u8, 100u8, 99u8, 117u8,
+                        0u8, 99u8, 118u8, 0u8, 100u8, 97u8, 114u8, 100u8, 99u8, 99u8, 100u8, 103u8,
+                        108u8, 100u8, 109u8, 102u8, 100u8, 111u8, 105u8, 100u8, 114u8, 104u8,
+                        100u8, 114u8, 115u8, 100u8, 116u8, 121u8, 100u8, 118u8, 0u8, 100u8, 122u8,
+                        0u8, 101u8, 103u8, 121u8, 101u8, 107u8, 121u8, 101u8, 108u8, 0u8, 101u8,
+                        115u8, 103u8, 101u8, 116u8, 116u8, 102u8, 97u8, 0u8, 102u8, 105u8, 97u8,
+                        102u8, 117u8, 98u8, 103u8, 97u8, 110u8, 103u8, 98u8, 109u8, 103u8, 98u8,
+                        122u8, 103u8, 101u8, 122u8, 103u8, 103u8, 110u8, 103u8, 106u8, 107u8,
+                        103u8, 106u8, 117u8, 103u8, 108u8, 107u8, 103u8, 109u8, 118u8, 103u8,
+                        111u8, 102u8, 103u8, 111u8, 109u8, 103u8, 111u8, 110u8, 103u8, 111u8,
+                        116u8, 103u8, 114u8, 99u8, 103u8, 114u8, 116u8, 103u8, 117u8, 0u8, 103u8,
+                        118u8, 114u8, 103u8, 119u8, 99u8, 103u8, 119u8, 116u8, 104u8, 97u8, 107u8,
+                        104u8, 97u8, 122u8, 104u8, 100u8, 121u8, 104u8, 101u8, 0u8, 104u8, 105u8,
+                        0u8, 104u8, 108u8, 117u8, 104u8, 109u8, 100u8, 104u8, 110u8, 100u8, 104u8,
+                        110u8, 101u8, 104u8, 110u8, 106u8, 104u8, 110u8, 111u8, 104u8, 111u8, 99u8,
+                        104u8, 111u8, 106u8, 104u8, 115u8, 110u8, 104u8, 121u8, 0u8, 105u8, 105u8,
+                        0u8, 105u8, 110u8, 104u8, 105u8, 117u8, 0u8, 105u8, 119u8, 0u8, 106u8,
+                        97u8, 0u8, 106u8, 105u8, 0u8, 106u8, 109u8, 108u8, 107u8, 97u8, 0u8, 107u8,
+                        97u8, 97u8, 107u8, 97u8, 119u8, 107u8, 98u8, 100u8, 107u8, 98u8, 121u8,
+                        107u8, 100u8, 116u8, 107u8, 102u8, 114u8, 107u8, 102u8, 121u8, 107u8,
+                        104u8, 98u8, 107u8, 104u8, 110u8, 107u8, 104u8, 116u8, 107u8, 104u8, 119u8,
+                        107u8, 106u8, 103u8, 107u8, 107u8, 0u8, 107u8, 109u8, 0u8, 107u8, 110u8,
+                        0u8, 107u8, 111u8, 0u8, 107u8, 111u8, 105u8, 107u8, 111u8, 107u8, 107u8,
+                        113u8, 121u8, 107u8, 114u8, 99u8, 107u8, 114u8, 117u8, 107u8, 115u8, 0u8,
+                        107u8, 116u8, 98u8, 107u8, 117u8, 109u8, 107u8, 118u8, 0u8, 107u8, 118u8,
+                        120u8, 107u8, 120u8, 99u8, 107u8, 120u8, 108u8, 107u8, 120u8, 109u8, 107u8,
+                        120u8, 112u8, 107u8, 121u8, 0u8, 107u8, 122u8, 104u8, 108u8, 97u8, 98u8,
+                        108u8, 97u8, 100u8, 108u8, 97u8, 104u8, 108u8, 98u8, 101u8, 108u8, 99u8,
+                        112u8, 108u8, 101u8, 112u8, 108u8, 101u8, 122u8, 108u8, 105u8, 102u8,
+                        108u8, 105u8, 115u8, 108u8, 107u8, 105u8, 108u8, 109u8, 110u8, 108u8,
+                        111u8, 0u8, 108u8, 114u8, 99u8, 108u8, 117u8, 122u8, 108u8, 119u8, 108u8,
+                        108u8, 122u8, 104u8, 109u8, 97u8, 103u8, 109u8, 97u8, 105u8, 109u8, 100u8,
+                        101u8, 109u8, 100u8, 102u8, 109u8, 100u8, 120u8, 109u8, 102u8, 97u8, 109u8,
+                        103u8, 112u8, 109u8, 107u8, 0u8, 109u8, 107u8, 105u8, 109u8, 108u8, 0u8,
+                        109u8, 110u8, 0u8, 109u8, 110u8, 105u8, 109u8, 110u8, 119u8, 109u8, 114u8,
+                        0u8, 109u8, 114u8, 100u8, 109u8, 114u8, 106u8, 109u8, 114u8, 111u8, 109u8,
+                        116u8, 114u8, 109u8, 118u8, 121u8, 109u8, 119u8, 114u8, 109u8, 119u8,
+                        119u8, 109u8, 121u8, 0u8, 109u8, 121u8, 109u8, 109u8, 121u8, 118u8, 109u8,
+                        121u8, 122u8, 109u8, 122u8, 110u8, 110u8, 97u8, 110u8, 110u8, 101u8, 0u8,
+                        110u8, 101u8, 119u8, 110u8, 110u8, 112u8, 110u8, 111u8, 100u8, 110u8,
+                        111u8, 101u8, 110u8, 111u8, 110u8, 110u8, 113u8, 111u8, 110u8, 115u8,
+                        107u8, 110u8, 115u8, 116u8, 111u8, 106u8, 0u8, 111u8, 106u8, 115u8, 111u8,
+                        114u8, 0u8, 111u8, 114u8, 117u8, 111u8, 115u8, 0u8, 111u8, 115u8, 97u8,
+                        111u8, 116u8, 97u8, 111u8, 116u8, 107u8, 111u8, 117u8, 105u8, 112u8, 97u8,
+                        0u8, 112u8, 97u8, 108u8, 112u8, 101u8, 111u8, 112u8, 104u8, 108u8, 112u8,
+                        104u8, 110u8, 112u8, 107u8, 97u8, 112u8, 110u8, 116u8, 112u8, 112u8, 97u8,
+                        112u8, 114u8, 97u8, 112u8, 114u8, 100u8, 112u8, 115u8, 0u8, 114u8, 97u8,
+                        106u8, 114u8, 104u8, 103u8, 114u8, 105u8, 102u8, 114u8, 106u8, 115u8,
+                        114u8, 107u8, 116u8, 114u8, 109u8, 116u8, 114u8, 117u8, 0u8, 114u8, 117u8,
+                        101u8, 114u8, 121u8, 117u8, 115u8, 97u8, 0u8, 115u8, 97u8, 104u8, 115u8,
+                        97u8, 116u8, 115u8, 97u8, 122u8, 115u8, 99u8, 107u8, 115u8, 99u8, 108u8,
+                        115u8, 100u8, 0u8, 115u8, 100u8, 104u8, 115u8, 103u8, 97u8, 115u8, 103u8,
+                        119u8, 115u8, 104u8, 105u8, 115u8, 104u8, 110u8, 115u8, 104u8, 117u8,
+                        115u8, 105u8, 0u8, 115u8, 107u8, 114u8, 115u8, 109u8, 112u8, 115u8, 111u8,
+                        103u8, 115u8, 111u8, 117u8, 115u8, 114u8, 0u8, 115u8, 114u8, 98u8, 115u8,
+                        114u8, 120u8, 115u8, 119u8, 98u8, 115u8, 119u8, 118u8, 115u8, 121u8, 108u8,
+                        115u8, 121u8, 114u8, 116u8, 97u8, 0u8, 116u8, 97u8, 106u8, 116u8, 99u8,
+                        121u8, 116u8, 100u8, 100u8, 116u8, 100u8, 103u8, 116u8, 100u8, 104u8,
+                        116u8, 101u8, 0u8, 116u8, 103u8, 0u8, 116u8, 104u8, 0u8, 116u8, 104u8,
+                        108u8, 116u8, 104u8, 113u8, 116u8, 104u8, 114u8, 116u8, 105u8, 0u8, 116u8,
+                        105u8, 103u8, 116u8, 107u8, 116u8, 116u8, 114u8, 119u8, 116u8, 115u8,
+                        100u8, 116u8, 115u8, 102u8, 116u8, 115u8, 106u8, 116u8, 116u8, 0u8, 116u8,
+                        116u8, 115u8, 116u8, 120u8, 103u8, 116u8, 120u8, 111u8, 116u8, 121u8,
+                        118u8, 117u8, 100u8, 105u8, 117u8, 100u8, 109u8, 117u8, 103u8, 0u8, 117u8,
+                        103u8, 97u8, 117u8, 107u8, 0u8, 117u8, 110u8, 114u8, 117u8, 110u8, 120u8,
+                        117u8, 114u8, 0u8, 118u8, 97u8, 105u8, 119u8, 97u8, 108u8, 119u8, 98u8,
+                        113u8, 119u8, 98u8, 114u8, 119u8, 110u8, 105u8, 119u8, 115u8, 103u8, 119u8,
+                        116u8, 109u8, 119u8, 117u8, 117u8, 120u8, 99u8, 111u8, 120u8, 99u8, 114u8,
+                        120u8, 108u8, 99u8, 120u8, 108u8, 100u8, 120u8, 109u8, 102u8, 120u8, 109u8,
+                        110u8, 120u8, 109u8, 114u8, 120u8, 110u8, 97u8, 120u8, 110u8, 114u8, 120u8,
+                        112u8, 114u8, 120u8, 115u8, 97u8, 120u8, 115u8, 114u8, 121u8, 105u8, 0u8,
+                        121u8, 117u8, 101u8, 122u8, 100u8, 106u8, 122u8, 103u8, 104u8, 122u8,
+                        104u8, 0u8, 122u8, 104u8, 120u8, 122u8, 107u8, 116u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 84u8, 105u8, 98u8,
+                        116u8, 67u8, 121u8, 114u8, 108u8, 65u8, 118u8, 115u8, 116u8, 65u8, 114u8,
+                        97u8, 98u8, 65u8, 104u8, 111u8, 109u8, 65u8, 114u8, 97u8, 98u8, 88u8,
+                        115u8, 117u8, 120u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8, 105u8,
+                        65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8,
+                        65u8, 114u8, 109u8, 105u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8,
+                        98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 66u8, 101u8, 110u8,
+                        103u8, 83u8, 103u8, 110u8, 119u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8,
+                        97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 65u8,
+                        114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 66u8, 97u8, 109u8, 117u8,
+                        69u8, 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, 97u8,
+                        98u8, 84u8, 97u8, 109u8, 108u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8,
+                        118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, 118u8, 97u8, 65u8,
+                        114u8, 97u8, 98u8, 71u8, 114u8, 101u8, 107u8, 68u8, 101u8, 118u8, 97u8,
+                        68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 69u8, 116u8, 104u8,
+                        105u8, 68u8, 101u8, 118u8, 97u8, 84u8, 97u8, 118u8, 116u8, 66u8, 101u8,
+                        110u8, 103u8, 84u8, 105u8, 98u8, 116u8, 66u8, 101u8, 110u8, 103u8, 65u8,
+                        114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 68u8,
+                        101u8, 118u8, 97u8, 66u8, 97u8, 115u8, 115u8, 69u8, 116u8, 104u8, 105u8,
+                        68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8,
+                        105u8, 67u8, 97u8, 107u8, 109u8, 67u8, 121u8, 114u8, 108u8, 67u8, 121u8,
+                        114u8, 108u8, 67u8, 104u8, 101u8, 114u8, 65u8, 114u8, 97u8, 98u8, 67u8,
+                        104u8, 97u8, 109u8, 65u8, 114u8, 97u8, 98u8, 83u8, 111u8, 121u8, 111u8,
+                        67u8, 111u8, 112u8, 116u8, 67u8, 97u8, 110u8, 115u8, 67u8, 121u8, 114u8,
+                        108u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8,
+                        110u8, 115u8, 80u8, 97u8, 117u8, 99u8, 67u8, 121u8, 114u8, 108u8, 67u8,
+                        121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, 97u8, 98u8,
+                        65u8, 114u8, 97u8, 98u8, 77u8, 101u8, 100u8, 102u8, 68u8, 101u8, 118u8,
+                        97u8, 77u8, 111u8, 110u8, 103u8, 69u8, 116u8, 104u8, 105u8, 68u8, 101u8,
+                        118u8, 97u8, 84u8, 104u8, 97u8, 97u8, 84u8, 105u8, 98u8, 116u8, 69u8,
+                        103u8, 121u8, 112u8, 75u8, 97u8, 108u8, 105u8, 71u8, 114u8, 101u8, 107u8,
+                        71u8, 111u8, 110u8, 109u8, 73u8, 116u8, 97u8, 108u8, 65u8, 114u8, 97u8,
+                        98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8,
+                        115u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 69u8, 116u8,
+                        104u8, 105u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 65u8,
+                        114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8,
+                        69u8, 116u8, 104u8, 105u8, 68u8, 101u8, 118u8, 97u8, 84u8, 101u8, 108u8,
+                        117u8, 71u8, 111u8, 116u8, 104u8, 67u8, 112u8, 114u8, 116u8, 66u8, 101u8,
+                        110u8, 103u8, 71u8, 117u8, 106u8, 114u8, 68u8, 101u8, 118u8, 97u8, 65u8,
+                        114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 65u8,
+                        114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, 72u8, 101u8, 98u8, 114u8,
+                        68u8, 101u8, 118u8, 97u8, 72u8, 108u8, 117u8, 119u8, 80u8, 108u8, 114u8,
+                        100u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 109u8,
+                        110u8, 112u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 68u8,
+                        101u8, 118u8, 97u8, 72u8, 97u8, 110u8, 115u8, 65u8, 114u8, 109u8, 110u8,
+                        89u8, 105u8, 105u8, 105u8, 67u8, 121u8, 114u8, 108u8, 67u8, 97u8, 110u8,
+                        115u8, 72u8, 101u8, 98u8, 114u8, 74u8, 112u8, 97u8, 110u8, 72u8, 101u8,
+                        98u8, 114u8, 68u8, 101u8, 118u8, 97u8, 71u8, 101u8, 111u8, 114u8, 67u8,
+                        121u8, 114u8, 108u8, 75u8, 97u8, 119u8, 105u8, 67u8, 121u8, 114u8, 108u8,
+                        65u8, 114u8, 97u8, 98u8, 84u8, 104u8, 97u8, 105u8, 68u8, 101u8, 118u8,
+                        97u8, 68u8, 101u8, 118u8, 97u8, 84u8, 97u8, 108u8, 117u8, 68u8, 101u8,
+                        118u8, 97u8, 77u8, 121u8, 109u8, 114u8, 65u8, 114u8, 97u8, 98u8, 76u8,
+                        97u8, 111u8, 111u8, 67u8, 121u8, 114u8, 108u8, 75u8, 104u8, 109u8, 114u8,
+                        75u8, 110u8, 100u8, 97u8, 75u8, 111u8, 114u8, 101u8, 67u8, 121u8, 114u8,
+                        108u8, 68u8, 101u8, 118u8, 97u8, 69u8, 116u8, 104u8, 105u8, 67u8, 121u8,
+                        114u8, 108u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 69u8,
+                        116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8,
+                        65u8, 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, 68u8, 101u8, 118u8,
+                        97u8, 84u8, 104u8, 97u8, 105u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8,
+                        114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 76u8, 105u8, 110u8, 97u8, 72u8,
+                        101u8, 98u8, 114u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8,
+                        84u8, 104u8, 97u8, 105u8, 76u8, 101u8, 112u8, 99u8, 67u8, 121u8, 114u8,
+                        108u8, 68u8, 101u8, 118u8, 97u8, 76u8, 105u8, 115u8, 117u8, 65u8, 114u8,
+                        97u8, 98u8, 84u8, 101u8, 108u8, 117u8, 76u8, 97u8, 111u8, 111u8, 65u8,
+                        114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 84u8, 104u8, 97u8, 105u8, 72u8,
+                        97u8, 110u8, 115u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8,
+                        65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8,
+                        105u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8,
+                        114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 77u8, 108u8, 121u8, 109u8, 67u8,
+                        121u8, 114u8, 108u8, 66u8, 101u8, 110u8, 103u8, 77u8, 121u8, 109u8, 114u8,
+                        68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8,
+                        108u8, 77u8, 114u8, 111u8, 111u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8,
+                        97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 109u8, 110u8, 112u8, 77u8,
+                        121u8, 109u8, 114u8, 69u8, 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8,
+                        77u8, 97u8, 110u8, 100u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8,
+                        115u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 87u8, 99u8,
+                        104u8, 111u8, 76u8, 97u8, 110u8, 97u8, 68u8, 101u8, 118u8, 97u8, 82u8,
+                        117u8, 110u8, 114u8, 78u8, 107u8, 111u8, 111u8, 67u8, 97u8, 110u8, 115u8,
+                        84u8, 110u8, 115u8, 97u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, 110u8,
+                        115u8, 79u8, 114u8, 121u8, 97u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8,
+                        114u8, 108u8, 79u8, 115u8, 103u8, 101u8, 65u8, 114u8, 97u8, 98u8, 79u8,
+                        114u8, 107u8, 104u8, 79u8, 117u8, 103u8, 114u8, 71u8, 117u8, 114u8, 117u8,
+                        80u8, 104u8, 108u8, 105u8, 88u8, 112u8, 101u8, 111u8, 65u8, 114u8, 97u8,
+                        98u8, 80u8, 104u8, 110u8, 120u8, 66u8, 114u8, 97u8, 104u8, 71u8, 114u8,
+                        101u8, 107u8, 68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 97u8, 114u8, 65u8,
+                        114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 82u8,
+                        111u8, 104u8, 103u8, 84u8, 102u8, 110u8, 103u8, 68u8, 101u8, 118u8, 97u8,
+                        66u8, 101u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8,
+                        108u8, 67u8, 121u8, 114u8, 108u8, 75u8, 97u8, 110u8, 97u8, 68u8, 101u8,
+                        118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 79u8, 108u8, 99u8, 107u8, 83u8,
+                        97u8, 117u8, 114u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8,
+                        65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 79u8, 103u8, 97u8, 109u8,
+                        69u8, 116u8, 104u8, 105u8, 84u8, 102u8, 110u8, 103u8, 77u8, 121u8, 109u8,
+                        114u8, 65u8, 114u8, 97u8, 98u8, 83u8, 105u8, 110u8, 104u8, 65u8, 114u8,
+                        97u8, 98u8, 83u8, 97u8, 109u8, 114u8, 83u8, 111u8, 103u8, 100u8, 84u8,
+                        104u8, 97u8, 105u8, 67u8, 121u8, 114u8, 108u8, 83u8, 111u8, 114u8, 97u8,
+                        68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8,
+                        97u8, 66u8, 101u8, 110u8, 103u8, 83u8, 121u8, 114u8, 99u8, 84u8, 97u8,
+                        109u8, 108u8, 68u8, 101u8, 118u8, 97u8, 75u8, 110u8, 100u8, 97u8, 84u8,
+                        97u8, 108u8, 101u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8,
+                        84u8, 101u8, 108u8, 117u8, 67u8, 121u8, 114u8, 108u8, 84u8, 104u8, 97u8,
+                        105u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8,
+                        118u8, 97u8, 69u8, 116u8, 104u8, 105u8, 69u8, 116u8, 104u8, 105u8, 68u8,
+                        101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 71u8, 114u8, 101u8, 107u8,
+                        68u8, 101u8, 118u8, 97u8, 84u8, 105u8, 98u8, 116u8, 67u8, 121u8, 114u8,
+                        108u8, 84u8, 104u8, 97u8, 105u8, 84u8, 97u8, 110u8, 103u8, 84u8, 111u8,
+                        116u8, 111u8, 67u8, 121u8, 114u8, 108u8, 65u8, 103u8, 104u8, 98u8, 67u8,
+                        121u8, 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 85u8, 103u8, 97u8, 114u8,
+                        67u8, 121u8, 114u8, 108u8, 66u8, 101u8, 110u8, 103u8, 66u8, 101u8, 110u8,
+                        103u8, 65u8, 114u8, 97u8, 98u8, 86u8, 97u8, 105u8, 105u8, 69u8, 116u8,
+                        104u8, 105u8, 84u8, 101u8, 108u8, 117u8, 68u8, 101u8, 118u8, 97u8, 65u8,
+                        114u8, 97u8, 98u8, 71u8, 111u8, 110u8, 103u8, 68u8, 101u8, 118u8, 97u8,
+                        72u8, 97u8, 110u8, 115u8, 67u8, 104u8, 114u8, 115u8, 67u8, 97u8, 114u8,
+                        105u8, 76u8, 121u8, 99u8, 105u8, 76u8, 121u8, 100u8, 105u8, 71u8, 101u8,
+                        111u8, 114u8, 77u8, 97u8, 110u8, 105u8, 77u8, 101u8, 114u8, 99u8, 78u8,
+                        97u8, 114u8, 98u8, 68u8, 101u8, 118u8, 97u8, 80u8, 114u8, 116u8, 105u8,
+                        83u8, 97u8, 114u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 101u8, 98u8,
+                        114u8, 72u8, 97u8, 110u8, 116u8, 65u8, 114u8, 97u8, 98u8, 84u8, 102u8,
+                        110u8, 103u8, 72u8, 97u8, 110u8, 115u8, 78u8, 115u8, 104u8, 117u8, 75u8,
+                        105u8, 116u8, 115u8,
+                    ])
+                },
+            )
+        },
+        lr2s: unsafe {
+            #[allow(unused_unsafe)]
+            ::zerovec::ZeroMap2d::from_parts_unchecked(
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        97u8, 122u8, 0u8, 104u8, 97u8, 0u8, 107u8, 107u8, 0u8, 107u8, 117u8, 0u8,
+                        107u8, 121u8, 0u8, 109u8, 97u8, 110u8, 109u8, 110u8, 0u8, 109u8, 115u8,
+                        0u8, 112u8, 97u8, 0u8, 114u8, 105u8, 102u8, 115u8, 100u8, 0u8, 115u8,
+                        114u8, 0u8, 116u8, 103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8,
+                        117u8, 122u8, 0u8, 121u8, 117u8, 101u8, 122u8, 104u8, 0u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        3u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 10u8, 0u8, 0u8,
+                        0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 15u8,
+                        0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+                        0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 26u8,
+                        0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8, 29u8, 0u8, 0u8, 0u8, 44u8, 0u8, 0u8,
+                        0u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        73u8, 81u8, 0u8, 73u8, 82u8, 0u8, 82u8, 85u8, 0u8, 67u8, 77u8, 0u8, 83u8,
+                        68u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 73u8, 82u8, 0u8, 77u8, 78u8,
+                        0u8, 76u8, 66u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 71u8, 78u8, 0u8,
+                        67u8, 78u8, 0u8, 67u8, 67u8, 0u8, 80u8, 75u8, 0u8, 78u8, 76u8, 0u8, 73u8,
+                        78u8, 0u8, 77u8, 69u8, 0u8, 82u8, 79u8, 0u8, 82u8, 85u8, 0u8, 84u8, 82u8,
+                        0u8, 80u8, 75u8, 0u8, 75u8, 90u8, 0u8, 77u8, 78u8, 0u8, 78u8, 80u8, 0u8,
+                        65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 67u8, 78u8, 0u8, 65u8, 85u8, 0u8, 66u8,
+                        78u8, 0u8, 71u8, 66u8, 0u8, 71u8, 70u8, 0u8, 72u8, 75u8, 0u8, 73u8, 68u8,
+                        0u8, 77u8, 79u8, 0u8, 80u8, 65u8, 0u8, 80u8, 70u8, 0u8, 80u8, 72u8, 0u8,
+                        83u8, 82u8, 0u8, 84u8, 72u8, 0u8, 84u8, 87u8, 0u8, 85u8, 83u8, 0u8, 86u8,
+                        78u8, 0u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8,
+                        108u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8,
+                        98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8,
+                        98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, 116u8,
+                        110u8, 78u8, 107u8, 111u8, 111u8, 77u8, 111u8, 110u8, 103u8, 65u8, 114u8,
+                        97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, 116u8, 110u8, 68u8, 101u8,
+                        118u8, 97u8, 76u8, 97u8, 116u8, 110u8, 76u8, 97u8, 116u8, 110u8, 76u8,
+                        97u8, 116u8, 110u8, 76u8, 97u8, 116u8, 110u8, 65u8, 114u8, 97u8, 98u8,
+                        67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, 118u8,
+                        97u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 72u8, 97u8,
+                        110u8, 115u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8,
+                        97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8,
+                        72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8,
+                        116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8,
+                        110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8,
+                        97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8,
+                    ])
+                },
+            )
+        },
+        l2r: unsafe {
+            #[allow(unused_unsafe)]
+            ::zerovec::ZeroMap::from_parts_unchecked(
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        97u8, 97u8, 0u8, 97u8, 98u8, 0u8, 97u8, 98u8, 114u8, 97u8, 99u8, 101u8,
+                        97u8, 99u8, 104u8, 97u8, 100u8, 97u8, 97u8, 100u8, 112u8, 97u8, 100u8,
+                        121u8, 97u8, 101u8, 0u8, 97u8, 101u8, 98u8, 97u8, 102u8, 0u8, 97u8, 103u8,
+                        113u8, 97u8, 104u8, 111u8, 97u8, 106u8, 116u8, 97u8, 107u8, 0u8, 97u8,
+                        107u8, 107u8, 97u8, 108u8, 110u8, 97u8, 108u8, 116u8, 97u8, 109u8, 0u8,
+                        97u8, 109u8, 111u8, 97u8, 110u8, 0u8, 97u8, 110u8, 110u8, 97u8, 111u8,
+                        122u8, 97u8, 112u8, 100u8, 97u8, 114u8, 0u8, 97u8, 114u8, 99u8, 97u8,
+                        114u8, 110u8, 97u8, 114u8, 111u8, 97u8, 114u8, 113u8, 97u8, 114u8, 115u8,
+                        97u8, 114u8, 121u8, 97u8, 114u8, 122u8, 97u8, 115u8, 0u8, 97u8, 115u8,
+                        97u8, 97u8, 115u8, 101u8, 97u8, 115u8, 116u8, 97u8, 116u8, 106u8, 97u8,
+                        118u8, 0u8, 97u8, 119u8, 97u8, 97u8, 121u8, 0u8, 97u8, 122u8, 0u8, 98u8,
+                        97u8, 0u8, 98u8, 97u8, 108u8, 98u8, 97u8, 110u8, 98u8, 97u8, 112u8, 98u8,
+                        97u8, 114u8, 98u8, 97u8, 115u8, 98u8, 97u8, 120u8, 98u8, 98u8, 99u8, 98u8,
+                        98u8, 106u8, 98u8, 99u8, 105u8, 98u8, 101u8, 0u8, 98u8, 101u8, 106u8, 98u8,
+                        101u8, 109u8, 98u8, 101u8, 119u8, 98u8, 101u8, 122u8, 98u8, 102u8, 100u8,
+                        98u8, 102u8, 113u8, 98u8, 102u8, 116u8, 98u8, 102u8, 121u8, 98u8, 103u8,
+                        0u8, 98u8, 103u8, 99u8, 98u8, 103u8, 110u8, 98u8, 103u8, 120u8, 98u8,
+                        104u8, 98u8, 98u8, 104u8, 105u8, 98u8, 104u8, 111u8, 98u8, 105u8, 0u8,
+                        98u8, 105u8, 107u8, 98u8, 105u8, 110u8, 98u8, 106u8, 106u8, 98u8, 106u8,
+                        110u8, 98u8, 106u8, 116u8, 98u8, 107u8, 109u8, 98u8, 107u8, 117u8, 98u8,
+                        108u8, 97u8, 98u8, 108u8, 103u8, 98u8, 108u8, 116u8, 98u8, 109u8, 0u8,
+                        98u8, 109u8, 113u8, 98u8, 110u8, 0u8, 98u8, 111u8, 0u8, 98u8, 112u8, 121u8,
+                        98u8, 113u8, 105u8, 98u8, 113u8, 118u8, 98u8, 114u8, 0u8, 98u8, 114u8,
+                        97u8, 98u8, 114u8, 104u8, 98u8, 114u8, 120u8, 98u8, 115u8, 0u8, 98u8,
+                        115u8, 113u8, 98u8, 115u8, 115u8, 98u8, 116u8, 111u8, 98u8, 116u8, 118u8,
+                        98u8, 117u8, 97u8, 98u8, 117u8, 99u8, 98u8, 117u8, 103u8, 98u8, 117u8,
+                        109u8, 98u8, 118u8, 98u8, 98u8, 121u8, 110u8, 98u8, 121u8, 118u8, 98u8,
+                        122u8, 101u8, 99u8, 97u8, 0u8, 99u8, 97u8, 100u8, 99u8, 99u8, 104u8, 99u8,
+                        99u8, 112u8, 99u8, 101u8, 0u8, 99u8, 101u8, 98u8, 99u8, 103u8, 103u8, 99u8,
+                        104u8, 0u8, 99u8, 104u8, 107u8, 99u8, 104u8, 109u8, 99u8, 104u8, 111u8,
+                        99u8, 104u8, 112u8, 99u8, 104u8, 114u8, 99u8, 105u8, 99u8, 99u8, 106u8,
+                        97u8, 99u8, 106u8, 109u8, 99u8, 107u8, 98u8, 99u8, 108u8, 99u8, 99u8,
+                        109u8, 103u8, 99u8, 111u8, 0u8, 99u8, 111u8, 112u8, 99u8, 112u8, 115u8,
+                        99u8, 114u8, 0u8, 99u8, 114u8, 103u8, 99u8, 114u8, 104u8, 99u8, 114u8,
+                        107u8, 99u8, 114u8, 108u8, 99u8, 114u8, 115u8, 99u8, 115u8, 0u8, 99u8,
+                        115u8, 98u8, 99u8, 115u8, 119u8, 99u8, 116u8, 100u8, 99u8, 117u8, 0u8,
+                        99u8, 118u8, 0u8, 99u8, 121u8, 0u8, 100u8, 97u8, 0u8, 100u8, 97u8, 102u8,
+                        100u8, 97u8, 107u8, 100u8, 97u8, 114u8, 100u8, 97u8, 118u8, 100u8, 99u8,
+                        99u8, 100u8, 101u8, 0u8, 100u8, 101u8, 110u8, 100u8, 103u8, 114u8, 100u8,
+                        106u8, 101u8, 100u8, 109u8, 102u8, 100u8, 110u8, 106u8, 100u8, 111u8,
+                        105u8, 100u8, 114u8, 104u8, 100u8, 115u8, 98u8, 100u8, 116u8, 109u8, 100u8,
+                        116u8, 112u8, 100u8, 116u8, 121u8, 100u8, 117u8, 97u8, 100u8, 118u8, 0u8,
+                        100u8, 121u8, 111u8, 100u8, 121u8, 117u8, 100u8, 122u8, 0u8, 101u8, 98u8,
+                        117u8, 101u8, 101u8, 0u8, 101u8, 102u8, 105u8, 101u8, 103u8, 108u8, 101u8,
+                        103u8, 121u8, 101u8, 107u8, 121u8, 101u8, 108u8, 0u8, 101u8, 110u8, 0u8,
+                        101u8, 111u8, 0u8, 101u8, 115u8, 0u8, 101u8, 115u8, 103u8, 101u8, 115u8,
+                        117u8, 101u8, 116u8, 0u8, 101u8, 116u8, 116u8, 101u8, 117u8, 0u8, 101u8,
+                        119u8, 111u8, 101u8, 120u8, 116u8, 102u8, 97u8, 0u8, 102u8, 97u8, 110u8,
+                        102u8, 102u8, 0u8, 102u8, 102u8, 109u8, 102u8, 105u8, 0u8, 102u8, 105u8,
+                        97u8, 102u8, 105u8, 108u8, 102u8, 105u8, 116u8, 102u8, 106u8, 0u8, 102u8,
+                        111u8, 0u8, 102u8, 111u8, 110u8, 102u8, 114u8, 0u8, 102u8, 114u8, 99u8,
+                        102u8, 114u8, 112u8, 102u8, 114u8, 114u8, 102u8, 114u8, 115u8, 102u8,
+                        117u8, 98u8, 102u8, 117u8, 100u8, 102u8, 117u8, 102u8, 102u8, 117u8, 113u8,
+                        102u8, 117u8, 114u8, 102u8, 117u8, 118u8, 102u8, 118u8, 114u8, 102u8,
+                        121u8, 0u8, 103u8, 97u8, 0u8, 103u8, 97u8, 97u8, 103u8, 97u8, 103u8, 103u8,
+                        97u8, 110u8, 103u8, 97u8, 121u8, 103u8, 98u8, 109u8, 103u8, 98u8, 122u8,
+                        103u8, 99u8, 114u8, 103u8, 100u8, 0u8, 103u8, 101u8, 122u8, 103u8, 103u8,
+                        110u8, 103u8, 105u8, 108u8, 103u8, 106u8, 107u8, 103u8, 106u8, 117u8,
+                        103u8, 108u8, 0u8, 103u8, 108u8, 107u8, 103u8, 110u8, 0u8, 103u8, 111u8,
+                        109u8, 103u8, 111u8, 110u8, 103u8, 111u8, 114u8, 103u8, 111u8, 115u8,
+                        103u8, 111u8, 116u8, 103u8, 114u8, 99u8, 103u8, 114u8, 116u8, 103u8, 115u8,
+                        119u8, 103u8, 117u8, 0u8, 103u8, 117u8, 98u8, 103u8, 117u8, 99u8, 103u8,
+                        117u8, 114u8, 103u8, 117u8, 122u8, 103u8, 118u8, 0u8, 103u8, 118u8, 114u8,
+                        103u8, 119u8, 105u8, 104u8, 97u8, 0u8, 104u8, 97u8, 107u8, 104u8, 97u8,
+                        119u8, 104u8, 97u8, 122u8, 104u8, 101u8, 0u8, 104u8, 105u8, 0u8, 104u8,
+                        105u8, 102u8, 104u8, 105u8, 108u8, 104u8, 108u8, 117u8, 104u8, 109u8,
+                        100u8, 104u8, 110u8, 100u8, 104u8, 110u8, 101u8, 104u8, 110u8, 106u8,
+                        104u8, 110u8, 110u8, 104u8, 110u8, 111u8, 104u8, 111u8, 0u8, 104u8, 111u8,
+                        99u8, 104u8, 111u8, 106u8, 104u8, 114u8, 0u8, 104u8, 115u8, 98u8, 104u8,
+                        115u8, 110u8, 104u8, 116u8, 0u8, 104u8, 117u8, 0u8, 104u8, 117u8, 114u8,
+                        104u8, 121u8, 0u8, 104u8, 122u8, 0u8, 105u8, 97u8, 0u8, 105u8, 98u8, 97u8,
+                        105u8, 98u8, 98u8, 105u8, 100u8, 0u8, 105u8, 102u8, 101u8, 105u8, 103u8,
+                        0u8, 105u8, 105u8, 0u8, 105u8, 107u8, 0u8, 105u8, 108u8, 111u8, 105u8,
+                        110u8, 0u8, 105u8, 110u8, 104u8, 105u8, 111u8, 0u8, 105u8, 115u8, 0u8,
+                        105u8, 116u8, 0u8, 105u8, 117u8, 0u8, 105u8, 119u8, 0u8, 105u8, 122u8,
+                        104u8, 106u8, 97u8, 0u8, 106u8, 97u8, 109u8, 106u8, 98u8, 111u8, 106u8,
+                        103u8, 111u8, 106u8, 105u8, 0u8, 106u8, 109u8, 99u8, 106u8, 109u8, 108u8,
+                        106u8, 117u8, 116u8, 106u8, 118u8, 0u8, 106u8, 119u8, 0u8, 107u8, 97u8,
+                        0u8, 107u8, 97u8, 97u8, 107u8, 97u8, 98u8, 107u8, 97u8, 99u8, 107u8, 97u8,
+                        106u8, 107u8, 97u8, 109u8, 107u8, 97u8, 111u8, 107u8, 97u8, 119u8, 107u8,
+                        98u8, 100u8, 107u8, 98u8, 121u8, 107u8, 99u8, 103u8, 107u8, 99u8, 107u8,
+                        107u8, 100u8, 101u8, 107u8, 100u8, 104u8, 107u8, 100u8, 116u8, 107u8,
+                        101u8, 97u8, 107u8, 101u8, 110u8, 107u8, 102u8, 111u8, 107u8, 102u8, 114u8,
+                        107u8, 102u8, 121u8, 107u8, 103u8, 0u8, 107u8, 103u8, 101u8, 107u8, 103u8,
+                        112u8, 107u8, 104u8, 97u8, 107u8, 104u8, 98u8, 107u8, 104u8, 110u8, 107u8,
+                        104u8, 113u8, 107u8, 104u8, 116u8, 107u8, 104u8, 119u8, 107u8, 105u8, 0u8,
+                        107u8, 105u8, 117u8, 107u8, 106u8, 0u8, 107u8, 106u8, 103u8, 107u8, 107u8,
+                        0u8, 107u8, 107u8, 106u8, 107u8, 108u8, 0u8, 107u8, 108u8, 110u8, 107u8,
+                        109u8, 0u8, 107u8, 109u8, 98u8, 107u8, 110u8, 0u8, 107u8, 110u8, 102u8,
+                        107u8, 111u8, 0u8, 107u8, 111u8, 105u8, 107u8, 111u8, 107u8, 107u8, 111u8,
+                        115u8, 107u8, 112u8, 101u8, 107u8, 114u8, 99u8, 107u8, 114u8, 105u8, 107u8,
+                        114u8, 106u8, 107u8, 114u8, 108u8, 107u8, 114u8, 117u8, 107u8, 115u8, 0u8,
+                        107u8, 115u8, 98u8, 107u8, 115u8, 102u8, 107u8, 115u8, 104u8, 107u8, 116u8,
+                        114u8, 107u8, 117u8, 0u8, 107u8, 117u8, 109u8, 107u8, 118u8, 0u8, 107u8,
+                        118u8, 114u8, 107u8, 118u8, 120u8, 107u8, 119u8, 0u8, 107u8, 119u8, 107u8,
+                        107u8, 120u8, 108u8, 107u8, 120u8, 109u8, 107u8, 120u8, 112u8, 107u8,
+                        121u8, 0u8, 107u8, 122u8, 106u8, 107u8, 122u8, 116u8, 108u8, 97u8, 0u8,
+                        108u8, 97u8, 98u8, 108u8, 97u8, 100u8, 108u8, 97u8, 103u8, 108u8, 97u8,
+                        104u8, 108u8, 97u8, 106u8, 108u8, 98u8, 0u8, 108u8, 98u8, 101u8, 108u8,
+                        98u8, 119u8, 108u8, 99u8, 112u8, 108u8, 101u8, 112u8, 108u8, 101u8, 122u8,
+                        108u8, 103u8, 0u8, 108u8, 105u8, 0u8, 108u8, 105u8, 102u8, 108u8, 105u8,
+                        106u8, 108u8, 105u8, 108u8, 108u8, 105u8, 115u8, 108u8, 106u8, 112u8,
+                        108u8, 107u8, 105u8, 108u8, 107u8, 116u8, 108u8, 109u8, 110u8, 108u8,
+                        109u8, 111u8, 108u8, 110u8, 0u8, 108u8, 111u8, 0u8, 108u8, 111u8, 108u8,
+                        108u8, 111u8, 122u8, 108u8, 114u8, 99u8, 108u8, 116u8, 0u8, 108u8, 116u8,
+                        103u8, 108u8, 117u8, 0u8, 108u8, 117u8, 97u8, 108u8, 117u8, 111u8, 108u8,
+                        117u8, 121u8, 108u8, 117u8, 122u8, 108u8, 118u8, 0u8, 108u8, 119u8, 108u8,
+                        108u8, 122u8, 104u8, 108u8, 122u8, 122u8, 109u8, 97u8, 100u8, 109u8, 97u8,
+                        102u8, 109u8, 97u8, 103u8, 109u8, 97u8, 105u8, 109u8, 97u8, 107u8, 109u8,
+                        97u8, 110u8, 109u8, 97u8, 115u8, 109u8, 97u8, 122u8, 109u8, 100u8, 102u8,
+                        109u8, 100u8, 104u8, 109u8, 100u8, 114u8, 109u8, 101u8, 110u8, 109u8,
+                        101u8, 114u8, 109u8, 102u8, 97u8, 109u8, 102u8, 101u8, 109u8, 103u8, 0u8,
+                        109u8, 103u8, 104u8, 109u8, 103u8, 111u8, 109u8, 103u8, 112u8, 109u8,
+                        103u8, 121u8, 109u8, 104u8, 0u8, 109u8, 105u8, 0u8, 109u8, 105u8, 99u8,
+                        109u8, 105u8, 110u8, 109u8, 107u8, 0u8, 109u8, 108u8, 0u8, 109u8, 108u8,
+                        115u8, 109u8, 110u8, 0u8, 109u8, 110u8, 105u8, 109u8, 110u8, 119u8, 109u8,
+                        111u8, 0u8, 109u8, 111u8, 101u8, 109u8, 111u8, 104u8, 109u8, 111u8, 115u8,
+                        109u8, 114u8, 0u8, 109u8, 114u8, 100u8, 109u8, 114u8, 106u8, 109u8, 114u8,
+                        111u8, 109u8, 115u8, 0u8, 109u8, 116u8, 0u8, 109u8, 116u8, 114u8, 109u8,
+                        117u8, 97u8, 109u8, 117u8, 115u8, 109u8, 118u8, 121u8, 109u8, 119u8, 107u8,
+                        109u8, 119u8, 114u8, 109u8, 119u8, 118u8, 109u8, 119u8, 119u8, 109u8,
+                        120u8, 99u8, 109u8, 121u8, 0u8, 109u8, 121u8, 118u8, 109u8, 121u8, 120u8,
+                        109u8, 121u8, 122u8, 109u8, 122u8, 110u8, 110u8, 97u8, 0u8, 110u8, 97u8,
+                        110u8, 110u8, 97u8, 112u8, 110u8, 97u8, 113u8, 110u8, 98u8, 0u8, 110u8,
+                        99u8, 104u8, 110u8, 100u8, 0u8, 110u8, 100u8, 99u8, 110u8, 100u8, 115u8,
+                        110u8, 101u8, 0u8, 110u8, 101u8, 119u8, 110u8, 103u8, 0u8, 110u8, 103u8,
+                        108u8, 110u8, 104u8, 101u8, 110u8, 104u8, 119u8, 110u8, 105u8, 106u8,
+                        110u8, 105u8, 117u8, 110u8, 106u8, 111u8, 110u8, 108u8, 0u8, 110u8, 109u8,
+                        103u8, 110u8, 110u8, 0u8, 110u8, 110u8, 104u8, 110u8, 110u8, 112u8, 110u8,
+                        111u8, 0u8, 110u8, 111u8, 100u8, 110u8, 111u8, 101u8, 110u8, 111u8, 110u8,
+                        110u8, 113u8, 111u8, 110u8, 114u8, 0u8, 110u8, 115u8, 107u8, 110u8, 115u8,
+                        111u8, 110u8, 115u8, 116u8, 110u8, 117u8, 115u8, 110u8, 118u8, 0u8, 110u8,
+                        120u8, 113u8, 110u8, 121u8, 0u8, 110u8, 121u8, 109u8, 110u8, 121u8, 110u8,
+                        110u8, 122u8, 105u8, 111u8, 99u8, 0u8, 111u8, 106u8, 0u8, 111u8, 106u8,
+                        115u8, 111u8, 107u8, 97u8, 111u8, 109u8, 0u8, 111u8, 114u8, 0u8, 111u8,
+                        115u8, 0u8, 111u8, 115u8, 97u8, 111u8, 116u8, 107u8, 111u8, 117u8, 105u8,
+                        112u8, 97u8, 0u8, 112u8, 97u8, 103u8, 112u8, 97u8, 108u8, 112u8, 97u8,
+                        109u8, 112u8, 97u8, 112u8, 112u8, 97u8, 117u8, 112u8, 99u8, 100u8, 112u8,
+                        99u8, 109u8, 112u8, 100u8, 99u8, 112u8, 100u8, 116u8, 112u8, 101u8, 111u8,
+                        112u8, 102u8, 108u8, 112u8, 104u8, 110u8, 112u8, 105u8, 115u8, 112u8,
+                        107u8, 97u8, 112u8, 107u8, 111u8, 112u8, 108u8, 0u8, 112u8, 109u8, 115u8,
+                        112u8, 110u8, 116u8, 112u8, 111u8, 110u8, 112u8, 112u8, 97u8, 112u8, 113u8,
+                        109u8, 112u8, 114u8, 97u8, 112u8, 114u8, 100u8, 112u8, 114u8, 103u8, 112u8,
+                        115u8, 0u8, 112u8, 116u8, 0u8, 112u8, 117u8, 117u8, 113u8, 117u8, 0u8,
+                        113u8, 117u8, 99u8, 113u8, 117u8, 103u8, 114u8, 97u8, 106u8, 114u8, 99u8,
+                        102u8, 114u8, 101u8, 106u8, 114u8, 103u8, 110u8, 114u8, 104u8, 103u8,
+                        114u8, 105u8, 97u8, 114u8, 105u8, 102u8, 114u8, 106u8, 115u8, 114u8, 107u8,
+                        116u8, 114u8, 109u8, 0u8, 114u8, 109u8, 102u8, 114u8, 109u8, 111u8, 114u8,
+                        109u8, 116u8, 114u8, 109u8, 117u8, 114u8, 110u8, 0u8, 114u8, 110u8, 103u8,
+                        114u8, 111u8, 0u8, 114u8, 111u8, 98u8, 114u8, 111u8, 102u8, 114u8, 116u8,
+                        109u8, 114u8, 117u8, 0u8, 114u8, 117u8, 101u8, 114u8, 117u8, 103u8, 114u8,
+                        119u8, 0u8, 114u8, 119u8, 107u8, 114u8, 121u8, 117u8, 115u8, 97u8, 0u8,
+                        115u8, 97u8, 102u8, 115u8, 97u8, 104u8, 115u8, 97u8, 113u8, 115u8, 97u8,
+                        115u8, 115u8, 97u8, 116u8, 115u8, 97u8, 118u8, 115u8, 97u8, 122u8, 115u8,
+                        98u8, 112u8, 115u8, 99u8, 0u8, 115u8, 99u8, 107u8, 115u8, 99u8, 110u8,
+                        115u8, 99u8, 111u8, 115u8, 100u8, 0u8, 115u8, 100u8, 99u8, 115u8, 100u8,
+                        104u8, 115u8, 101u8, 0u8, 115u8, 101u8, 102u8, 115u8, 101u8, 104u8, 115u8,
+                        101u8, 105u8, 115u8, 101u8, 115u8, 115u8, 103u8, 0u8, 115u8, 103u8, 97u8,
+                        115u8, 103u8, 115u8, 115u8, 104u8, 105u8, 115u8, 104u8, 110u8, 115u8,
+                        105u8, 0u8, 115u8, 105u8, 100u8, 115u8, 107u8, 0u8, 115u8, 107u8, 114u8,
+                        115u8, 108u8, 0u8, 115u8, 108u8, 105u8, 115u8, 108u8, 121u8, 115u8, 109u8,
+                        0u8, 115u8, 109u8, 97u8, 115u8, 109u8, 100u8, 115u8, 109u8, 106u8, 115u8,
+                        109u8, 110u8, 115u8, 109u8, 112u8, 115u8, 109u8, 115u8, 115u8, 110u8, 0u8,
+                        115u8, 110u8, 98u8, 115u8, 110u8, 107u8, 115u8, 111u8, 0u8, 115u8, 111u8,
+                        103u8, 115u8, 111u8, 117u8, 115u8, 113u8, 0u8, 115u8, 114u8, 0u8, 115u8,
+                        114u8, 98u8, 115u8, 114u8, 110u8, 115u8, 114u8, 114u8, 115u8, 114u8, 120u8,
+                        115u8, 115u8, 0u8, 115u8, 115u8, 121u8, 115u8, 116u8, 0u8, 115u8, 116u8,
+                        113u8, 115u8, 117u8, 0u8, 115u8, 117u8, 107u8, 115u8, 117u8, 115u8, 115u8,
+                        118u8, 0u8, 115u8, 119u8, 0u8, 115u8, 119u8, 98u8, 115u8, 119u8, 99u8,
+                        115u8, 119u8, 103u8, 115u8, 119u8, 118u8, 115u8, 120u8, 110u8, 115u8,
+                        121u8, 108u8, 115u8, 121u8, 114u8, 115u8, 122u8, 108u8, 116u8, 97u8, 0u8,
+                        116u8, 97u8, 106u8, 116u8, 98u8, 119u8, 116u8, 99u8, 121u8, 116u8, 100u8,
+                        100u8, 116u8, 100u8, 103u8, 116u8, 100u8, 104u8, 116u8, 100u8, 117u8,
+                        116u8, 101u8, 0u8, 116u8, 101u8, 109u8, 116u8, 101u8, 111u8, 116u8, 101u8,
+                        116u8, 116u8, 103u8, 0u8, 116u8, 104u8, 0u8, 116u8, 104u8, 108u8, 116u8,
+                        104u8, 113u8, 116u8, 104u8, 114u8, 116u8, 105u8, 0u8, 116u8, 105u8, 103u8,
+                        116u8, 105u8, 118u8, 116u8, 107u8, 0u8, 116u8, 107u8, 108u8, 116u8, 107u8,
+                        114u8, 116u8, 107u8, 116u8, 116u8, 108u8, 0u8, 116u8, 108u8, 121u8, 116u8,
+                        109u8, 104u8, 116u8, 110u8, 0u8, 116u8, 111u8, 0u8, 116u8, 111u8, 103u8,
+                        116u8, 111u8, 107u8, 116u8, 112u8, 105u8, 116u8, 114u8, 0u8, 116u8, 114u8,
+                        117u8, 116u8, 114u8, 118u8, 116u8, 114u8, 119u8, 116u8, 115u8, 0u8, 116u8,
+                        115u8, 100u8, 116u8, 115u8, 102u8, 116u8, 115u8, 103u8, 116u8, 115u8,
+                        106u8, 116u8, 116u8, 0u8, 116u8, 116u8, 106u8, 116u8, 116u8, 115u8, 116u8,
+                        116u8, 116u8, 116u8, 117u8, 109u8, 116u8, 118u8, 108u8, 116u8, 119u8,
+                        113u8, 116u8, 120u8, 103u8, 116u8, 120u8, 111u8, 116u8, 121u8, 0u8, 116u8,
+                        121u8, 118u8, 116u8, 122u8, 109u8, 117u8, 100u8, 105u8, 117u8, 100u8,
+                        109u8, 117u8, 103u8, 0u8, 117u8, 103u8, 97u8, 117u8, 107u8, 0u8, 117u8,
+                        108u8, 105u8, 117u8, 109u8, 98u8, 117u8, 110u8, 114u8, 117u8, 110u8, 120u8,
+                        117u8, 114u8, 0u8, 117u8, 122u8, 0u8, 118u8, 97u8, 105u8, 118u8, 101u8,
+                        0u8, 118u8, 101u8, 99u8, 118u8, 101u8, 112u8, 118u8, 105u8, 0u8, 118u8,
+                        105u8, 99u8, 118u8, 108u8, 115u8, 118u8, 109u8, 102u8, 118u8, 109u8, 119u8,
+                        118u8, 111u8, 0u8, 118u8, 111u8, 116u8, 118u8, 114u8, 111u8, 118u8, 117u8,
+                        110u8, 119u8, 97u8, 0u8, 119u8, 97u8, 101u8, 119u8, 97u8, 108u8, 119u8,
+                        97u8, 114u8, 119u8, 98u8, 112u8, 119u8, 98u8, 113u8, 119u8, 98u8, 114u8,
+                        119u8, 108u8, 115u8, 119u8, 110u8, 105u8, 119u8, 111u8, 0u8, 119u8, 115u8,
+                        103u8, 119u8, 116u8, 109u8, 119u8, 117u8, 117u8, 120u8, 97u8, 118u8, 120u8,
+                        99u8, 111u8, 120u8, 99u8, 114u8, 120u8, 104u8, 0u8, 120u8, 108u8, 99u8,
+                        120u8, 108u8, 100u8, 120u8, 109u8, 102u8, 120u8, 109u8, 110u8, 120u8,
+                        109u8, 114u8, 120u8, 110u8, 97u8, 120u8, 110u8, 114u8, 120u8, 111u8, 103u8,
+                        120u8, 112u8, 114u8, 120u8, 115u8, 97u8, 120u8, 115u8, 114u8, 121u8, 97u8,
+                        111u8, 121u8, 97u8, 112u8, 121u8, 97u8, 118u8, 121u8, 98u8, 98u8, 121u8,
+                        105u8, 0u8, 121u8, 111u8, 0u8, 121u8, 114u8, 108u8, 121u8, 117u8, 97u8,
+                        121u8, 117u8, 101u8, 122u8, 97u8, 0u8, 122u8, 97u8, 103u8, 122u8, 100u8,
+                        106u8, 122u8, 101u8, 97u8, 122u8, 103u8, 104u8, 122u8, 104u8, 0u8, 122u8,
+                        104u8, 120u8, 122u8, 107u8, 116u8, 122u8, 108u8, 109u8, 122u8, 109u8,
+                        105u8, 122u8, 117u8, 0u8, 122u8, 122u8, 97u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        69u8, 84u8, 0u8, 71u8, 69u8, 0u8, 71u8, 72u8, 0u8, 73u8, 68u8, 0u8, 85u8,
+                        71u8, 0u8, 71u8, 72u8, 0u8, 66u8, 84u8, 0u8, 82u8, 85u8, 0u8, 73u8, 82u8,
+                        0u8, 84u8, 78u8, 0u8, 90u8, 65u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8,
+                        84u8, 78u8, 0u8, 71u8, 72u8, 0u8, 73u8, 81u8, 0u8, 88u8, 75u8, 0u8, 82u8,
+                        85u8, 0u8, 69u8, 84u8, 0u8, 78u8, 71u8, 0u8, 69u8, 83u8, 0u8, 78u8, 71u8,
+                        0u8, 73u8, 68u8, 0u8, 84u8, 71u8, 0u8, 69u8, 71u8, 0u8, 73u8, 82u8, 0u8,
+                        67u8, 76u8, 0u8, 66u8, 79u8, 0u8, 68u8, 90u8, 0u8, 83u8, 65u8, 0u8, 77u8,
+                        65u8, 0u8, 69u8, 71u8, 0u8, 73u8, 78u8, 0u8, 84u8, 90u8, 0u8, 85u8, 83u8,
+                        0u8, 69u8, 83u8, 0u8, 67u8, 65u8, 0u8, 82u8, 85u8, 0u8, 73u8, 78u8, 0u8,
+                        66u8, 79u8, 0u8, 65u8, 90u8, 0u8, 82u8, 85u8, 0u8, 80u8, 75u8, 0u8, 73u8,
+                        68u8, 0u8, 78u8, 80u8, 0u8, 65u8, 84u8, 0u8, 67u8, 77u8, 0u8, 67u8, 77u8,
+                        0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 67u8, 73u8, 0u8, 66u8, 89u8, 0u8,
+                        83u8, 68u8, 0u8, 90u8, 77u8, 0u8, 73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 67u8,
+                        77u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 66u8, 71u8,
+                        0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8,
+                        73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 86u8, 85u8, 0u8, 80u8, 72u8, 0u8, 78u8,
+                        71u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8, 83u8, 78u8, 0u8, 67u8, 77u8,
+                        0u8, 80u8, 72u8, 0u8, 67u8, 65u8, 0u8, 77u8, 89u8, 0u8, 86u8, 78u8, 0u8,
+                        77u8, 76u8, 0u8, 77u8, 76u8, 0u8, 66u8, 68u8, 0u8, 67u8, 78u8, 0u8, 73u8,
+                        78u8, 0u8, 73u8, 82u8, 0u8, 67u8, 73u8, 0u8, 70u8, 82u8, 0u8, 73u8, 78u8,
+                        0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 66u8, 65u8, 0u8, 76u8, 82u8, 0u8,
+                        67u8, 77u8, 0u8, 80u8, 72u8, 0u8, 80u8, 75u8, 0u8, 82u8, 85u8, 0u8, 89u8,
+                        84u8, 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 71u8, 81u8, 0u8, 69u8, 82u8,
+                        0u8, 67u8, 77u8, 0u8, 77u8, 76u8, 0u8, 69u8, 83u8, 0u8, 85u8, 83u8, 0u8,
+                        78u8, 71u8, 0u8, 66u8, 68u8, 0u8, 82u8, 85u8, 0u8, 80u8, 72u8, 0u8, 85u8,
+                        71u8, 0u8, 71u8, 85u8, 0u8, 70u8, 77u8, 0u8, 82u8, 85u8, 0u8, 85u8, 83u8,
+                        0u8, 67u8, 65u8, 0u8, 85u8, 83u8, 0u8, 85u8, 83u8, 0u8, 75u8, 72u8, 0u8,
+                        86u8, 78u8, 0u8, 73u8, 81u8, 0u8, 67u8, 65u8, 0u8, 77u8, 78u8, 0u8, 70u8,
+                        82u8, 0u8, 69u8, 71u8, 0u8, 80u8, 72u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8,
+                        0u8, 85u8, 65u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 83u8, 67u8, 0u8,
+                        67u8, 90u8, 0u8, 80u8, 76u8, 0u8, 67u8, 65u8, 0u8, 77u8, 77u8, 0u8, 82u8,
+                        85u8, 0u8, 82u8, 85u8, 0u8, 71u8, 66u8, 0u8, 68u8, 75u8, 0u8, 67u8, 73u8,
+                        0u8, 85u8, 83u8, 0u8, 82u8, 85u8, 0u8, 75u8, 69u8, 0u8, 73u8, 78u8, 0u8,
+                        68u8, 69u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 78u8, 69u8, 0u8, 78u8,
+                        71u8, 0u8, 67u8, 73u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, 68u8, 69u8,
+                        0u8, 77u8, 76u8, 0u8, 77u8, 89u8, 0u8, 78u8, 80u8, 0u8, 67u8, 77u8, 0u8,
+                        77u8, 86u8, 0u8, 83u8, 78u8, 0u8, 66u8, 70u8, 0u8, 66u8, 84u8, 0u8, 75u8,
+                        69u8, 0u8, 71u8, 72u8, 0u8, 78u8, 71u8, 0u8, 73u8, 84u8, 0u8, 69u8, 71u8,
+                        0u8, 77u8, 77u8, 0u8, 71u8, 82u8, 0u8, 85u8, 83u8, 0u8, 48u8, 48u8, 49u8,
+                        69u8, 83u8, 0u8, 73u8, 78u8, 0u8, 85u8, 83u8, 0u8, 69u8, 69u8, 0u8, 73u8,
+                        84u8, 0u8, 69u8, 83u8, 0u8, 67u8, 77u8, 0u8, 69u8, 83u8, 0u8, 73u8, 82u8,
+                        0u8, 71u8, 81u8, 0u8, 83u8, 78u8, 0u8, 77u8, 76u8, 0u8, 70u8, 73u8, 0u8,
+                        83u8, 68u8, 0u8, 80u8, 72u8, 0u8, 83u8, 69u8, 0u8, 70u8, 74u8, 0u8, 70u8,
+                        79u8, 0u8, 66u8, 74u8, 0u8, 70u8, 82u8, 0u8, 85u8, 83u8, 0u8, 70u8, 82u8,
+                        0u8, 68u8, 69u8, 0u8, 68u8, 69u8, 0u8, 67u8, 77u8, 0u8, 87u8, 70u8, 0u8,
+                        71u8, 78u8, 0u8, 78u8, 69u8, 0u8, 73u8, 84u8, 0u8, 78u8, 71u8, 0u8, 83u8,
+                        68u8, 0u8, 78u8, 76u8, 0u8, 73u8, 69u8, 0u8, 71u8, 72u8, 0u8, 77u8, 68u8,
+                        0u8, 67u8, 78u8, 0u8, 73u8, 68u8, 0u8, 73u8, 78u8, 0u8, 73u8, 82u8, 0u8,
+                        71u8, 70u8, 0u8, 71u8, 66u8, 0u8, 69u8, 84u8, 0u8, 78u8, 80u8, 0u8, 75u8,
+                        73u8, 0u8, 80u8, 75u8, 0u8, 80u8, 75u8, 0u8, 69u8, 83u8, 0u8, 73u8, 82u8,
+                        0u8, 80u8, 89u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8,
+                        78u8, 76u8, 0u8, 85u8, 65u8, 0u8, 67u8, 89u8, 0u8, 73u8, 78u8, 0u8, 67u8,
+                        72u8, 0u8, 73u8, 78u8, 0u8, 66u8, 82u8, 0u8, 67u8, 79u8, 0u8, 71u8, 72u8,
+                        0u8, 75u8, 69u8, 0u8, 73u8, 77u8, 0u8, 78u8, 80u8, 0u8, 67u8, 65u8, 0u8,
+                        78u8, 71u8, 0u8, 67u8, 78u8, 0u8, 85u8, 83u8, 0u8, 65u8, 70u8, 0u8, 73u8,
+                        76u8, 0u8, 73u8, 78u8, 0u8, 70u8, 74u8, 0u8, 80u8, 72u8, 0u8, 84u8, 82u8,
+                        0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 85u8, 83u8, 0u8,
+                        80u8, 72u8, 0u8, 80u8, 75u8, 0u8, 80u8, 71u8, 0u8, 73u8, 78u8, 0u8, 73u8,
+                        78u8, 0u8, 72u8, 82u8, 0u8, 68u8, 69u8, 0u8, 67u8, 78u8, 0u8, 72u8, 84u8,
+                        0u8, 72u8, 85u8, 0u8, 67u8, 65u8, 0u8, 65u8, 77u8, 0u8, 78u8, 65u8, 0u8,
+                        48u8, 48u8, 49u8, 77u8, 89u8, 0u8, 78u8, 71u8, 0u8, 73u8, 68u8, 0u8, 84u8,
+                        71u8, 0u8, 78u8, 71u8, 0u8, 67u8, 78u8, 0u8, 85u8, 83u8, 0u8, 80u8, 72u8,
+                        0u8, 73u8, 68u8, 0u8, 82u8, 85u8, 0u8, 48u8, 48u8, 49u8, 73u8, 83u8, 0u8,
+                        73u8, 84u8, 0u8, 67u8, 65u8, 0u8, 73u8, 76u8, 0u8, 82u8, 85u8, 0u8, 74u8,
+                        80u8, 0u8, 74u8, 77u8, 0u8, 48u8, 48u8, 49u8, 67u8, 77u8, 0u8, 85u8, 65u8,
+                        0u8, 84u8, 90u8, 0u8, 78u8, 80u8, 0u8, 68u8, 75u8, 0u8, 73u8, 68u8, 0u8,
+                        73u8, 68u8, 0u8, 71u8, 69u8, 0u8, 85u8, 90u8, 0u8, 68u8, 90u8, 0u8, 77u8,
+                        77u8, 0u8, 78u8, 71u8, 0u8, 75u8, 69u8, 0u8, 77u8, 76u8, 0u8, 73u8, 68u8,
+                        0u8, 82u8, 85u8, 0u8, 78u8, 69u8, 0u8, 78u8, 71u8, 0u8, 90u8, 87u8, 0u8,
+                        84u8, 90u8, 0u8, 84u8, 71u8, 0u8, 84u8, 72u8, 0u8, 67u8, 86u8, 0u8, 67u8,
+                        77u8, 0u8, 67u8, 73u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 67u8, 68u8,
+                        0u8, 73u8, 68u8, 0u8, 66u8, 82u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8,
+                        73u8, 78u8, 0u8, 77u8, 76u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8,
+                        69u8, 0u8, 84u8, 82u8, 0u8, 78u8, 65u8, 0u8, 76u8, 65u8, 0u8, 75u8, 90u8,
+                        0u8, 67u8, 77u8, 0u8, 71u8, 76u8, 0u8, 75u8, 69u8, 0u8, 75u8, 72u8, 0u8,
+                        65u8, 79u8, 0u8, 73u8, 78u8, 0u8, 71u8, 87u8, 0u8, 75u8, 82u8, 0u8, 82u8,
+                        85u8, 0u8, 73u8, 78u8, 0u8, 70u8, 77u8, 0u8, 76u8, 82u8, 0u8, 82u8, 85u8,
+                        0u8, 83u8, 76u8, 0u8, 80u8, 72u8, 0u8, 82u8, 85u8, 0u8, 73u8, 78u8, 0u8,
+                        73u8, 78u8, 0u8, 84u8, 90u8, 0u8, 67u8, 77u8, 0u8, 68u8, 69u8, 0u8, 77u8,
+                        89u8, 0u8, 84u8, 82u8, 0u8, 82u8, 85u8, 0u8, 82u8, 85u8, 0u8, 73u8, 68u8,
+                        0u8, 80u8, 75u8, 0u8, 71u8, 66u8, 0u8, 67u8, 65u8, 0u8, 73u8, 78u8, 0u8,
+                        84u8, 72u8, 0u8, 80u8, 75u8, 0u8, 75u8, 71u8, 0u8, 77u8, 89u8, 0u8, 77u8,
+                        89u8, 0u8, 86u8, 65u8, 0u8, 71u8, 82u8, 0u8, 73u8, 76u8, 0u8, 84u8, 90u8,
+                        0u8, 80u8, 75u8, 0u8, 85u8, 71u8, 0u8, 76u8, 85u8, 0u8, 82u8, 85u8, 0u8,
+                        73u8, 68u8, 0u8, 67u8, 78u8, 0u8, 73u8, 78u8, 0u8, 82u8, 85u8, 0u8, 85u8,
+                        71u8, 0u8, 78u8, 76u8, 0u8, 78u8, 80u8, 0u8, 73u8, 84u8, 0u8, 67u8, 65u8,
+                        0u8, 67u8, 78u8, 0u8, 73u8, 68u8, 0u8, 73u8, 82u8, 0u8, 85u8, 83u8, 0u8,
+                        73u8, 78u8, 0u8, 73u8, 84u8, 0u8, 67u8, 68u8, 0u8, 76u8, 65u8, 0u8, 67u8,
+                        68u8, 0u8, 90u8, 77u8, 0u8, 73u8, 82u8, 0u8, 76u8, 84u8, 0u8, 76u8, 86u8,
+                        0u8, 67u8, 68u8, 0u8, 67u8, 68u8, 0u8, 75u8, 69u8, 0u8, 75u8, 69u8, 0u8,
+                        73u8, 82u8, 0u8, 76u8, 86u8, 0u8, 84u8, 72u8, 0u8, 67u8, 78u8, 0u8, 84u8,
+                        82u8, 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8,
+                        0u8, 73u8, 68u8, 0u8, 71u8, 77u8, 0u8, 75u8, 69u8, 0u8, 77u8, 88u8, 0u8,
+                        82u8, 85u8, 0u8, 80u8, 72u8, 0u8, 73u8, 68u8, 0u8, 83u8, 76u8, 0u8, 75u8,
+                        69u8, 0u8, 84u8, 72u8, 0u8, 77u8, 85u8, 0u8, 77u8, 71u8, 0u8, 77u8, 90u8,
+                        0u8, 67u8, 77u8, 0u8, 78u8, 80u8, 0u8, 84u8, 90u8, 0u8, 77u8, 72u8, 0u8,
+                        78u8, 90u8, 0u8, 67u8, 65u8, 0u8, 73u8, 68u8, 0u8, 77u8, 75u8, 0u8, 73u8,
+                        78u8, 0u8, 83u8, 68u8, 0u8, 77u8, 78u8, 0u8, 73u8, 78u8, 0u8, 77u8, 77u8,
+                        0u8, 82u8, 79u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 66u8, 70u8, 0u8,
+                        73u8, 78u8, 0u8, 78u8, 80u8, 0u8, 82u8, 85u8, 0u8, 66u8, 68u8, 0u8, 77u8,
+                        89u8, 0u8, 77u8, 84u8, 0u8, 73u8, 78u8, 0u8, 67u8, 77u8, 0u8, 85u8, 83u8,
+                        0u8, 80u8, 75u8, 0u8, 77u8, 76u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8,
+                        85u8, 83u8, 0u8, 90u8, 87u8, 0u8, 77u8, 77u8, 0u8, 82u8, 85u8, 0u8, 85u8,
+                        71u8, 0u8, 73u8, 82u8, 0u8, 73u8, 82u8, 0u8, 78u8, 82u8, 0u8, 67u8, 78u8,
+                        0u8, 73u8, 84u8, 0u8, 78u8, 65u8, 0u8, 78u8, 79u8, 0u8, 77u8, 88u8, 0u8,
+                        90u8, 87u8, 0u8, 77u8, 90u8, 0u8, 68u8, 69u8, 0u8, 78u8, 80u8, 0u8, 78u8,
+                        80u8, 0u8, 78u8, 65u8, 0u8, 77u8, 90u8, 0u8, 77u8, 88u8, 0u8, 77u8, 88u8,
+                        0u8, 73u8, 68u8, 0u8, 78u8, 85u8, 0u8, 73u8, 78u8, 0u8, 78u8, 76u8, 0u8,
+                        67u8, 77u8, 0u8, 78u8, 79u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, 78u8,
+                        79u8, 0u8, 84u8, 72u8, 0u8, 73u8, 78u8, 0u8, 83u8, 69u8, 0u8, 71u8, 78u8,
+                        0u8, 90u8, 65u8, 0u8, 67u8, 65u8, 0u8, 90u8, 65u8, 0u8, 73u8, 78u8, 0u8,
+                        83u8, 83u8, 0u8, 85u8, 83u8, 0u8, 67u8, 78u8, 0u8, 77u8, 87u8, 0u8, 84u8,
+                        90u8, 0u8, 85u8, 71u8, 0u8, 71u8, 72u8, 0u8, 70u8, 82u8, 0u8, 67u8, 65u8,
+                        0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 69u8, 84u8, 0u8, 73u8, 78u8, 0u8,
+                        71u8, 69u8, 0u8, 85u8, 83u8, 0u8, 77u8, 78u8, 0u8, 49u8, 52u8, 51u8, 73u8,
+                        78u8, 0u8, 80u8, 72u8, 0u8, 73u8, 82u8, 0u8, 80u8, 72u8, 0u8, 65u8, 87u8,
+                        0u8, 80u8, 87u8, 0u8, 70u8, 82u8, 0u8, 78u8, 71u8, 0u8, 85u8, 83u8, 0u8,
+                        67u8, 65u8, 0u8, 73u8, 82u8, 0u8, 68u8, 69u8, 0u8, 76u8, 66u8, 0u8, 83u8,
+                        66u8, 0u8, 73u8, 78u8, 0u8, 75u8, 69u8, 0u8, 80u8, 76u8, 0u8, 73u8, 84u8,
+                        0u8, 71u8, 82u8, 0u8, 70u8, 77u8, 0u8, 73u8, 78u8, 0u8, 67u8, 65u8, 0u8,
+                        80u8, 75u8, 0u8, 73u8, 82u8, 0u8, 48u8, 48u8, 49u8, 65u8, 70u8, 0u8, 66u8,
+                        82u8, 0u8, 71u8, 65u8, 0u8, 80u8, 69u8, 0u8, 71u8, 84u8, 0u8, 69u8, 67u8,
+                        0u8, 73u8, 78u8, 0u8, 82u8, 69u8, 0u8, 73u8, 68u8, 0u8, 73u8, 84u8, 0u8,
+                        77u8, 77u8, 0u8, 73u8, 78u8, 0u8, 77u8, 65u8, 0u8, 78u8, 80u8, 0u8, 66u8,
+                        68u8, 0u8, 67u8, 72u8, 0u8, 70u8, 73u8, 0u8, 67u8, 72u8, 0u8, 73u8, 82u8,
+                        0u8, 83u8, 69u8, 0u8, 66u8, 73u8, 0u8, 77u8, 90u8, 0u8, 82u8, 79u8, 0u8,
+                        73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 70u8, 74u8, 0u8, 82u8, 85u8, 0u8, 85u8,
+                        65u8, 0u8, 83u8, 66u8, 0u8, 82u8, 87u8, 0u8, 84u8, 90u8, 0u8, 74u8, 80u8,
+                        0u8, 73u8, 78u8, 0u8, 71u8, 72u8, 0u8, 82u8, 85u8, 0u8, 75u8, 69u8, 0u8,
+                        73u8, 68u8, 0u8, 73u8, 78u8, 0u8, 83u8, 78u8, 0u8, 73u8, 78u8, 0u8, 84u8,
+                        90u8, 0u8, 73u8, 84u8, 0u8, 73u8, 78u8, 0u8, 73u8, 84u8, 0u8, 71u8, 66u8,
+                        0u8, 80u8, 75u8, 0u8, 73u8, 84u8, 0u8, 73u8, 82u8, 0u8, 78u8, 79u8, 0u8,
+                        67u8, 73u8, 0u8, 77u8, 90u8, 0u8, 77u8, 88u8, 0u8, 77u8, 76u8, 0u8, 67u8,
+                        70u8, 0u8, 73u8, 69u8, 0u8, 76u8, 84u8, 0u8, 77u8, 65u8, 0u8, 77u8, 77u8,
+                        0u8, 76u8, 75u8, 0u8, 69u8, 84u8, 0u8, 83u8, 75u8, 0u8, 80u8, 75u8, 0u8,
+                        83u8, 73u8, 0u8, 80u8, 76u8, 0u8, 73u8, 68u8, 0u8, 87u8, 83u8, 0u8, 83u8,
+                        69u8, 0u8, 65u8, 79u8, 0u8, 83u8, 69u8, 0u8, 70u8, 73u8, 0u8, 73u8, 76u8,
+                        0u8, 70u8, 73u8, 0u8, 90u8, 87u8, 0u8, 77u8, 89u8, 0u8, 77u8, 76u8, 0u8,
+                        83u8, 79u8, 0u8, 85u8, 90u8, 0u8, 84u8, 72u8, 0u8, 65u8, 76u8, 0u8, 82u8,
+                        83u8, 0u8, 73u8, 78u8, 0u8, 83u8, 82u8, 0u8, 83u8, 78u8, 0u8, 73u8, 78u8,
+                        0u8, 90u8, 65u8, 0u8, 69u8, 82u8, 0u8, 90u8, 65u8, 0u8, 68u8, 69u8, 0u8,
+                        73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 71u8, 78u8, 0u8, 83u8, 69u8, 0u8, 84u8,
+                        90u8, 0u8, 89u8, 84u8, 0u8, 67u8, 68u8, 0u8, 68u8, 69u8, 0u8, 73u8, 78u8,
+                        0u8, 73u8, 68u8, 0u8, 66u8, 68u8, 0u8, 73u8, 81u8, 0u8, 80u8, 76u8, 0u8,
+                        73u8, 78u8, 0u8, 78u8, 80u8, 0u8, 80u8, 72u8, 0u8, 73u8, 78u8, 0u8, 67u8,
+                        78u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 77u8, 89u8, 0u8, 73u8, 78u8,
+                        0u8, 83u8, 76u8, 0u8, 85u8, 71u8, 0u8, 84u8, 76u8, 0u8, 84u8, 74u8, 0u8,
+                        84u8, 72u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 69u8,
+                        84u8, 0u8, 69u8, 82u8, 0u8, 78u8, 71u8, 0u8, 84u8, 77u8, 0u8, 84u8, 75u8,
+                        0u8, 65u8, 90u8, 0u8, 78u8, 80u8, 0u8, 80u8, 72u8, 0u8, 65u8, 90u8, 0u8,
+                        78u8, 69u8, 0u8, 90u8, 65u8, 0u8, 84u8, 79u8, 0u8, 77u8, 87u8, 0u8, 48u8,
+                        48u8, 49u8, 80u8, 71u8, 0u8, 84u8, 82u8, 0u8, 84u8, 82u8, 0u8, 84u8, 87u8,
+                        0u8, 80u8, 75u8, 0u8, 90u8, 65u8, 0u8, 71u8, 82u8, 0u8, 78u8, 80u8, 0u8,
+                        80u8, 72u8, 0u8, 66u8, 84u8, 0u8, 82u8, 85u8, 0u8, 85u8, 71u8, 0u8, 84u8,
+                        72u8, 0u8, 65u8, 90u8, 0u8, 77u8, 87u8, 0u8, 84u8, 86u8, 0u8, 78u8, 69u8,
+                        0u8, 67u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 70u8, 0u8, 82u8, 85u8, 0u8,
+                        77u8, 65u8, 0u8, 82u8, 85u8, 0u8, 82u8, 85u8, 0u8, 67u8, 78u8, 0u8, 83u8,
+                        89u8, 0u8, 85u8, 65u8, 0u8, 70u8, 77u8, 0u8, 65u8, 79u8, 0u8, 73u8, 78u8,
+                        0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 85u8, 90u8, 0u8, 76u8, 82u8, 0u8,
+                        90u8, 65u8, 0u8, 73u8, 84u8, 0u8, 82u8, 85u8, 0u8, 86u8, 78u8, 0u8, 83u8,
+                        88u8, 0u8, 66u8, 69u8, 0u8, 68u8, 69u8, 0u8, 77u8, 90u8, 0u8, 48u8, 48u8,
+                        49u8, 82u8, 85u8, 0u8, 69u8, 69u8, 0u8, 84u8, 90u8, 0u8, 66u8, 69u8, 0u8,
+                        67u8, 72u8, 0u8, 69u8, 84u8, 0u8, 80u8, 72u8, 0u8, 65u8, 85u8, 0u8, 73u8,
+                        78u8, 0u8, 73u8, 78u8, 0u8, 87u8, 70u8, 0u8, 75u8, 77u8, 0u8, 83u8, 78u8,
+                        0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, 66u8, 82u8, 0u8,
+                        85u8, 90u8, 0u8, 84u8, 82u8, 0u8, 90u8, 65u8, 0u8, 84u8, 82u8, 0u8, 84u8,
+                        82u8, 0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 83u8, 68u8, 0u8, 83u8, 65u8,
+                        0u8, 73u8, 78u8, 0u8, 85u8, 71u8, 0u8, 73u8, 82u8, 0u8, 89u8, 69u8, 0u8,
+                        78u8, 80u8, 0u8, 77u8, 90u8, 0u8, 70u8, 77u8, 0u8, 67u8, 77u8, 0u8, 67u8,
+                        77u8, 0u8, 48u8, 48u8, 49u8, 78u8, 71u8, 0u8, 66u8, 82u8, 0u8, 77u8, 88u8,
+                        0u8, 72u8, 75u8, 0u8, 67u8, 78u8, 0u8, 83u8, 68u8, 0u8, 75u8, 77u8, 0u8,
+                        78u8, 76u8, 0u8, 77u8, 65u8, 0u8, 67u8, 78u8, 0u8, 67u8, 78u8, 0u8, 67u8,
+                        78u8, 0u8, 84u8, 71u8, 0u8, 77u8, 89u8, 0u8, 90u8, 65u8, 0u8, 84u8, 82u8,
+                        0u8,
+                    ])
+                },
+            )
+        },
+        ls2r: unsafe {
+            #[allow(unused_unsafe)]
+            ::zerovec::ZeroMap2d::from_parts_unchecked(
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        97u8, 114u8, 99u8, 97u8, 122u8, 0u8, 99u8, 117u8, 0u8, 101u8, 110u8, 0u8,
+                        102u8, 102u8, 0u8, 103u8, 114u8, 99u8, 107u8, 107u8, 0u8, 107u8, 117u8,
+                        0u8, 107u8, 121u8, 0u8, 108u8, 105u8, 102u8, 109u8, 97u8, 110u8, 109u8,
+                        110u8, 0u8, 112u8, 97u8, 0u8, 112u8, 97u8, 108u8, 115u8, 100u8, 0u8, 116u8,
+                        103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8, 117u8, 122u8, 0u8,
+                        121u8, 117u8, 101u8, 122u8, 104u8, 0u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        2u8, 0u8, 0u8, 0u8, 3u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8,
+                        0u8, 6u8, 0u8, 0u8, 0u8, 7u8, 0u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 10u8, 0u8,
+                        0u8, 0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8,
+                        15u8, 0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 20u8, 0u8,
+                        0u8, 0u8, 21u8, 0u8, 0u8, 0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8,
+                        24u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        78u8, 98u8, 97u8, 116u8, 80u8, 97u8, 108u8, 109u8, 65u8, 114u8, 97u8, 98u8,
+                        71u8, 108u8, 97u8, 103u8, 83u8, 104u8, 97u8, 119u8, 65u8, 100u8, 108u8,
+                        109u8, 76u8, 105u8, 110u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8,
+                        97u8, 98u8, 89u8, 101u8, 122u8, 105u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8,
+                        116u8, 110u8, 76u8, 105u8, 109u8, 98u8, 78u8, 107u8, 111u8, 111u8, 77u8,
+                        111u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 80u8, 104u8, 108u8, 112u8,
+                        68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 111u8, 106u8, 83u8, 105u8, 110u8,
+                        100u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8,
+                        118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 66u8,
+                        111u8, 112u8, 111u8, 72u8, 97u8, 110u8, 98u8, 72u8, 97u8, 110u8, 116u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        74u8, 79u8, 0u8, 83u8, 89u8, 0u8, 73u8, 82u8, 0u8, 66u8, 71u8, 0u8, 71u8,
+                        66u8, 0u8, 71u8, 78u8, 0u8, 71u8, 82u8, 0u8, 67u8, 78u8, 0u8, 73u8, 81u8,
+                        0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8,
+                        71u8, 78u8, 0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 67u8, 78u8, 0u8, 73u8,
+                        78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8, 90u8,
+                        0u8, 78u8, 80u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 84u8, 87u8, 0u8,
+                        84u8, 87u8, 0u8, 84u8, 87u8, 0u8,
+                    ])
+                },
+            )
+        },
+    };
diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/mod.rs b/compiler/rustc_baked_icu_data/src/data/fallback/mod.rs
new file mode 100644 (file)
index 0000000..a485a5a
--- /dev/null
@@ -0,0 +1,4 @@
+// @generated
+pub mod likelysubtags_v1;
+pub mod parents_v1;
+pub mod supplement;
diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/parents_v1.rs b/compiler/rustc_baked_icu_data/src/data/fallback/parents_v1.rs
new file mode 100644 (file)
index 0000000..f07b4b8
--- /dev/null
@@ -0,0 +1,207 @@
+// @generated
+type DataStruct = < :: icu_provider_adapters :: fallback :: provider :: LocaleFallbackParentsV1Marker as :: icu_provider :: DataMarker > :: Yokeable ;
+pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> =
+    litemap::LiteMap::from_sorted_store_unchecked(&[("und", UND)]);
+static UND: &DataStruct = &::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1 {
+    parents: unsafe {
+        #[allow(unused_unsafe)]
+        ::zerovec::ZeroMap::from_parts_unchecked(
+            unsafe {
+                ::zerovec::VarZeroVec::from_bytes_unchecked(&[
+                    131u8, 0u8, 0u8, 0u8, 0u8, 0u8, 6u8, 0u8, 11u8, 0u8, 16u8, 0u8, 21u8, 0u8,
+                    26u8, 0u8, 31u8, 0u8, 36u8, 0u8, 41u8, 0u8, 46u8, 0u8, 51u8, 0u8, 56u8, 0u8,
+                    61u8, 0u8, 66u8, 0u8, 71u8, 0u8, 76u8, 0u8, 81u8, 0u8, 86u8, 0u8, 91u8, 0u8,
+                    96u8, 0u8, 101u8, 0u8, 106u8, 0u8, 111u8, 0u8, 116u8, 0u8, 121u8, 0u8, 126u8,
+                    0u8, 131u8, 0u8, 136u8, 0u8, 141u8, 0u8, 146u8, 0u8, 151u8, 0u8, 156u8, 0u8,
+                    161u8, 0u8, 166u8, 0u8, 171u8, 0u8, 176u8, 0u8, 181u8, 0u8, 186u8, 0u8, 191u8,
+                    0u8, 196u8, 0u8, 201u8, 0u8, 206u8, 0u8, 211u8, 0u8, 216u8, 0u8, 221u8, 0u8,
+                    226u8, 0u8, 231u8, 0u8, 236u8, 0u8, 241u8, 0u8, 246u8, 0u8, 251u8, 0u8, 0u8,
+                    1u8, 5u8, 1u8, 10u8, 1u8, 15u8, 1u8, 20u8, 1u8, 25u8, 1u8, 30u8, 1u8, 35u8,
+                    1u8, 40u8, 1u8, 45u8, 1u8, 50u8, 1u8, 55u8, 1u8, 60u8, 1u8, 65u8, 1u8, 70u8,
+                    1u8, 75u8, 1u8, 80u8, 1u8, 85u8, 1u8, 90u8, 1u8, 95u8, 1u8, 100u8, 1u8, 105u8,
+                    1u8, 110u8, 1u8, 115u8, 1u8, 120u8, 1u8, 125u8, 1u8, 130u8, 1u8, 135u8, 1u8,
+                    140u8, 1u8, 145u8, 1u8, 150u8, 1u8, 155u8, 1u8, 160u8, 1u8, 165u8, 1u8, 170u8,
+                    1u8, 175u8, 1u8, 180u8, 1u8, 185u8, 1u8, 190u8, 1u8, 195u8, 1u8, 200u8, 1u8,
+                    205u8, 1u8, 210u8, 1u8, 215u8, 1u8, 220u8, 1u8, 225u8, 1u8, 230u8, 1u8, 235u8,
+                    1u8, 240u8, 1u8, 245u8, 1u8, 250u8, 1u8, 255u8, 1u8, 4u8, 2u8, 9u8, 2u8, 14u8,
+                    2u8, 19u8, 2u8, 24u8, 2u8, 29u8, 2u8, 34u8, 2u8, 39u8, 2u8, 44u8, 2u8, 49u8,
+                    2u8, 54u8, 2u8, 59u8, 2u8, 64u8, 2u8, 71u8, 2u8, 73u8, 2u8, 75u8, 2u8, 77u8,
+                    2u8, 82u8, 2u8, 87u8, 2u8, 92u8, 2u8, 97u8, 2u8, 102u8, 2u8, 107u8, 2u8, 112u8,
+                    2u8, 117u8, 2u8, 122u8, 2u8, 127u8, 2u8, 132u8, 2u8, 101u8, 110u8, 45u8, 49u8,
+                    53u8, 48u8, 101u8, 110u8, 45u8, 65u8, 71u8, 101u8, 110u8, 45u8, 65u8, 73u8,
+                    101u8, 110u8, 45u8, 65u8, 84u8, 101u8, 110u8, 45u8, 65u8, 85u8, 101u8, 110u8,
+                    45u8, 66u8, 66u8, 101u8, 110u8, 45u8, 66u8, 69u8, 101u8, 110u8, 45u8, 66u8,
+                    77u8, 101u8, 110u8, 45u8, 66u8, 83u8, 101u8, 110u8, 45u8, 66u8, 87u8, 101u8,
+                    110u8, 45u8, 66u8, 90u8, 101u8, 110u8, 45u8, 67u8, 67u8, 101u8, 110u8, 45u8,
+                    67u8, 72u8, 101u8, 110u8, 45u8, 67u8, 75u8, 101u8, 110u8, 45u8, 67u8, 77u8,
+                    101u8, 110u8, 45u8, 67u8, 88u8, 101u8, 110u8, 45u8, 67u8, 89u8, 101u8, 110u8,
+                    45u8, 68u8, 69u8, 101u8, 110u8, 45u8, 68u8, 71u8, 101u8, 110u8, 45u8, 68u8,
+                    75u8, 101u8, 110u8, 45u8, 68u8, 77u8, 101u8, 110u8, 45u8, 69u8, 82u8, 101u8,
+                    110u8, 45u8, 70u8, 73u8, 101u8, 110u8, 45u8, 70u8, 74u8, 101u8, 110u8, 45u8,
+                    70u8, 75u8, 101u8, 110u8, 45u8, 70u8, 77u8, 101u8, 110u8, 45u8, 71u8, 66u8,
+                    101u8, 110u8, 45u8, 71u8, 68u8, 101u8, 110u8, 45u8, 71u8, 71u8, 101u8, 110u8,
+                    45u8, 71u8, 72u8, 101u8, 110u8, 45u8, 71u8, 73u8, 101u8, 110u8, 45u8, 71u8,
+                    77u8, 101u8, 110u8, 45u8, 71u8, 89u8, 101u8, 110u8, 45u8, 72u8, 75u8, 101u8,
+                    110u8, 45u8, 73u8, 69u8, 101u8, 110u8, 45u8, 73u8, 76u8, 101u8, 110u8, 45u8,
+                    73u8, 77u8, 101u8, 110u8, 45u8, 73u8, 78u8, 101u8, 110u8, 45u8, 73u8, 79u8,
+                    101u8, 110u8, 45u8, 74u8, 69u8, 101u8, 110u8, 45u8, 74u8, 77u8, 101u8, 110u8,
+                    45u8, 75u8, 69u8, 101u8, 110u8, 45u8, 75u8, 73u8, 101u8, 110u8, 45u8, 75u8,
+                    78u8, 101u8, 110u8, 45u8, 75u8, 89u8, 101u8, 110u8, 45u8, 76u8, 67u8, 101u8,
+                    110u8, 45u8, 76u8, 82u8, 101u8, 110u8, 45u8, 76u8, 83u8, 101u8, 110u8, 45u8,
+                    77u8, 71u8, 101u8, 110u8, 45u8, 77u8, 79u8, 101u8, 110u8, 45u8, 77u8, 83u8,
+                    101u8, 110u8, 45u8, 77u8, 84u8, 101u8, 110u8, 45u8, 77u8, 85u8, 101u8, 110u8,
+                    45u8, 77u8, 86u8, 101u8, 110u8, 45u8, 77u8, 87u8, 101u8, 110u8, 45u8, 77u8,
+                    89u8, 101u8, 110u8, 45u8, 78u8, 65u8, 101u8, 110u8, 45u8, 78u8, 70u8, 101u8,
+                    110u8, 45u8, 78u8, 71u8, 101u8, 110u8, 45u8, 78u8, 76u8, 101u8, 110u8, 45u8,
+                    78u8, 82u8, 101u8, 110u8, 45u8, 78u8, 85u8, 101u8, 110u8, 45u8, 78u8, 90u8,
+                    101u8, 110u8, 45u8, 80u8, 71u8, 101u8, 110u8, 45u8, 80u8, 75u8, 101u8, 110u8,
+                    45u8, 80u8, 78u8, 101u8, 110u8, 45u8, 80u8, 87u8, 101u8, 110u8, 45u8, 82u8,
+                    87u8, 101u8, 110u8, 45u8, 83u8, 66u8, 101u8, 110u8, 45u8, 83u8, 67u8, 101u8,
+                    110u8, 45u8, 83u8, 68u8, 101u8, 110u8, 45u8, 83u8, 69u8, 101u8, 110u8, 45u8,
+                    83u8, 71u8, 101u8, 110u8, 45u8, 83u8, 72u8, 101u8, 110u8, 45u8, 83u8, 73u8,
+                    101u8, 110u8, 45u8, 83u8, 76u8, 101u8, 110u8, 45u8, 83u8, 83u8, 101u8, 110u8,
+                    45u8, 83u8, 88u8, 101u8, 110u8, 45u8, 83u8, 90u8, 101u8, 110u8, 45u8, 84u8,
+                    67u8, 101u8, 110u8, 45u8, 84u8, 75u8, 101u8, 110u8, 45u8, 84u8, 79u8, 101u8,
+                    110u8, 45u8, 84u8, 84u8, 101u8, 110u8, 45u8, 84u8, 86u8, 101u8, 110u8, 45u8,
+                    84u8, 90u8, 101u8, 110u8, 45u8, 85u8, 71u8, 101u8, 110u8, 45u8, 86u8, 67u8,
+                    101u8, 110u8, 45u8, 86u8, 71u8, 101u8, 110u8, 45u8, 86u8, 85u8, 101u8, 110u8,
+                    45u8, 87u8, 83u8, 101u8, 110u8, 45u8, 90u8, 65u8, 101u8, 110u8, 45u8, 90u8,
+                    77u8, 101u8, 110u8, 45u8, 90u8, 87u8, 101u8, 115u8, 45u8, 65u8, 82u8, 101u8,
+                    115u8, 45u8, 66u8, 79u8, 101u8, 115u8, 45u8, 66u8, 82u8, 101u8, 115u8, 45u8,
+                    66u8, 90u8, 101u8, 115u8, 45u8, 67u8, 76u8, 101u8, 115u8, 45u8, 67u8, 79u8,
+                    101u8, 115u8, 45u8, 67u8, 82u8, 101u8, 115u8, 45u8, 67u8, 85u8, 101u8, 115u8,
+                    45u8, 68u8, 79u8, 101u8, 115u8, 45u8, 69u8, 67u8, 101u8, 115u8, 45u8, 71u8,
+                    84u8, 101u8, 115u8, 45u8, 72u8, 78u8, 101u8, 115u8, 45u8, 77u8, 88u8, 101u8,
+                    115u8, 45u8, 78u8, 73u8, 101u8, 115u8, 45u8, 80u8, 65u8, 101u8, 115u8, 45u8,
+                    80u8, 69u8, 101u8, 115u8, 45u8, 80u8, 82u8, 101u8, 115u8, 45u8, 80u8, 89u8,
+                    101u8, 115u8, 45u8, 83u8, 86u8, 101u8, 115u8, 45u8, 85u8, 83u8, 101u8, 115u8,
+                    45u8, 85u8, 89u8, 101u8, 115u8, 45u8, 86u8, 69u8, 104u8, 105u8, 45u8, 76u8,
+                    97u8, 116u8, 110u8, 104u8, 116u8, 110u8, 98u8, 110u8, 110u8, 112u8, 116u8,
+                    45u8, 65u8, 79u8, 112u8, 116u8, 45u8, 67u8, 72u8, 112u8, 116u8, 45u8, 67u8,
+                    86u8, 112u8, 116u8, 45u8, 70u8, 82u8, 112u8, 116u8, 45u8, 71u8, 81u8, 112u8,
+                    116u8, 45u8, 71u8, 87u8, 112u8, 116u8, 45u8, 76u8, 85u8, 112u8, 116u8, 45u8,
+                    77u8, 79u8, 112u8, 116u8, 45u8, 77u8, 90u8, 112u8, 116u8, 45u8, 83u8, 84u8,
+                    112u8, 116u8, 45u8, 84u8, 76u8, 122u8, 104u8, 45u8, 72u8, 97u8, 110u8, 116u8,
+                    45u8, 77u8, 79u8,
+                ])
+            },
+            unsafe {
+                ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                    101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8,
+                    48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
+                    49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
+                    110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 115u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8,
+                    57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8,
+                    115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8,
+                    57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8,
+                    115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
+                    52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8,
+                    57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8,
+                    115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 110u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 73u8, 78u8, 0u8, 102u8, 114u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 1u8, 72u8, 84u8, 0u8, 110u8, 111u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 110u8, 111u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8,
+                    84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8,
+                    112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 122u8, 104u8, 0u8, 1u8, 72u8, 97u8, 110u8,
+                    116u8, 1u8, 72u8, 75u8, 0u8,
+                ])
+            },
+        )
+    },
+};
diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1.rs b/compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1.rs
new file mode 100644 (file)
index 0000000..7df33c1
--- /dev/null
@@ -0,0 +1,41 @@
+// @generated
+type DataStruct = < :: icu_provider_adapters :: fallback :: provider :: CollationFallbackSupplementV1Marker as :: icu_provider :: DataMarker > :: Yokeable ;
+pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> =
+    litemap::LiteMap::from_sorted_store_unchecked(&[("und", UND)]);
+static UND: &DataStruct =
+    &::icu_provider_adapters::fallback::provider::LocaleFallbackSupplementV1 {
+        parents: unsafe {
+            #[allow(unused_unsafe)]
+            ::zerovec::ZeroMap::from_parts_unchecked(
+                unsafe {
+                    ::zerovec::VarZeroVec::from_bytes_unchecked(&[
+                        1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 121u8, 117u8, 101u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::ZeroVec::from_bytes_unchecked(&[
+                        122u8, 104u8, 0u8, 1u8, 72u8, 97u8, 110u8, 116u8, 0u8, 0u8, 0u8, 0u8,
+                    ])
+                },
+            )
+        },
+        unicode_extension_defaults: unsafe {
+            #[allow(unused_unsafe)]
+            ::zerovec::ZeroMap2d::from_parts_unchecked(
+                unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(&[99u8, 111u8]) },
+                unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(&[2u8, 0u8, 0u8, 0u8]) },
+                unsafe {
+                    ::zerovec::VarZeroVec::from_bytes_unchecked(&[
+                        2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 122u8, 104u8, 122u8, 104u8, 45u8,
+                        72u8, 97u8, 110u8, 116u8,
+                    ])
+                },
+                unsafe {
+                    ::zerovec::VarZeroVec::from_bytes_unchecked(&[
+                        2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 6u8, 0u8, 112u8, 105u8, 110u8, 121u8, 105u8,
+                        110u8, 115u8, 116u8, 114u8, 111u8, 107u8, 101u8,
+                    ])
+                },
+            )
+        },
+    };
diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/supplement/mod.rs b/compiler/rustc_baked_icu_data/src/data/fallback/supplement/mod.rs
new file mode 100644 (file)
index 0000000..6295713
--- /dev/null
@@ -0,0 +1,2 @@
+// @generated
+pub mod co_v1;
diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1.rs b/compiler/rustc_baked_icu_data/src/data/list/and_v1.rs
new file mode 100644 (file)
index 0000000..9cae549
--- /dev/null
@@ -0,0 +1,1161 @@
+// @generated
+type DataStruct = <::icu_list::provider::AndListV1Marker as ::icu_provider::DataMarker>::Yokeable;
+pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> =
+    litemap::LiteMap::from_sorted_store_unchecked(&[
+        ("en", EN),
+        ("es", ES),
+        ("fr", FR),
+        ("it", IT),
+        ("ja", JA),
+        ("pt", PT),
+        ("ru", RU),
+        ("tr", TR),
+        ("und", UND),
+        ("zh", ZH_ZH_HANS),
+        ("zh-Hans", ZH_ZH_HANS),
+        ("zh-Hant", ZH_HANT),
+    ]);
+static EN: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", and ", 6u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" and ", 5u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", & ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" & ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+]);
+static ES: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+        },
+        special_case: Some(::icu_list::provider::SpecialCasePattern {
+            condition: unsafe {
+                ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+                    114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+                    97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+                    45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+                    0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+                    15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+                    16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+                    21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+                    23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+                    27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+                    0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+                    0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+                    104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+                    4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+                    23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+                    0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+                    0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+                    25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+                    0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+                    18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+                    0u8, 35u8, 0u8, 0u8, 0u8,
+                ])
+            },
+            pattern: unsafe {
+                ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+            },
+        }),
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+        },
+        special_case: Some(::icu_list::provider::SpecialCasePattern {
+            condition: unsafe {
+                ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+                    114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+                    97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+                    45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+                    0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+                    15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+                    16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+                    21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+                    23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+                    27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+                    0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+                    0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+                    104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+                    4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+                    23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+                    0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+                    0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+                    25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+                    0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+                    18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+                    0u8, 35u8, 0u8, 0u8, 0u8,
+                ])
+            },
+            pattern: unsafe {
+                ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+            },
+        }),
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+        },
+        special_case: Some(::icu_list::provider::SpecialCasePattern {
+            condition: unsafe {
+                ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+                    114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+                    97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+                    45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+                    0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+                    15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+                    16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+                    21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+                    23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+                    27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+                    0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+                    0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+                    104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+                    4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+                    23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+                    0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+                    0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+                    25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+                    0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+                    18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+                    0u8, 35u8, 0u8, 0u8, 0u8,
+                ])
+            },
+            pattern: unsafe {
+                ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+            },
+        }),
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+        },
+        special_case: Some(::icu_list::provider::SpecialCasePattern {
+            condition: unsafe {
+                ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+                    114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+                    97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+                    45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+                    0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+                    15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+                    16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+                    21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+                    23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+                    27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+                    0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+                    0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+                    104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+                    4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+                    23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+                    0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+                    0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+                    25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+                    0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+                    18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+                    0u8, 35u8, 0u8, 0u8, 0u8,
+                ])
+            },
+            pattern: unsafe {
+                ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+            },
+        }),
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+        },
+        special_case: Some(::icu_list::provider::SpecialCasePattern {
+            condition: unsafe {
+                ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+                    114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+                    97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+                    45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+                    0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+                    15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+                    16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+                    21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+                    23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+                    27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+                    0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+                    0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+                    104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+                    4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+                    23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+                    0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+                    0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+                    25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+                    0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+                    18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+                    0u8, 35u8, 0u8, 0u8, 0u8,
+                ])
+            },
+            pattern: unsafe {
+                ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+            },
+        }),
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+        },
+        special_case: Some(::icu_list::provider::SpecialCasePattern {
+            condition: unsafe {
+                ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+                    114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+                    97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+                    45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+                    0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+                    7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+                    14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+                    15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+                    16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+                    17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+                    19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+                    21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+                    23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+                    27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+                    0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+                    0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+                    0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+                    104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+                    4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+                    23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+                    0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+                    0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+                    25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+                    191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+                    221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+                    0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+                    0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+                    18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+                    0u8, 35u8, 0u8, 0u8, 0u8,
+                ])
+            },
+            pattern: unsafe {
+                ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+            },
+        }),
+    },
+]);
+static FR: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+]);
+static IT: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+]);
+static JA: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+]);
+static PT: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+]);
+static RU: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+]);
+static TR: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+]);
+static UND: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+        },
+        special_case: None,
+    },
+]);
+static ZH_HANT: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+]);
+static ZH_ZH_HANS: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+    ::icu_list::provider::ConditionalListJoinerPattern {
+        default: unsafe {
+            ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+        },
+        special_case: None,
+    },
+]);
diff --git a/compiler/rustc_baked_icu_data/src/data/list/mod.rs b/compiler/rustc_baked_icu_data/src/data/list/mod.rs
new file mode 100644 (file)
index 0000000..9318225
--- /dev/null
@@ -0,0 +1,2 @@
+// @generated
+pub mod and_v1;
diff --git a/compiler/rustc_baked_icu_data/src/data/mod.rs b/compiler/rustc_baked_icu_data/src/data/mod.rs
new file mode 100644 (file)
index 0000000..a6a71c7
--- /dev/null
@@ -0,0 +1,90 @@
+// @generated
+mod fallback;
+mod list;
+/// This data provider was programmatically generated by [`icu_datagen`](
+/// https://unicode-org.github.io/icu4x-docs/doc/icu_datagen/enum.Out.html#variant.Module).
+#[non_exhaustive]
+pub struct BakedDataProvider;
+use ::icu_provider::prelude::*;
+impl DataProvider<::icu_list::provider::AndListV1Marker> for BakedDataProvider {
+    fn load(
+        &self,
+        req: DataRequest,
+    ) -> Result<DataResponse<::icu_list::provider::AndListV1Marker>, DataError> {
+        Ok(DataResponse {
+            metadata: Default::default(),
+            payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from(
+                *list::and_v1::DATA
+                    .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
+                    .ok_or_else(|| {
+                        DataErrorKind::MissingLocale
+                            .with_req(::icu_list::provider::AndListV1Marker::KEY, req)
+                    })?,
+            ))),
+        })
+    }
+}
+impl DataProvider<::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker>
+    for BakedDataProvider
+{
+    fn load(
+        &self,
+        req: DataRequest,
+    ) -> Result<
+        DataResponse<
+            ::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker,
+        >,
+        DataError,
+    > {
+        Ok(DataResponse {
+            metadata: Default::default(),
+            payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from(
+                *fallback::supplement::co_v1::DATA.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).ok_or_else(|| {
+                    DataErrorKind::MissingLocale.with_req(::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker::KEY, req)
+                })?,
+            ))),
+        })
+    }
+}
+impl DataProvider<::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker>
+    for BakedDataProvider
+{
+    fn load(
+        &self,
+        req: DataRequest,
+    ) -> Result<
+        DataResponse<
+            ::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker,
+        >,
+        DataError,
+    > {
+        Ok(DataResponse {
+            metadata: Default::default(),
+            payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from(
+                *fallback::likelysubtags_v1::DATA.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).ok_or_else(|| {
+                    DataErrorKind::MissingLocale.with_req(::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker::KEY, req)
+                })?,
+            ))),
+        })
+    }
+}
+impl DataProvider<::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker>
+    for BakedDataProvider
+{
+    fn load(
+        &self,
+        req: DataRequest,
+    ) -> Result<
+        DataResponse<::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker>,
+        DataError,
+    > {
+        Ok(DataResponse {
+            metadata: Default::default(),
+            payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from(
+                *fallback::parents_v1::DATA.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).ok_or_else(|| {
+                    DataErrorKind::MissingLocale.with_req(::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker::KEY, req)
+                })?,
+            ))),
+        })
+    }
+}
diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs
new file mode 100644 (file)
index 0000000..4651e03
--- /dev/null
@@ -0,0 +1,46 @@
+//! This crate contains pre-baked ICU4X data, generated by `icu4x-datagen`. The tool
+//! fetches locale data from CLDR and transforms them into const code in statics that
+//! ICU4X can load, via databake. `lib.rs` in this crate is manually written, but all
+//! other code is generated.
+//!
+//! This crate can be regenerated when there's a new CLDR version, though that is unlikely
+//! to result in changes in most cases (currently this only covers list formatting data, which
+//! is rather stable). It may need to be regenerated when updating ICU4X versions, especially
+//! across major versions, in case it fails to compile after an update.
+//!
+//! It must be regenerated when adding new locales to Rust, or if Rust's usage of ICU4X
+//! grows to need more kinds of data.
+//!
+//! To regenerate the data, run this command:
+//!
+//! ```text
+//! icu4x-datagen -W --pretty --fingerprint --use-separate-crates \
+//! --format mod -l en es fr it ja pt ru tr zh zh-Hans zh-Hant \
+//! -k list/and@1 fallback/likelysubtags@1 fallback/parents@1 fallback/supplement/co@1 \
+//! --cldr-tag latest --icuexport-tag latest -o src/data
+//! ```
+#![allow(elided_lifetimes_in_paths)]
+
+mod data {
+    include!("data/mod.rs");
+    include!("data/any.rs");
+}
+
+pub use data::BakedDataProvider;
+
+pub const fn baked_data_provider() -> BakedDataProvider {
+    data::BakedDataProvider
+}
+
+pub mod supported_locales {
+    pub const EN: icu_locid::Locale = icu_locid::locale!("en");
+    pub const ES: icu_locid::Locale = icu_locid::locale!("es");
+    pub const FR: icu_locid::Locale = icu_locid::locale!("fr");
+    pub const IT: icu_locid::Locale = icu_locid::locale!("it");
+    pub const JA: icu_locid::Locale = icu_locid::locale!("ja");
+    pub const PT: icu_locid::Locale = icu_locid::locale!("pt");
+    pub const RU: icu_locid::Locale = icu_locid::locale!("ru");
+    pub const TR: icu_locid::Locale = icu_locid::locale!("tr");
+    pub const ZH_HANS: icu_locid::Locale = icu_locid::locale!("zh-Hans");
+    pub const ZH_HANT: icu_locid::Locale = icu_locid::locale!("zh-Hant");
+}
index 4a4887f19702f91149c053108308eaf0333c77d0..163170a1d1aa0cfda50cdf3a44854d6ac9a1129f 100644 (file)
@@ -19,7 +19,7 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_data_structures::vec_map::VecMap;
-use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{Diagnostic, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::bit_set::ChunkedBitSet;
@@ -192,13 +192,13 @@ fn do_mir_borrowck<'tcx>(
         }
     }
 
-    let mut errors = error::BorrowckErrors::new();
+    let mut errors = error::BorrowckErrors::new(infcx.tcx);
 
     // Gather the upvars of a closure, if any.
     let tables = tcx.typeck_opt_const_arg(def);
-    if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors {
-        infcx.set_tainted_by_errors();
-        errors.set_tainted_by_errors();
+    if let Some(e) = tables.tainted_by_errors {
+        infcx.set_tainted_by_errors(e);
+        errors.set_tainted_by_errors(e);
     }
     let upvars: Vec<_> = tables
         .closure_min_captures_flattened(def.did)
@@ -2260,6 +2260,7 @@ mod error {
     use super::*;
 
     pub struct BorrowckErrors<'tcx> {
+        tcx: TyCtxt<'tcx>,
         /// This field keeps track of move errors that are to be reported for given move indices.
         ///
         /// There are situations where many errors can be reported for a single move out (see #53807)
@@ -2282,19 +2283,24 @@ pub struct BorrowckErrors<'tcx> {
         tainted_by_errors: Option<ErrorGuaranteed>,
     }
 
-    impl BorrowckErrors<'_> {
-        pub fn new() -> Self {
+    impl<'tcx> BorrowckErrors<'tcx> {
+        pub fn new(tcx: TyCtxt<'tcx>) -> Self {
             BorrowckErrors {
+                tcx,
                 buffered_move_errors: BTreeMap::new(),
                 buffered: Default::default(),
                 tainted_by_errors: None,
             }
         }
 
-        // FIXME(eddyb) this is a suboptimal API because `tainted_by_errors` is
-        // set before any emission actually happens (weakening the guarantee).
         pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) {
-            self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+            if let None = self.tainted_by_errors {
+                self.tainted_by_errors = Some(
+                    self.tcx
+                        .sess
+                        .delay_span_bug(t.span.clone(), "diagnostic buffered but not emitted"),
+                )
+            }
             t.buffer(&mut self.buffered);
         }
 
@@ -2302,8 +2308,8 @@ pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_, ()>) {
             t.buffer(&mut self.buffered);
         }
 
-        pub fn set_tainted_by_errors(&mut self) {
-            self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+        pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) {
+            self.tainted_by_errors = Some(e);
         }
     }
 
index f8856b56d140bae139a7d069159b8bb813b28dd6..4a12e1b1b92e0f22b180dc566f47f9db2bd989b0 100644 (file)
@@ -303,7 +303,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
 
     if !nll_errors.is_empty() {
         // Suppress unhelpful extra errors in `infer_opaque_types`.
-        infcx.set_tainted_by_errors();
+        infcx.set_tainted_by_errors(infcx.tcx.sess.delay_span_bug(
+            body.span,
+            "`compute_regions` tainted `infcx` with errors but did not emit any errors",
+        ));
     }
 
     let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values);
index b2db77944fd1e9a5141e32aa579bd44c45793e4c..b9885952a893c55741e6e057f9c703f7adf45353 100644 (file)
@@ -219,8 +219,8 @@ fn infer_opaque_definition_from_instantiation(
         instantiated_ty: OpaqueHiddenType<'tcx>,
         origin: OpaqueTyOrigin,
     ) -> Ty<'tcx> {
-        if self.is_tainted_by_errors() {
-            return self.tcx.ty_error();
+        if let Some(e) = self.tainted_by_errors() {
+            return self.tcx.ty_error_with_guaranteed(e);
         }
 
         let definition_ty = instantiated_ty
index f72cd14bea0436e574a7a0f90ee26af58552fe72..4b57bdfbc8fb1a689cab2d099d56813027ffaa08 100644 (file)
@@ -3,8 +3,8 @@
     ptr::P,
     token,
     tokenstream::{DelimSpan, TokenStream, TokenTree},
-    BinOpKind, BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, Mutability,
-    Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID,
+    BinOpKind, BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, MethodCall,
+    Mutability, Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID,
 };
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
@@ -242,9 +242,9 @@ fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
                 self.manage_cond_expr(prefix);
                 self.manage_cond_expr(suffix);
             }
-            ExprKind::MethodCall(_, _,ref mut local_exprs, _) => {
-                for local_expr in local_exprs.iter_mut() {
-                    self.manage_cond_expr(local_expr);
+            ExprKind::MethodCall(ref mut call) => {
+                for arg in call.args.iter_mut() {
+                    self.manage_cond_expr(arg);
                 }
             }
             ExprKind::Path(_, Path { ref segments, .. }) if let &[ref path_segment] = &segments[..] => {
@@ -296,7 +296,7 @@ fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
             | ExprKind::Block(_, _)
             | ExprKind::Box(_)
             | ExprKind::Break(_, _)
-            | ExprKind::Closure(_, _, _, _, _, _, _)
+            | ExprKind::Closure(_)
             | ExprKind::ConstBlock(_)
             | ExprKind::Continue(_)
             | ExprKind::Err
@@ -442,12 +442,12 @@ fn expr_addr_of_mut(cx: &ExtCtxt<'_>, sp: Span, e: P<Expr>) -> P<Expr> {
 
 fn expr_method_call(
     cx: &ExtCtxt<'_>,
-    path: PathSegment,
+    seg: PathSegment,
     receiver: P<Expr>,
     args: Vec<P<Expr>>,
     span: Span,
 ) -> P<Expr> {
-    cx.expr(span, ExprKind::MethodCall(path, receiver, args, span))
+    cx.expr(span, ExprKind::MethodCall(Box::new(MethodCall { seg, receiver, args, span })))
 }
 
 fn expr_paren(cx: &ExtCtxt<'_>, sp: Span, e: P<Expr>) -> P<Expr> {
index 99059e788a074a12450d9022e210d27efc005978..1e22537c2ba42ac27202012738cf55ce004042b7 100644 (file)
@@ -22,7 +22,19 @@ fn clif_sig_from_fn_abi<'tcx>(
     default_call_conv: CallConv,
     fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
 ) -> Signature {
-    let call_conv = match fn_abi.conv {
+    let call_conv = conv_to_call_conv(fn_abi.conv, default_call_conv);
+
+    let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten();
+
+    let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx);
+    // Sometimes the first param is an pointer to the place where the return value needs to be stored.
+    let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect();
+
+    Signature { params, returns, call_conv }
+}
+
+pub(crate) fn conv_to_call_conv(c: Conv, default_call_conv: CallConv) -> CallConv {
+    match c {
         Conv::Rust | Conv::C => default_call_conv,
         Conv::RustCold => CallConv::Cold,
         Conv::X86_64SysV => CallConv::SystemV,
@@ -38,15 +50,8 @@ fn clif_sig_from_fn_abi<'tcx>(
         | Conv::X86VectorCall
         | Conv::AmdGpuKernel
         | Conv::AvrInterrupt
-        | Conv::AvrNonBlockingInterrupt => todo!("{:?}", fn_abi.conv),
-    };
-    let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten();
-
-    let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx);
-    // Sometimes the first param is an pointer to the place where the return value needs to be stored.
-    let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect();
-
-    Signature { params, returns, call_conv }
+        | Conv::AvrNonBlockingInterrupt => todo!("{:?}", c),
+    }
 }
 
 pub(crate) fn get_function_sig<'tcx>(
index cae6312a607351d93dc5101562c1760dbdb392a5..f7434633ea442b40fa30f4a85370135e8c134017 100644 (file)
@@ -63,10 +63,14 @@ fn create_entry_fn(
                 AbiParam::new(m.target_config().pointer_type()),
             ],
             returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
-            call_conv: CallConv::triple_default(m.isa().triple()),
+            call_conv: crate::conv_to_call_conv(
+                tcx.sess.target.options.entry_abi,
+                CallConv::triple_default(m.isa().triple()),
+            ),
         };
 
-        let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap();
+        let entry_name = tcx.sess.target.options.entry_name.as_ref();
+        let cmain_func_id = m.declare_function(entry_name, Linkage::Export, &cmain_sig).unwrap();
 
         let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
 
index 62a61eb8548da6b9d2a662ddb3be71b139297424..2e71c3665daa75ed3e1b096c0ca1bac99e74584c 100644 (file)
@@ -425,8 +425,9 @@ fn apply_target_cpu_attr(&self, _llfn: RValue<'gcc>) {
     }
 
     fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
-        if self.get_declared_value("main").is_none() {
-            Some(self.declare_cfn("main", fn_type))
+        let entry_name = self.sess().target.entry_name.as_ref();
+        if self.get_declared_value(entry_name).is_none() {
+            Some(self.declare_entry_fn(entry_name, fn_type, ()))
         }
         else {
             // If the symbol already exists, it is an error: for example, the user wrote
index a619e2f77125243a062ca7617c098f7a2ca562c7..eae77508c973abe0c0f50ab70a5e1935bcba246f 100644 (file)
@@ -65,13 +65,13 @@ pub fn declare_private_global(&self, name: &str, ty: Type<'gcc>) -> LValue<'gcc>
         global
     }
 
-    pub fn declare_cfn(&self, name: &str, _fn_type: Type<'gcc>) -> RValue<'gcc> {
+    pub fn declare_entry_fn(&self, name: &str, _fn_type: Type<'gcc>, callconv: () /*llvm::CCallConv*/) -> RValue<'gcc> {
         // TODO(antoyo): use the fn_type parameter.
         let const_string = self.context.new_type::<u8>().make_pointer().make_pointer();
         let return_type = self.type_i32();
         let variadic = false;
         self.linkage.set(FunctionType::Exported);
-        let func = declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, &[self.type_i32(), const_string], variadic);
+        let func = declare_raw_fn(self, name, callconv, return_type, &[self.type_i32(), const_string], variadic);
         // NOTE: it is needed to set the current_func here as well, because get_fn() is not called
         // for the main function.
         *self.current_func.borrow_mut() = Some(func);
index d478efc863a9e21fb7cb3863ed1bce2200e015b7..a6fd2a7de6bd04eb544c7d10f78111d8de5938e2 100644 (file)
@@ -398,23 +398,7 @@ fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
     }
 
     fn llvm_cconv(&self) -> llvm::CallConv {
-        match self.conv {
-            Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
-            Conv::RustCold => llvm::ColdCallConv,
-            Conv::AmdGpuKernel => llvm::AmdGpuKernel,
-            Conv::AvrInterrupt => llvm::AvrInterrupt,
-            Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
-            Conv::ArmAapcs => llvm::ArmAapcsCallConv,
-            Conv::Msp430Intr => llvm::Msp430Intr,
-            Conv::PtxKernel => llvm::PtxKernel,
-            Conv::X86Fastcall => llvm::X86FastcallCallConv,
-            Conv::X86Intr => llvm::X86_Intr,
-            Conv::X86Stdcall => llvm::X86StdcallCallConv,
-            Conv::X86ThisCall => llvm::X86_ThisCall,
-            Conv::X86VectorCall => llvm::X86_VectorCall,
-            Conv::X86_64SysV => llvm::X86_64_SysV,
-            Conv::X86_64Win64 => llvm::X86_64_Win64,
-        }
+        self.conv.into()
     }
 
     fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
@@ -596,3 +580,25 @@ fn get_param(&mut self, index: usize) -> Self::Value {
         llvm::get_param(self.llfn(), index as c_uint)
     }
 }
+
+impl From<Conv> for llvm::CallConv {
+    fn from(conv: Conv) -> Self {
+        match conv {
+            Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
+            Conv::RustCold => llvm::ColdCallConv,
+            Conv::AmdGpuKernel => llvm::AmdGpuKernel,
+            Conv::AvrInterrupt => llvm::AvrInterrupt,
+            Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
+            Conv::ArmAapcs => llvm::ArmAapcsCallConv,
+            Conv::Msp430Intr => llvm::Msp430Intr,
+            Conv::PtxKernel => llvm::PtxKernel,
+            Conv::X86Fastcall => llvm::X86FastcallCallConv,
+            Conv::X86Intr => llvm::X86_Intr,
+            Conv::X86Stdcall => llvm::X86StdcallCallConv,
+            Conv::X86ThisCall => llvm::X86_ThisCall,
+            Conv::X86VectorCall => llvm::X86_VectorCall,
+            Conv::X86_64SysV => llvm::X86_64_SysV,
+            Conv::X86_64Win64 => llvm::X86_64_Win64,
+        }
+    }
+}
index eaa2ccfc835c5f2564a58d53ff9522d87e3320e7..4dcc7cd54477def2a32ab3ea7e06b9f566b08b0c 100644 (file)
@@ -576,8 +576,14 @@ fn apply_target_cpu_attr(&self, llfn: &'ll Value) {
     }
 
     fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
-        if self.get_declared_value("main").is_none() {
-            Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type))
+        let entry_name = self.sess().target.entry_name.as_ref();
+        if self.get_declared_value(entry_name).is_none() {
+            Some(self.declare_entry_fn(
+                entry_name,
+                self.sess().target.entry_abi.into(),
+                llvm::UnnamedAddr::Global,
+                fn_type,
+            ))
         } else {
             // If the symbol already exists, it is an error: for example, the user wrote
             // #[no_mangle] extern "C" fn main(..) {..}
index f79ef11720df9b4436d83dd50674065b7e12a988..dc21a02cec44a144fef0c9704b3a16af5c1868d2 100644 (file)
@@ -90,6 +90,28 @@ pub fn declare_cfn(
         declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
     }
 
+    /// Declare an entry Function
+    ///
+    /// The ABI of this function can change depending on the target (although for now the same as
+    /// `declare_cfn`)
+    ///
+    /// If there’s a value with the same name already declared, the function will
+    /// update the declaration and return existing Value instead.
+    pub fn declare_entry_fn(
+        &self,
+        name: &str,
+        callconv: llvm::CallConv,
+        unnamed: llvm::UnnamedAddr,
+        fn_type: &'ll Type,
+    ) -> &'ll Value {
+        let visibility = if self.tcx.sess.target.default_hidden_visibility {
+            llvm::Visibility::Hidden
+        } else {
+            llvm::Visibility::Default
+        };
+        declare_raw_fn(self, name, callconv, unnamed, visibility, fn_type)
+    }
+
     /// Declare a Rust function.
     ///
     /// If there’s a value with the same name already declared, the function will
index 752f6b1ef40c92fcdd64994d03c715f9ad6ee90b..22f534d909ab6ca4ccab579d2003b535be8e8376 100644 (file)
@@ -180,7 +180,8 @@ fn exported_symbols_provider_local<'tcx>(
         .collect();
 
     if tcx.entry_fn(()).is_some() {
-        let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, "main"));
+        let exported_symbol =
+            ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref()));
 
         symbols.push((
             exported_symbol,
index e09a6d1d6f5aa890d0606ad6c0457391cd07eca3..51489e2936068c8519ddae244ec0006912098e2e 100644 (file)
@@ -7,6 +7,7 @@ edition = "2021"
 
 [dependencies]
 tracing = "0.1"
+either = "1"
 rustc_apfloat = { path = "../rustc_apfloat" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_attr = { path = "../rustc_attr" }
index f5942deaf9fa1ed2d7670a38eeeb934ac5579ea4..c777a840f3fb661cfd56c25a51b38d6d9c811606 100644 (file)
@@ -1,10 +1,7 @@
-use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr};
-use crate::interpret::eval_nullary_intrinsic;
-use crate::interpret::{
-    intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId,
-    Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy,
-    RefTracking, StackPopCleanup,
-};
+use std::borrow::Cow;
+use std::convert::TryInto;
+
+use either::{Left, Right};
 
 use rustc_hir::def::DefKind;
 use rustc_middle::mir;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::source_map::Span;
 use rustc_target::abi::{self, Abi};
-use std::borrow::Cow;
-use std::convert::TryInto;
+
+use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr};
+use crate::interpret::eval_nullary_intrinsic;
+use crate::interpret::{
+    intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId,
+    Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy,
+    RefTracking, StackPopCleanup,
+};
 
 const NOTE_ON_UNDEFINED_BEHAVIOR_ERROR: &str = "The rules on what exactly is undefined behavior aren't clear, \
      so this check might be overzealous. Please open an issue on the rustc \
@@ -135,14 +138,14 @@ pub(super) fn op_to_const<'tcx>(
         _ => false,
     };
     let immediate = if try_as_immediate {
-        Err(ecx.read_immediate(op).expect("normalization works on validated constants"))
+        Right(ecx.read_immediate(op).expect("normalization works on validated constants"))
     } else {
         // It is guaranteed that any non-slice scalar pair is actually ByRef here.
         // When we come back from raw const eval, we are always by-ref. The only way our op here is
         // by-val is if we are in destructure_mir_constant, i.e., if this is (a field of) something that we
         // "tried to make immediate" before. We wouldn't do that for non-slice scalar pairs or
         // structs containing such.
-        op.try_as_mplace()
+        op.as_mplace_or_imm()
     };
 
     debug!(?immediate);
@@ -168,9 +171,9 @@ pub(super) fn op_to_const<'tcx>(
         }
     };
     match immediate {
-        Ok(ref mplace) => to_const_value(mplace),
+        Left(ref mplace) => to_const_value(mplace),
         // see comment on `let try_as_immediate` above
-        Err(imm) => match *imm {
+        Right(imm) => match *imm {
             _ if imm.layout.is_zst() => ConstValue::ZeroSized,
             Immediate::Scalar(x) => ConstValue::Scalar(x),
             Immediate::ScalarPair(a, b) => {
index 35d58d2f638bfceb56d3699deba074b0c8bcc76c..04e68b96455251c2eeaa8651be41b7c88685b78f 100644 (file)
@@ -1,8 +1,12 @@
 use rustc_hir::def::DefKind;
+use rustc_hir::LangItem;
 use rustc_middle::mir;
+use rustc_middle::mir::interpret::PointerArithmetic;
+use rustc_middle::ty::layout::FnAbiOf;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use std::borrow::Borrow;
 use std::hash::Hash;
+use std::ops::ControlFlow;
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::fx::IndexEntry;
 use rustc_target::spec::abi::Abi as CallAbi;
 
 use crate::interpret::{
-    self, compile_time_machine, AllocId, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult,
-    OpTy, PlaceTy, Pointer, Scalar, StackPopUnwind,
+    self, compile_time_machine, AllocId, ConstAllocation, FnVal, Frame, ImmTy, InterpCx,
+    InterpResult, OpTy, PlaceTy, Pointer, Scalar, StackPopUnwind,
 };
 
 use super::error::*;
 
-impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
-    /// "Intercept" a function call to a panic-related function
-    /// because we have something special to do for it.
-    /// If this returns successfully (`Ok`), the function should just be evaluated normally.
-    fn hook_special_const_fn(
-        &mut self,
-        instance: ty::Instance<'tcx>,
-        args: &[OpTy<'tcx>],
-    ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
-        // All `#[rustc_do_not_const_check]` functions should be hooked here.
-        let def_id = instance.def_id();
-
-        if Some(def_id) == self.tcx.lang_items().panic_display()
-            || Some(def_id) == self.tcx.lang_items().begin_panic_fn()
-        {
-            // &str or &&str
-            assert!(args.len() == 1);
-
-            let mut msg_place = self.deref_operand(&args[0])?;
-            while msg_place.layout.ty.is_ref() {
-                msg_place = self.deref_operand(&msg_place.into())?;
-            }
-
-            let msg = Symbol::intern(self.read_str(&msg_place)?);
-            let span = self.find_closest_untracked_caller_location();
-            let (file, line, col) = self.location_triple_for_span(span);
-            return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into());
-        } else if Some(def_id) == self.tcx.lang_items().panic_fmt() {
-            // For panic_fmt, call const_panic_fmt instead.
-            if let Some(const_panic_fmt) = self.tcx.lang_items().const_panic_fmt() {
-                return Ok(Some(
-                    ty::Instance::resolve(
-                        *self.tcx,
-                        ty::ParamEnv::reveal_all(),
-                        const_panic_fmt,
-                        self.tcx.intern_substs(&[]),
-                    )
-                    .unwrap()
-                    .unwrap(),
-                ));
-            }
-        }
-        Ok(None)
-    }
-}
-
 /// Extra machine state for CTFE, and the Machine instance
 pub struct CompileTimeInterpreter<'mir, 'tcx> {
     /// For now, the number of terminators that can be evaluated before we throw a resource
@@ -191,6 +149,125 @@ fn may_leak(self) -> bool {
 }
 
 impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
+    /// "Intercept" a function call, because we have something special to do for it.
+    /// All `#[rustc_do_not_const_check]` functions should be hooked here.
+    /// If this returns `Some` function, which may be `instance` or a different function with
+    /// compatible arguments, then evaluation should continue with that function.
+    /// If this returns `None`, the function call has been handled and the function has returned.
+    fn hook_special_const_fn(
+        &mut self,
+        instance: ty::Instance<'tcx>,
+        args: &[OpTy<'tcx>],
+        dest: &PlaceTy<'tcx>,
+        ret: Option<mir::BasicBlock>,
+    ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
+        let def_id = instance.def_id();
+
+        if Some(def_id) == self.tcx.lang_items().panic_display()
+            || Some(def_id) == self.tcx.lang_items().begin_panic_fn()
+        {
+            // &str or &&str
+            assert!(args.len() == 1);
+
+            let mut msg_place = self.deref_operand(&args[0])?;
+            while msg_place.layout.ty.is_ref() {
+                msg_place = self.deref_operand(&msg_place.into())?;
+            }
+
+            let msg = Symbol::intern(self.read_str(&msg_place)?);
+            let span = self.find_closest_untracked_caller_location();
+            let (file, line, col) = self.location_triple_for_span(span);
+            return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into());
+        } else if Some(def_id) == self.tcx.lang_items().panic_fmt() {
+            // For panic_fmt, call const_panic_fmt instead.
+            let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None);
+            let new_instance = ty::Instance::resolve(
+                *self.tcx,
+                ty::ParamEnv::reveal_all(),
+                const_def_id,
+                instance.substs,
+            )
+            .unwrap()
+            .unwrap();
+
+            return Ok(Some(new_instance));
+        } else if Some(def_id) == self.tcx.lang_items().align_offset_fn() {
+            // For align_offset, we replace the function call if the pointer has no address.
+            match self.align_offset(instance, args, dest, ret)? {
+                ControlFlow::Continue(()) => return Ok(Some(instance)),
+                ControlFlow::Break(()) => return Ok(None),
+            }
+        }
+        Ok(Some(instance))
+    }
+
+    /// `align_offset(ptr, target_align)` needs special handling in const eval, because the pointer
+    /// may not have an address.
+    ///
+    /// If `ptr` does have a known address, then we return `CONTINUE` and the function call should
+    /// proceed as normal.
+    ///
+    /// If `ptr` doesn't have an address, but its underlying allocation's alignment is at most
+    /// `target_align`, then we call the function again with an dummy address relative to the
+    /// allocation.
+    ///
+    /// If `ptr` doesn't have an address and `target_align` is stricter than the underlying
+    /// allocation's alignment, then we return `usize::MAX` immediately.
+    fn align_offset(
+        &mut self,
+        instance: ty::Instance<'tcx>,
+        args: &[OpTy<'tcx>],
+        dest: &PlaceTy<'tcx>,
+        ret: Option<mir::BasicBlock>,
+    ) -> InterpResult<'tcx, ControlFlow<()>> {
+        assert_eq!(args.len(), 2);
+
+        let ptr = self.read_pointer(&args[0])?;
+        let target_align = self.read_scalar(&args[1])?.to_machine_usize(self)?;
+
+        if !target_align.is_power_of_two() {
+            throw_ub_format!("`align_offset` called with non-power-of-two align: {}", target_align);
+        }
+
+        match self.ptr_try_get_alloc_id(ptr) {
+            Ok((alloc_id, offset, _extra)) => {
+                let (_size, alloc_align, _kind) = self.get_alloc_info(alloc_id);
+
+                if target_align <= alloc_align.bytes() {
+                    // Extract the address relative to the allocation base that is definitely
+                    // sufficiently aligned and call `align_offset` again.
+                    let addr = ImmTy::from_uint(offset.bytes(), args[0].layout).into();
+                    let align = ImmTy::from_uint(target_align, args[1].layout).into();
+                    let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?;
+
+                    // We replace the entire entire function call with a "tail call".
+                    // Note that this happens before the frame of the original function
+                    // is pushed on the stack.
+                    self.eval_fn_call(
+                        FnVal::Instance(instance),
+                        (CallAbi::Rust, fn_abi),
+                        &[addr, align],
+                        /* with_caller_location = */ false,
+                        dest,
+                        ret,
+                        StackPopUnwind::NotAllowed,
+                    )?;
+                    Ok(ControlFlow::BREAK)
+                } else {
+                    // Not alignable in const, return `usize::MAX`.
+                    let usize_max = Scalar::from_machine_usize(self.machine_usize_max(), self);
+                    self.write_scalar(usize_max, dest)?;
+                    self.return_to_block(ret)?;
+                    Ok(ControlFlow::BREAK)
+                }
+            }
+            Err(_addr) => {
+                // The pointer has an address, continue with function call.
+                Ok(ControlFlow::CONTINUE)
+            }
+        }
+    }
+
     /// See documentation on the `ptr_guaranteed_cmp` intrinsic.
     fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
         Ok(match (a, b) {
@@ -271,8 +348,8 @@ fn find_mir_or_eval_fn(
         instance: ty::Instance<'tcx>,
         _abi: CallAbi,
         args: &[OpTy<'tcx>],
-        _dest: &PlaceTy<'tcx>,
-        _ret: Option<mir::BasicBlock>,
+        dest: &PlaceTy<'tcx>,
+        ret: Option<mir::BasicBlock>,
         _unwind: StackPopUnwind, // unwinding is not supported in consts
     ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
         debug!("find_mir_or_eval_fn: {:?}", instance);
@@ -291,7 +368,11 @@ fn find_mir_or_eval_fn(
                 }
             }
 
-            if let Some(new_instance) = ecx.hook_special_const_fn(instance, args)? {
+            let Some(new_instance) = ecx.hook_special_const_fn(instance, args, dest, ret)? else {
+                return Ok(None);
+            };
+
+            if new_instance != instance {
                 // We call another const fn instead.
                 // However, we return the *original* instance to make backtraces work out
                 // (and we hope this does not confuse the FnAbi checks too much).
@@ -300,13 +381,14 @@ fn find_mir_or_eval_fn(
                     new_instance,
                     _abi,
                     args,
-                    _dest,
-                    _ret,
+                    dest,
+                    ret,
                     _unwind,
                 )?
                 .map(|(body, _instance)| (body, instance)));
             }
         }
+
         // This is a const fn. Call it.
         Ok(Some((ecx.load_mir(instance.def, None)?, instance)))
     }
index ed69d8554d2cc8b6c82d755f278bfa709056db23..79450fccfc4d8567e377320463034e0ebef3f15d 100644 (file)
@@ -2,6 +2,8 @@
 use std::fmt;
 use std::mem;
 
+use either::{Either, Left, Right};
+
 use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir;
@@ -23,7 +25,7 @@
     MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, PointerArithmetic, Provenance,
     Scalar, StackPopJump,
 };
-use crate::transform::validate::equal_up_to_regions;
+use crate::util;
 
 pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
     /// Stores the `Machine` instance.
@@ -121,13 +123,12 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = AllocId, Extra = ()> {
     ////////////////////////////////////////////////////////////////////////////////
     // Current position within the function
     ////////////////////////////////////////////////////////////////////////////////
-    /// If this is `Err`, we are not currently executing any particular statement in
+    /// If this is `Right`, we are not currently executing any particular statement in
     /// this frame (can happen e.g. during frame initialization, and during unwinding on
     /// frames without cleanup code).
-    /// We basically abuse `Result` as `Either`.
     ///
     /// Needs to be public because ConstProp does unspeakable things to it.
-    pub loc: Result<mir::Location, Span>,
+    pub loc: Either<mir::Location, Span>,
 }
 
 /// What we store about a frame in an interpreter backtrace.
@@ -227,25 +228,24 @@ pub fn with_extra<Extra>(self, extra: Extra) -> Frame<'mir, 'tcx, Prov, Extra> {
 impl<'mir, 'tcx, Prov: Provenance, Extra> Frame<'mir, 'tcx, Prov, Extra> {
     /// Get the current location within the Frame.
     ///
-    /// If this is `Err`, we are not currently executing any particular statement in
+    /// If this is `Left`, we are not currently executing any particular statement in
     /// this frame (can happen e.g. during frame initialization, and during unwinding on
     /// frames without cleanup code).
-    /// We basically abuse `Result` as `Either`.
     ///
     /// Used by priroda.
-    pub fn current_loc(&self) -> Result<mir::Location, Span> {
+    pub fn current_loc(&self) -> Either<mir::Location, Span> {
         self.loc
     }
 
     /// Return the `SourceInfo` of the current instruction.
     pub fn current_source_info(&self) -> Option<&mir::SourceInfo> {
-        self.loc.ok().map(|loc| self.body.source_info(loc))
+        self.loc.left().map(|loc| self.body.source_info(loc))
     }
 
     pub fn current_span(&self) -> Span {
         match self.loc {
-            Ok(loc) => self.body.source_info(loc).span,
-            Err(span) => span,
+            Left(loc) => self.body.source_info(loc).span,
+            Right(span) => span,
         }
     }
 }
@@ -354,8 +354,8 @@ pub(super) fn mir_assign_valid_types<'tcx>(
     // Type-changing assignments can happen when subtyping is used. While
     // all normal lifetimes are erased, higher-ranked types with their
     // late-bound lifetimes are still around and can lead to type
-    // differences. So we compare ignoring lifetimes.
-    if equal_up_to_regions(tcx, param_env, src.ty, dest.ty) {
+    // differences.
+    if util::is_subtype(tcx, param_env, src.ty, dest.ty) {
         // Make sure the layout is equal, too -- just to be safe. Miri really
         // needs layout equality. For performance reason we skip this check when
         // the types are equal. Equal types *can* have different layouts when
@@ -679,7 +679,7 @@ pub fn push_stack_frame(
         // first push a stack frame so we have access to the local substs
         let pre_frame = Frame {
             body,
-            loc: Err(body.span), // Span used for errors caused during preamble.
+            loc: Right(body.span), // Span used for errors caused during preamble.
             return_to_block,
             return_place: return_place.clone(),
             // empty local array, we fill it in below, after we are inside the stack frame and
@@ -713,7 +713,7 @@ pub fn push_stack_frame(
         // done
         self.frame_mut().locals = locals;
         M::after_stack_push(self)?;
-        self.frame_mut().loc = Ok(mir::Location::START);
+        self.frame_mut().loc = Left(mir::Location::START);
 
         let span = info_span!("frame", "{}", instance);
         self.frame_mut().tracing_span.enter(span);
@@ -724,7 +724,7 @@ pub fn push_stack_frame(
     /// Jump to the given block.
     #[inline]
     pub fn go_to_block(&mut self, target: mir::BasicBlock) {
-        self.frame_mut().loc = Ok(mir::Location { block: target, statement_index: 0 });
+        self.frame_mut().loc = Left(mir::Location { block: target, statement_index: 0 });
     }
 
     /// *Return* to the given `target` basic block.
@@ -750,8 +750,8 @@ pub fn return_to_block(&mut self, target: Option<mir::BasicBlock>) -> InterpResu
     /// unwinding, and doing so is UB.
     pub fn unwind_to_block(&mut self, target: StackPopUnwind) -> InterpResult<'tcx> {
         self.frame_mut().loc = match target {
-            StackPopUnwind::Cleanup(block) => Ok(mir::Location { block, statement_index: 0 }),
-            StackPopUnwind::Skip => Err(self.frame_mut().body.span),
+            StackPopUnwind::Cleanup(block) => Left(mir::Location { block, statement_index: 0 }),
+            StackPopUnwind::Skip => Right(self.frame_mut().body.span),
             StackPopUnwind::NotAllowed => {
                 throw_ub_format!("unwinding past a stack frame that does not allow unwinding")
             }
@@ -783,8 +783,8 @@ pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx>
         assert_eq!(
             unwinding,
             match self.frame().loc {
-                Ok(loc) => self.body().basic_blocks[loc.block].is_cleanup,
-                Err(_) => true,
+                Left(loc) => self.body().basic_blocks[loc.block].is_cleanup,
+                Right(_) => true,
             }
         );
         if unwinding && self.frame_idx() == 0 {
index 6fc2407b778034044d558eac875a9cff2fe030f8..7940efcd2b11f1517a22631f0d5a4d77616ece7d 100644 (file)
@@ -243,6 +243,11 @@ pub fn emulate_intrinsic(
                 let discr_val = self.read_discriminant(&place.into())?.0;
                 self.write_scalar(discr_val, dest)?;
             }
+            sym::exact_div => {
+                let l = self.read_immediate(&args[0])?;
+                let r = self.read_immediate(&args[1])?;
+                self.exact_div(&l, &r, dest)?;
+            }
             sym::unchecked_shl
             | sym::unchecked_shr
             | sym::unchecked_add
index 0e3867557ada3c6694eee61948dabf5200830d68..7d94a22c43d71e467d3c8eeed2963ebc0dbcbff4 100644 (file)
@@ -19,8 +19,8 @@ pub(crate) fn find_closest_untracked_caller_location(&self) -> Span {
             debug!("find_closest_untracked_caller_location: checking frame {:?}", frame.instance);
 
             // Assert that the frame we look at is actually executing code currently
-            // (`loc` is `Err` when we are unwinding and the frame does not require cleanup).
-            let loc = frame.loc.unwrap();
+            // (`loc` is `Right` when we are unwinding and the frame does not require cleanup).
+            let loc = frame.loc.left().unwrap();
 
             // This could be a non-`Call` terminator (such as `Drop`), or not a terminator at all
             // (such as `box`). Use the normal span by default.
index cf9202540c7fe48b0f9fc37dd0c33a8bbd0423cb..3eb2b3a0b1b63ca361a7b98a532b42f9e94bb451 100644 (file)
@@ -1,6 +1,8 @@
 //! Functions concerning immediate values and operands, and reading from operands.
 //! All high-level functions to read from memory work on operands as sources.
 
+use either::{Either, Left, Right};
+
 use rustc_hir::def::Namespace;
 use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
@@ -261,9 +263,9 @@ pub fn offset_with_meta(
         layout: TyAndLayout<'tcx>,
         cx: &impl HasDataLayout,
     ) -> InterpResult<'tcx, Self> {
-        match self.try_as_mplace() {
-            Ok(mplace) => Ok(mplace.offset_with_meta(offset, meta, layout, cx)?.into()),
-            Err(imm) => {
+        match self.as_mplace_or_imm() {
+            Left(mplace) => Ok(mplace.offset_with_meta(offset, meta, layout, cx)?.into()),
+            Right(imm) => {
                 assert!(
                     matches!(*imm, Immediate::Uninit),
                     "Scalar/ScalarPair cannot be offset into"
@@ -353,8 +355,8 @@ fn read_immediate_from_mplace_raw(
 
     /// Try returning an immediate for the operand. If the layout does not permit loading this as an
     /// immediate, return where in memory we can find the data.
-    /// Note that for a given layout, this operation will either always fail or always
-    /// succeed!  Whether it succeeds depends on whether the layout can be represented
+    /// Note that for a given layout, this operation will either always return Left or Right!
+    /// succeed!  Whether it returns Left depends on whether the layout can be represented
     /// in an `Immediate`, not on which data is stored there currently.
     ///
     /// This is an internal function that should not usually be used; call `read_immediate` instead.
@@ -362,16 +364,16 @@ fn read_immediate_from_mplace_raw(
     pub fn read_immediate_raw(
         &self,
         src: &OpTy<'tcx, M::Provenance>,
-    ) -> InterpResult<'tcx, Result<ImmTy<'tcx, M::Provenance>, MPlaceTy<'tcx, M::Provenance>>> {
-        Ok(match src.try_as_mplace() {
-            Ok(ref mplace) => {
+    ) -> InterpResult<'tcx, Either<MPlaceTy<'tcx, M::Provenance>, ImmTy<'tcx, M::Provenance>>> {
+        Ok(match src.as_mplace_or_imm() {
+            Left(ref mplace) => {
                 if let Some(val) = self.read_immediate_from_mplace_raw(mplace)? {
-                    Ok(val)
+                    Right(val)
                 } else {
-                    Err(*mplace)
+                    Left(*mplace)
                 }
             }
-            Err(val) => Ok(val),
+            Right(val) => Right(val),
         })
     }
 
@@ -390,7 +392,7 @@ pub fn read_immediate(
         ) {
             span_bug!(self.cur_span(), "primitive read not possible for type: {:?}", op.layout.ty);
         }
-        let imm = self.read_immediate_raw(op)?.unwrap();
+        let imm = self.read_immediate_raw(op)?.right().unwrap();
         if matches!(*imm, Immediate::Uninit) {
             throw_ub!(InvalidUninitBytes(None));
         }
@@ -432,9 +434,9 @@ pub fn operand_to_simd(
         // Basically we just transmute this place into an array following simd_size_and_type.
         // This only works in memory, but repr(simd) types should never be immediates anyway.
         assert!(op.layout.ty.is_simd());
-        match op.try_as_mplace() {
-            Ok(mplace) => self.mplace_to_simd(&mplace),
-            Err(imm) => match *imm {
+        match op.as_mplace_or_imm() {
+            Left(mplace) => self.mplace_to_simd(&mplace),
+            Right(imm) => match *imm {
                 Immediate::Uninit => {
                     throw_ub!(InvalidUninitBytes(None))
                 }
index 29d2312612ea9fb8fa5d5dc7e5de03b54baa5320..c47cfe8bb69fd05831734e1f42cf16e3781d7049 100644 (file)
@@ -2,6 +2,8 @@
 //! into a place.
 //! All high-level functions to write to memory work on places as destinations.
 
+use either::{Either, Left, Right};
+
 use rustc_ast::Mutability;
 use rustc_middle::mir;
 use rustc_middle::ty;
@@ -252,36 +254,36 @@ pub(super) fn vtable(&self) -> Scalar<Prov> {
 // These are defined here because they produce a place.
 impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
     #[inline(always)]
-    pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> {
+    pub fn as_mplace_or_imm(&self) -> Either<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> {
         match **self {
             Operand::Indirect(mplace) => {
-                Ok(MPlaceTy { mplace, layout: self.layout, align: self.align.unwrap() })
+                Left(MPlaceTy { mplace, layout: self.layout, align: self.align.unwrap() })
             }
-            Operand::Immediate(imm) => Err(ImmTy::from_immediate(imm, self.layout)),
+            Operand::Immediate(imm) => Right(ImmTy::from_immediate(imm, self.layout)),
         }
     }
 
     #[inline(always)]
     #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
     pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> {
-        self.try_as_mplace().unwrap()
+        self.as_mplace_or_imm().left().unwrap()
     }
 }
 
 impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> {
     /// A place is either an mplace or some local.
     #[inline]
-    pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Prov>, (usize, mir::Local)> {
+    pub fn as_mplace_or_local(&self) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local)> {
         match **self {
-            Place::Ptr(mplace) => Ok(MPlaceTy { mplace, layout: self.layout, align: self.align }),
-            Place::Local { frame, local } => Err((frame, local)),
+            Place::Ptr(mplace) => Left(MPlaceTy { mplace, layout: self.layout, align: self.align }),
+            Place::Local { frame, local } => Right((frame, local)),
         }
     }
 
     #[inline(always)]
     #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
     pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> {
-        self.try_as_mplace().unwrap()
+        self.as_mplace_or_local().left().unwrap()
     }
 }
 
@@ -569,9 +571,9 @@ fn write_immediate_to_mplace_no_validate(
     }
 
     pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
-        let mplace = match dest.try_as_mplace() {
-            Ok(mplace) => mplace,
-            Err((frame, local)) => {
+        let mplace = match dest.as_mplace_or_local() {
+            Left(mplace) => mplace,
+            Right((frame, local)) => {
                 match M::access_local_mut(self, frame, local)? {
                     Operand::Immediate(local) => {
                         *local = Immediate::Uninit;
@@ -639,7 +641,7 @@ fn copy_op_no_validate(
         // Let us see if the layout is simple so we take a shortcut,
         // avoid force_allocation.
         let src = match self.read_immediate_raw(src)? {
-            Ok(src_val) => {
+            Right(src_val) => {
                 // FIXME(const_prop): Const-prop can possibly evaluate an
                 // unsized copy operation when it thinks that the type is
                 // actually sized, due to a trivially false where-clause
@@ -669,7 +671,7 @@ fn copy_op_no_validate(
                     )
                 };
             }
-            Err(mplace) => mplace,
+            Left(mplace) => mplace,
         };
         // Slow path, this does not fit into an immediate. Just memcpy.
         trace!("copy_op: {:?} <- {:?}: {}", *dest, src, dest.layout.ty);
index 6b2e2bb8aca8c604ce9fde02652de85675af3b09..4966fd6ea80c11ae2e1380ce2f701090c6ae2809 100644 (file)
@@ -7,6 +7,8 @@
 //! but we still need to do bounds checking and adjust the layout. To not duplicate that with MPlaceTy, we actually
 //! implement the logic on OpTy, and MPlaceTy calls that.
 
+use either::{Left, Right};
+
 use rustc_middle::mir;
 use rustc_middle::ty;
 use rustc_middle::ty::layout::LayoutOf;
@@ -84,13 +86,13 @@ pub fn operand_field(
         base: &OpTy<'tcx, M::Provenance>,
         field: usize,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
-        let base = match base.try_as_mplace() {
-            Ok(ref mplace) => {
+        let base = match base.as_mplace_or_imm() {
+            Left(ref mplace) => {
                 // We can reuse the mplace field computation logic for indirect operands.
                 let field = self.mplace_field(mplace, field)?;
                 return Ok(field.into());
             }
-            Err(value) => value,
+            Right(value) => value,
         };
 
         let field_layout = base.layout.field(self, field);
index 3c286fa61bec5c9cb1a9501924ceded45ab5d13b..73f8bf4362e6086da6a1a3325e189c8dc8875850 100644 (file)
@@ -2,6 +2,8 @@
 //!
 //! The main entry point is the `step` method.
 
+use either::Either;
+
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{InterpResult, Scalar};
 use rustc_middle::ty::layout::LayoutOf;
@@ -46,7 +48,7 @@ pub fn step(&mut self) -> InterpResult<'tcx, bool> {
             return Ok(false);
         }
 
-        let Ok(loc) = self.frame().loc else {
+        let Either::Left(loc) = self.frame().loc else {
             // We are unwinding and this fn has no cleanup code.
             // Just go on unwinding.
             trace!("unwinding: skipping frame");
@@ -61,7 +63,7 @@ pub fn step(&mut self) -> InterpResult<'tcx, bool> {
             // Make sure we are not updating `statement_index` of the wrong frame.
             assert_eq!(old_frames, self.frame_idx());
             // Advance the program counter.
-            self.frame_mut().loc.as_mut().unwrap().statement_index += 1;
+            self.frame_mut().loc.as_mut().left().unwrap().statement_index += 1;
             return Ok(true);
         }
 
@@ -305,7 +307,7 @@ fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> InterpResult<'tc
 
         self.eval_terminator(terminator)?;
         if !self.stack().is_empty() {
-            if let Ok(loc) = self.frame().loc {
+            if let Either::Left(loc) = self.frame().loc {
                 info!("// executing {:?}", loc.block);
             }
         }
index 8aa56c275d91b93c51b1618c87687a9146ca57c7..cd7a472c0f0df367479771f0eecea77789dbeefa 100644 (file)
@@ -8,6 +8,8 @@
 use std::fmt::{Display, Write};
 use std::num::NonZeroUsize;
 
+use either::{Left, Right};
+
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
@@ -852,9 +854,9 @@ fn visit_aggregate(
                     return Ok(());
                 }
                 // Now that we definitely have a non-ZST array, we know it lives in memory.
-                let mplace = match op.try_as_mplace() {
-                    Ok(mplace) => mplace,
-                    Err(imm) => match *imm {
+                let mplace = match op.as_mplace_or_imm() {
+                    Left(mplace) => mplace,
+                    Right(imm) => match *imm {
                         Immediate::Uninit =>
                             throw_validation_failure!(self.path, { "uninitialized bytes" }),
                         Immediate::Scalar(..) | Immediate::ScalarPair(..) =>
index 25b420bed1766b2d999d3de8ddde4498400ca246..b90e0962ce6ad05285f2980ab8ff0d4df4b64271 100644 (file)
@@ -62,7 +62,7 @@ pub fn is_const_stable_const_fn(&self) -> bool {
     }
 
     fn is_async(&self) -> bool {
-        self.tcx.asyncness(self.def_id()) == hir::IsAsync::Async
+        self.tcx.asyncness(self.def_id()).is_async()
     }
 }
 
index 81b82a21fa1a7276796672a3980784bad79869ed..860dee589805780addc061110736fa9db4c888af 100644 (file)
@@ -2,7 +2,6 @@
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_index::bit_set::BitSet;
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
@@ -12,8 +11,7 @@
     ProjectionElem, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
     TerminatorKind, UnOp, START_BLOCK,
 };
-use rustc_middle::ty::fold::BottomUpFolder;
-use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypeVisitable};
+use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable};
 use rustc_mir_dataflow::impls::MaybeStorageLive;
 use rustc_mir_dataflow::storage::always_storage_live_locals;
 use rustc_mir_dataflow::{Analysis, ResultsCursor};
@@ -70,44 +68,6 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     }
 }
 
-/// Returns whether the two types are equal up to lifetimes.
-/// All lifetimes, including higher-ranked ones, get ignored for this comparison.
-/// (This is unlike the `erasing_regions` methods, which keep higher-ranked lifetimes for soundness reasons.)
-///
-/// The point of this function is to approximate "equal up to subtyping".  However,
-/// the approximation is incorrect as variance is ignored.
-pub fn equal_up_to_regions<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    param_env: ParamEnv<'tcx>,
-    src: Ty<'tcx>,
-    dest: Ty<'tcx>,
-) -> bool {
-    // Fast path.
-    if src == dest {
-        return true;
-    }
-
-    // Normalize lifetimes away on both sides, then compare.
-    let normalize = |ty: Ty<'tcx>| {
-        tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty).fold_with(
-            &mut BottomUpFolder {
-                tcx,
-                // FIXME: We erase all late-bound lifetimes, but this is not fully correct.
-                // If you have a type like `<for<'a> fn(&'a u32) as SomeTrait>::Assoc`,
-                // this is not necessarily equivalent to `<fn(&'static u32) as SomeTrait>::Assoc`,
-                // since one may have an `impl SomeTrait for fn(&32)` and
-                // `impl SomeTrait for fn(&'static u32)` at the same time which
-                // specify distinct values for Assoc. (See also #56105)
-                lt_op: |_| tcx.lifetimes.re_erased,
-                // Leave consts and types unchanged.
-                ct_op: |ct| ct,
-                ty_op: |ty| ty,
-            },
-        )
-    };
-    tcx.infer_ctxt().build().can_eq(param_env, normalize(src), normalize(dest)).is_ok()
-}
-
 struct TypeChecker<'a, 'tcx> {
     when: &'a str,
     body: &'a Body<'tcx>,
@@ -183,22 +143,7 @@ fn mir_assign_valid_types(&self, src: Ty<'tcx>, dest: Ty<'tcx>) -> bool {
             return true;
         }
 
-        // Normalize projections and things like that.
-        // Type-changing assignments can happen when subtyping is used. While
-        // all normal lifetimes are erased, higher-ranked types with their
-        // late-bound lifetimes are still around and can lead to type
-        // differences. So we compare ignoring lifetimes.
-
-        // First, try with reveal_all. This might not work in some cases, as the predicates
-        // can be cleared in reveal_all mode. We try the reveal first anyways as it is used
-        // by some other passes like inlining as well.
-        let param_env = self.param_env.with_reveal_all_normalized(self.tcx);
-        if equal_up_to_regions(self.tcx, param_env, src, dest) {
-            return true;
-        }
-
-        // If this fails, we can try it without the reveal.
-        equal_up_to_regions(self.tcx, self.param_env, src, dest)
+        crate::util::is_subtype(self.tcx, self.param_env, src, dest)
     }
 }
 
diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs
new file mode 100644 (file)
index 0000000..a9cb191
--- /dev/null
@@ -0,0 +1,63 @@
+//! Routines to check for relations between fully inferred types.
+//!
+//! FIXME: Move this to a more general place. The utility of this extends to
+//! other areas of the compiler as well.
+
+use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
+use rustc_infer::traits::ObligationCause;
+use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
+use rustc_trait_selection::traits::ObligationCtxt;
+
+/// Returns whether the two types are equal up to subtyping.
+///
+/// This is used in case we don't know the expected subtyping direction
+/// and still want to check whether anything is broken.
+pub fn is_equal_up_to_subtyping<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    param_env: ParamEnv<'tcx>,
+    src: Ty<'tcx>,
+    dest: Ty<'tcx>,
+) -> bool {
+    // Fast path.
+    if src == dest {
+        return true;
+    }
+
+    // Check for subtyping in either direction.
+    is_subtype(tcx, param_env, src, dest) || is_subtype(tcx, param_env, dest, src)
+}
+
+/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
+///
+/// This mostly ignores opaque types as it can be used in constraining contexts
+/// while still computing the final underlying type.
+pub fn is_subtype<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    param_env: ParamEnv<'tcx>,
+    src: Ty<'tcx>,
+    dest: Ty<'tcx>,
+) -> bool {
+    if src == dest {
+        return true;
+    }
+
+    let mut builder =
+        tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble);
+    let infcx = builder.build();
+    let ocx = ObligationCtxt::new(&infcx);
+    let cause = ObligationCause::dummy();
+    let src = ocx.normalize(cause.clone(), param_env, src);
+    let dest = ocx.normalize(cause.clone(), param_env, dest);
+    match ocx.sub(&cause, param_env, src, dest) {
+        Ok(()) => {}
+        Err(_) => return false,
+    };
+    let errors = ocx.select_all_or_error();
+    // With `Reveal::All`, opaque types get normalized away, with `Reveal::UserFacing`
+    // we would get unification errors because we're unable to look into opaque types,
+    // even if they're constrained in our current function.
+    //
+    // It seems very unlikely that this hides any bugs.
+    let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
+    errors.is_empty()
+}
index 4d0f81a4060088b669d85902ca9013a50f7e3e4c..76ea5a24e69edd8c1bd09cab7ece7e05eb345302 100644 (file)
@@ -2,6 +2,7 @@
 mod alignment;
 mod call_kind;
 pub mod collect_writes;
+mod compare_types;
 mod find_self_call;
 mod might_permit_raw_init;
 mod type_name;
@@ -9,6 +10,7 @@
 pub use self::aggregate::expand_aggregate;
 pub use self::alignment::is_disaligned;
 pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind};
+pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype};
 pub use self::find_self_call::find_self_call;
 pub use self::might_permit_raw_init::might_permit_raw_init;
 pub use self::type_name::type_name;
index a3d3f988344c6e0663c6f980494da10354b4725e..84cb417dd89363c64946c1cef65cca0d15d6fd38 100644 (file)
@@ -34,43 +34,11 @@ impl<T> IdFunctor for Vec<T> {
     type Inner = T;
 
     #[inline]
-    fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E>
+    fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
     where
         F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
     {
-        struct HoleVec<T> {
-            vec: Vec<mem::ManuallyDrop<T>>,
-            hole: Option<usize>,
-        }
-
-        impl<T> Drop for HoleVec<T> {
-            fn drop(&mut self) {
-                unsafe {
-                    for (index, slot) in self.vec.iter_mut().enumerate() {
-                        if self.hole != Some(index) {
-                            mem::ManuallyDrop::drop(slot);
-                        }
-                    }
-                }
-            }
-        }
-
-        unsafe {
-            let (ptr, length, capacity) = self.into_raw_parts();
-            let vec = Vec::from_raw_parts(ptr.cast(), length, capacity);
-            let mut hole_vec = HoleVec { vec, hole: None };
-
-            for (index, slot) in hole_vec.vec.iter_mut().enumerate() {
-                hole_vec.hole = Some(index);
-                let original = mem::ManuallyDrop::take(slot);
-                let mapped = f(original)?;
-                *slot = mem::ManuallyDrop::new(mapped);
-                hole_vec.hole = None;
-            }
-
-            mem::forget(hole_vec);
-            Ok(Vec::from_raw_parts(ptr, length, capacity))
-        }
+        self.into_iter().map(f).collect()
     }
 }
 
index e043368fdfe0210ae475bd7b151310538ba099cc..8a712cec85211b0a9c1936c83b586350a74537dd 100644 (file)
@@ -5,6 +5,7 @@
 //! This API is completely unstable and subject to change.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(is_terminal)]
 #![feature(once_cell)]
 #![feature(decl_macro)]
 #![recursion_limit = "256"]
@@ -27,7 +28,6 @@
 use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
 use rustc_interface::{interface, Queries};
 use rustc_lint::LintStore;
-use rustc_log::stdout_isatty;
 use rustc_metadata::locator;
 use rustc_save_analysis as save;
 use rustc_save_analysis::DumpHandler;
@@ -48,7 +48,7 @@
 use std::env;
 use std::ffi::OsString;
 use std::fs;
-use std::io::{self, Read, Write};
+use std::io::{self, IsTerminal, Read, Write};
 use std::panic::{self, catch_unwind};
 use std::path::PathBuf;
 use std::process::{self, Command, Stdio};
@@ -515,7 +515,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
                 }
                 text.push('\n');
             }
-            if stdout_isatty() {
+            if io::stdout().is_terminal() {
                 show_content_with_pager(&text);
             } else {
                 print!("{}", text);
index 9945f337995d369fdafc8534713433470104e335..0c705d2ecf5fface2271ea6b76540eaee71b1d9d 100644 (file)
@@ -9,9 +9,17 @@ edition = "2021"
 fluent-bundle = "0.15.2"
 fluent-syntax = "0.11"
 intl-memoizer = "0.5.1"
+rustc_baked_icu_data = { path = "../rustc_baked_icu_data" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 rustc_macros = { path = "../rustc_macros" }
 tracing = "0.1"
 unic-langid = { version = "0.9.0", features = ["macros"] }
+icu_list = "1.0.0"
+writeable = "0.5.0"
+icu_locid = "1.0.0"
+icu_provider_adapters = "1.0.0"
+
+[features]
+rustc_use_parallel_compiler = ['rustc_baked_icu_data/rustc_use_parallel_compiler']
diff --git a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl b/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl
new file mode 100644 (file)
index 0000000..2ce417a
--- /dev/null
@@ -0,0 +1,8 @@
+hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
+hir_typeck_fru_expr = this expression does not end in a comma...
+hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
+hir_typeck_fru_suggestion =
+    to set the remaining fields{$expr ->
+        [NONE]{""}
+        *[other] {" "}from `{$expr}`
+    }, separate the last named field with a comma
index 4c7ce30097c95f324050b0d93ae2cc2770e1615c..1df5bf1a22037fef47d29a92a2b06d9df946b6d4 100644 (file)
@@ -54,6 +54,9 @@ parser_invalid_logical_operator = `{$incorrect}` is not a logical operator
 parser_tilde_is_not_unary_operator = `~` cannot be used as a unary operator
     .suggestion = use `!` to perform bitwise not
 
+parser_unexpected_if_with_if = unexpected `if` in the condition expression
+    .suggestion = remove the `if`
+
 parser_unexpected_token_after_not = unexpected {$negated_desc} after identifier
 parser_unexpected_token_after_not_bitwise = use `!` to perform bitwise not
 parser_unexpected_token_after_not_logical = use `!` to perform logical negation
diff --git a/compiler/rustc_error_messages/locales/en-US/resolve.ftl b/compiler/rustc_error_messages/locales/en-US/resolve.ftl
new file mode 100644 (file)
index 0000000..817bb83
--- /dev/null
@@ -0,0 +1,211 @@
+resolve_parent_module_reset_for_binding =
+    parent module is reset for binding
+
+resolve_ampersand_used_without_explicit_lifetime_name =
+    `&` without an explicit lifetime name cannot be used here
+    .note = explicit lifetime name needed here
+
+resolve_underscore_lifetime_name_cannot_be_used_here =
+    `'_` cannot be used here
+    .note = `'_` is a reserved lifetime name
+
+resolve_crate_may_not_be_imported =
+    `$crate` may not be imported
+
+resolve_crate_root_imports_must_be_named_explicitly =
+    crate root imports need to be explicitly named: `use crate as name;`
+
+resolve_generic_params_from_outer_function =
+    can't use generic parameters from outer function
+    .label = use of generic parameter from outer function
+    .suggestion = try using a local generic parameter instead
+
+resolve_self_type_implicitly_declared_by_impl =
+    `Self` type implicitly declared here, by this `impl`
+
+resolve_cannot_use_self_type_here =
+    can't use `Self` here
+
+resolve_use_a_type_here_instead =
+    use a type here instead
+
+resolve_type_param_from_outer_fn =
+    type parameter from outer function
+
+resolve_const_param_from_outer_fn =
+    const parameter from outer function
+
+resolve_try_using_local_generic_parameter =
+    try using a local generic parameter instead
+
+resolve_try_adding_local_generic_param_on_method =
+    try adding a local generic parameter in this method instead
+
+resolve_help_try_using_local_generic_param =
+    try using a local generic paramter instead
+
+resolve_name_is_already_used_as_generic_parameter =
+    the name `{$name}` is already used for a generic parameter in this item's generic parameters
+    .label = already used
+    .first_use_of_name = first use of `{$name}`
+
+resolve_method_not_member_of_trait =
+    method `{$method}` is not a member of trait `{$trait_}`
+    .label = not a member of trait `{$trait_}`
+
+resolve_associated_fn_with_similar_name_exists =
+    there is an associated function with a similar name
+
+resolve_type_not_member_of_trait =
+    type `{$type_}` is not a member of trait `{$trait_}`
+    .label = not a member of trait `{$trait_}`
+
+resolve_associated_type_with_similar_name_exists =
+    there is an associated type with a similar name
+
+resolve_const_not_member_of_trait =
+    const `{$const_}` is not a member of trait `{$trait_}`
+    .label = not a member of trait `{$trait_}`
+
+resolve_associated_const_with_similar_name_exists =
+    there is an associated constant with a similar name
+
+resolve_variable_bound_with_different_mode =
+    variable `{$variable_name}` is bound inconsistently across alternatives separated by `|`
+    .label = bound in different ways
+    .first_binding_span = first binding
+
+resolve_ident_bound_more_than_once_in_parameter_list =
+    identifier `{$identifier}` is bound more than once in this parameter list
+    .label = used as parameter more than once
+
+resolve_ident_bound_more_than_once_in_same_pattern =
+    identifier `{$identifier}` is bound more than once in the same pattern
+    .label = used in a pattern more than once
+
+resolve_undeclared_label =
+    use of undeclared label `{$name}`
+    .label = undeclared label `{$name}`
+
+resolve_label_with_similar_name_reachable =
+    a label with a similar name is reachable
+
+resolve_try_using_similarly_named_label =
+    try using similarly named label
+
+resolve_unreachable_label_with_similar_name_exists =
+    a label with a similar name exists but is unreachable
+
+resolve_self_import_can_only_appear_once_in_the_list =
+    `self` import can only appear once in an import list
+    .label = can only appear once in an import list
+
+resolve_self_import_only_in_import_list_with_non_empty_prefix =
+    `self` import can only appear in an import list with a non-empty prefix
+    .label = can only appear in an import list with a non-empty prefix
+
+resolve_cannot_capture_dynamic_environment_in_fn_item =
+    can't capture dynamic environment in a fn item
+    .help = use the `|| {"{"} ... {"}"}` closure form instead
+
+resolve_attempt_to_use_non_constant_value_in_constant =
+    attempt to use a non-constant value in a constant
+
+resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion =
+    consider using `{$suggestion}` instead of `{$current}`
+
+resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion =
+    non-constant value
+
+resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion =
+    this would need to be a `{$suggestion}`
+
+resolve_self_imports_only_allowed_within =
+    `self` imports are only allowed within a {"{"} {"}"} list
+
+resolve_self_imports_only_allowed_within_suggestion =
+    consider importing the module directly
+
+resolve_self_imports_only_allowed_within_multipart_suggestion =
+    alternatively, use the multi-path `use` syntax to import `self`
+
+resolve_binding_shadows_something_unacceptable =
+    {$shadowing_binding}s cannot shadow {$shadowed_binding}s
+    .label = cannot be named the same as {$article} {$shadowed_binding}
+    .label_shadowed_binding = the {$shadowed_binding} `{$name}` is {$participle} here
+
+resolve_binding_shadows_something_unacceptable_suggestion =
+    try specify the pattern arguments
+
+resolve_forward_declared_generic_param =
+    generic parameters with a default cannot use forward declared identifiers
+    .label = defaulted generic parameters cannot be forward declared
+
+resolve_param_in_ty_of_const_param =
+    the type of const parameters must not depend on other generic parameters
+    .label = the type must not depend on the parameter `{$name}`
+
+resolve_self_in_generic_param_default =
+    generic parameters cannot use `Self` in their defaults
+    .label = `Self` in generic parameter default
+
+resolve_param_in_non_trivial_anon_const =
+    generic parameters may not be used in const operations
+    .label = cannot perform const operation using `{$name}`
+
+resolve_param_in_non_trivial_anon_const_help =
+    use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+resolve_param_in_non_trivial_anon_const_sub_type =
+    type parameters may not be used in const expressions
+
+resolve_param_in_non_trivial_anon_const_sub_non_type =
+    const parameters may only be used as standalone arguments, i.e. `{$name}`
+
+resolve_unreachable_label =
+    use of unreachable label `{$name}`
+    .label = unreachable label `{$name}`
+    .label_definition_span = unreachable label defined here
+    .note = labels are unreachable through functions, closures, async blocks and modules
+
+resolve_unreachable_label_suggestion_use_similarly_named =
+    try using similarly named label
+
+resolve_unreachable_label_similar_name_reachable =
+    a label with a similar name is reachable
+
+resolve_unreachable_label_similar_name_unreachable =
+    a label with a similar name exists but is also unreachable
+
+resolve_trait_impl_mismatch =
+    item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}`
+    .label = does not match trait
+    .label_trait_item = item in trait
+
+resolve_invalid_asm_sym =
+    invalid `sym` operand
+    .label = is a local variable
+    .help = `sym` operands must refer to either a function or a static
+
+resolve_trait_impl_duplicate =
+    duplicate definitions with name `{$name}`:
+    .label = duplicate definition
+    .old_span_label = previous definition here
+    .trait_item_span = item in trait
+
+resolve_relative_2018 =
+    relative paths are not supported in visibilities in 2018 edition or later
+    .suggestion = try
+
+resolve_ancestor_only =
+    visibilities can only be restricted to ancestor modules
+
+resolve_expected_found =
+    expected module, found {$res} `{$path_str}`
+    .label = not a module
+
+resolve_indeterminate =
+    cannot determine resolution for the visibility
+
+resolve_module_only =
+    visibility must resolve to a module
index 0b1b75471a661cefaa5d530e0534cb85ea868ea7..1b35021db3d4bd673005f6cd539050f9e8cb7fc0 100644 (file)
@@ -10,6 +10,7 @@
 
 use fluent_bundle::FluentResource;
 use fluent_syntax::parser::ParserError;
+use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker};
 use rustc_data_structures::sync::Lrc;
 use rustc_macros::{fluent_messages, Decodable, Encodable};
 use rustc_span::Span;
@@ -30,8 +31,7 @@
 #[cfg(not(parallel_compiler))]
 use intl_memoizer::IntlLangMemoizer;
 
-pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
-
+pub use fluent_bundle::{self, types::FluentType, FluentArgs, FluentError, FluentValue};
 pub use unic_langid::{langid, LanguageIdentifier};
 
 // Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
@@ -51,6 +51,7 @@
     errors => "../locales/en-US/errors.ftl",
     expand => "../locales/en-US/expand.ftl",
     hir_analysis => "../locales/en-US/hir_analysis.ftl",
+    hir_typeck => "../locales/en-US/hir_typeck.ftl",
     infer => "../locales/en-US/infer.ftl",
     interface => "../locales/en-US/interface.ftl",
     lint => "../locales/en-US/lint.ftl",
@@ -63,6 +64,7 @@
     plugin_impl => "../locales/en-US/plugin_impl.ftl",
     privacy => "../locales/en-US/privacy.ftl",
     query_system => "../locales/en-US/query_system.ftl",
+    resolve => "../locales/en-US/resolve.ftl",
     save_analysis => "../locales/en-US/save_analysis.ftl",
     session => "../locales/en-US/session.ftl",
     symbol_mangling => "../locales/en-US/symbol_mangling.ftl",
@@ -541,3 +543,92 @@ fn from(spans: Vec<Span>) -> MultiSpan {
         MultiSpan::from_spans(spans)
     }
 }
+
+fn icu_locale_from_unic_langid(lang: LanguageIdentifier) -> Option<icu_locid::Locale> {
+    icu_locid::Locale::try_from_bytes(lang.to_string().as_bytes()).ok()
+}
+
+pub fn fluent_value_from_str_list_sep_by_and<'source>(
+    l: Vec<Cow<'source, str>>,
+) -> FluentValue<'source> {
+    // Fluent requires 'static value here for its AnyEq usages.
+    #[derive(Clone, PartialEq, Debug)]
+    struct FluentStrListSepByAnd(Vec<String>);
+
+    impl FluentType for FluentStrListSepByAnd {
+        fn duplicate(&self) -> Box<dyn FluentType + Send> {
+            Box::new(self.clone())
+        }
+
+        fn as_string(&self, intls: &intl_memoizer::IntlLangMemoizer) -> Cow<'static, str> {
+            let result = intls
+                .with_try_get::<MemoizableListFormatter, _, _>((), |list_formatter| {
+                    list_formatter.format_to_string(self.0.iter())
+                })
+                .unwrap();
+            Cow::Owned(result)
+        }
+
+        #[cfg(not(parallel_compiler))]
+        fn as_string_threadsafe(
+            &self,
+            _intls: &intl_memoizer::concurrent::IntlLangMemoizer,
+        ) -> Cow<'static, str> {
+            unreachable!("`as_string_threadsafe` is not used in non-parallel rustc")
+        }
+
+        #[cfg(parallel_compiler)]
+        fn as_string_threadsafe(
+            &self,
+            intls: &intl_memoizer::concurrent::IntlLangMemoizer,
+        ) -> Cow<'static, str> {
+            let result = intls
+                .with_try_get::<MemoizableListFormatter, _, _>((), |list_formatter| {
+                    list_formatter.format_to_string(self.0.iter())
+                })
+                .unwrap();
+            Cow::Owned(result)
+        }
+    }
+
+    struct MemoizableListFormatter(icu_list::ListFormatter);
+
+    impl std::ops::Deref for MemoizableListFormatter {
+        type Target = icu_list::ListFormatter;
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+
+    impl intl_memoizer::Memoizable for MemoizableListFormatter {
+        type Args = ();
+        type Error = ();
+
+        fn construct(lang: LanguageIdentifier, _args: Self::Args) -> Result<Self, Self::Error>
+        where
+            Self: Sized,
+        {
+            let baked_data_provider = rustc_baked_icu_data::baked_data_provider();
+            let locale_fallbacker =
+                LocaleFallbacker::try_new_with_any_provider(&baked_data_provider)
+                    .expect("Failed to create fallback provider");
+            let data_provider =
+                LocaleFallbackProvider::new_with_fallbacker(baked_data_provider, locale_fallbacker);
+            let locale = icu_locale_from_unic_langid(lang)
+                .unwrap_or_else(|| rustc_baked_icu_data::supported_locales::EN);
+            let list_formatter =
+                icu_list::ListFormatter::try_new_and_with_length_with_any_provider(
+                    &data_provider,
+                    &locale.into(),
+                    icu_list::ListLength::Wide,
+                )
+                .expect("Failed to create list formatter");
+
+            Ok(MemoizableListFormatter(list_formatter))
+        }
+    }
+
+    let l = l.into_iter().map(|x| x.into_owned()).collect();
+
+    FluentValue::Custom(Box::new(FluentStrListSepByAnd(l)))
+}
index 7803a0792e12c9c3c1ce5ccc1a76c8f689a5c43c..dee7a31ec2028287b06304fdb3b0b68f377a631e 100644 (file)
@@ -18,7 +18,6 @@ rustc_target = { path = "../rustc_target" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_lint_defs = { path = "../rustc_lint_defs" }
 unicode-width = "0.1.4"
-atty = "0.2"
 termcolor = "1.0"
 annotate-snippets = "0.9"
 termize = "0.1.1"
@@ -27,3 +26,6 @@ serde_json = "1.0.59"
 
 [target.'cfg(windows)'.dependencies]
 winapi = { version = "0.3", features = [ "handleapi", "synchapi", "winbase" ] }
+
+[features]
+rustc_use_parallel_compiler = ['rustc_error_messages/rustc_use_parallel_compiler']
index 66c986977eccb78c1ad58e2c9adc9c22a69f93e4..7d5e4723a6d883b6b22bf24c19259c93f210c3fa 100644 (file)
@@ -4,6 +4,7 @@
     SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
 };
 use rustc_data_structures::fx::FxHashMap;
+use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
 use rustc_error_messages::FluentValue;
 use rustc_lint_defs::{Applicability, LintExpectationId};
 use rustc_span::edition::LATEST_STABLE_EDITION;
@@ -34,6 +35,7 @@
 pub enum DiagnosticArgValue<'source> {
     Str(Cow<'source, str>),
     Number(usize),
+    StrListSepByAnd(Vec<Cow<'source, str>>),
 }
 
 /// Converts a value of a type into a `DiagnosticArg` (typically a field of an `IntoDiagnostic`
@@ -49,6 +51,9 @@ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
         match self {
             DiagnosticArgValue::Str(s) => DiagnosticArgValue::Str(Cow::Owned(s.into_owned())),
             DiagnosticArgValue::Number(n) => DiagnosticArgValue::Number(n),
+            DiagnosticArgValue::StrListSepByAnd(l) => DiagnosticArgValue::StrListSepByAnd(
+                l.into_iter().map(|s| Cow::Owned(s.into_owned())).collect(),
+            ),
         }
     }
 }
@@ -58,6 +63,7 @@ fn into(self) -> FluentValue<'source> {
         match self {
             DiagnosticArgValue::Str(s) => From::from(s),
             DiagnosticArgValue::Number(n) => From::from(n),
+            DiagnosticArgValue::StrListSepByAnd(l) => fluent_value_from_str_list_sep_by_and(l),
         }
     }
 }
index c6035705e39fa70d2022800fee8d488c82fb115b..7155db32e53b7f75e71c4e592c70aa58a4278362 100644 (file)
@@ -11,7 +11,6 @@
 use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
 use std::borrow::Cow;
 use std::fmt;
-use std::fmt::Write;
 use std::num::ParseIntError;
 use std::path::{Path, PathBuf};
 use std::process::ExitStatus;
@@ -191,23 +190,15 @@ fn from(v: Vec<Symbol>) -> Self {
 
 impl IntoDiagnosticArg for DiagnosticSymbolList {
     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        // FIXME: replace the logic here with a real list formatter
-        let symbols = match &self.0[..] {
-            [symbol] => format!("`{symbol}`"),
-            [symbol, last] => {
-                format!("`{symbol}` and `{last}`",)
-            }
-            [symbols @ .., last] => {
-                let mut result = String::new();
-                for symbol in symbols {
-                    write!(result, "`{symbol}`, ").unwrap();
-                }
-                write!(result, "and `{last}`").unwrap();
-                result
-            }
-            [] => unreachable!(),
-        };
-        DiagnosticArgValue::Str(Cow::Owned(symbols))
+        DiagnosticArgValue::StrListSepByAnd(
+            self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),
+        )
+    }
+}
+
+impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
     }
 }
 
index 55c7997a513636bc38d48f8acfc74da9e3c61dd9..bc136aea44d4cf59a97f30c8e8e5cdc89dab565a 100644 (file)
@@ -28,8 +28,8 @@
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use std::borrow::Cow;
 use std::cmp::{max, min, Reverse};
-use std::io;
 use std::io::prelude::*;
+use std::io::{self, IsTerminal};
 use std::iter;
 use std::path::Path;
 use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream};
@@ -619,14 +619,14 @@ impl ColorConfig {
     fn to_color_choice(self) -> ColorChoice {
         match self {
             ColorConfig::Always => {
-                if atty::is(atty::Stream::Stderr) {
+                if io::stderr().is_terminal() {
                     ColorChoice::Always
                 } else {
                     ColorChoice::AlwaysAnsi
                 }
             }
             ColorConfig::Never => ColorChoice::Never,
-            ColorConfig::Auto if atty::is(atty::Stream::Stderr) => ColorChoice::Auto,
+            ColorConfig::Auto if io::stderr().is_terminal() => ColorChoice::Auto,
             ColorConfig::Auto => ColorChoice::Never,
         }
     }
index 170d4341ae71b4a3356a12a7c6d03b60d9021f4f..f8747386c0498d3916ddbc65be287b46d799951a 100644 (file)
@@ -5,6 +5,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(drain_filter)]
 #![feature(if_let_guard)]
+#![feature(is_terminal)]
 #![feature(adt_const_params)]
 #![feature(let_chains)]
 #![feature(never_type)]
@@ -466,6 +467,9 @@ pub enum StashKey {
     /// When an invalid lifetime e.g. `'2` should be reinterpreted
     /// as a char literal in the parser
     LifetimeIsChar,
+    /// Maybe there was a typo where a comma was forgotten before
+    /// FRU syntax
+    MaybeFruTypo,
 }
 
 fn default_track_diagnostic(_: &Diagnostic) {}
@@ -644,13 +648,14 @@ pub fn reset_err_count(&self) {
         inner.stashed_diagnostics = Default::default();
     }
 
-    /// Stash a given diagnostic with the given `Span` and `StashKey` as the key for later stealing.
+    /// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key.
+    /// Retrieve a stashed diagnostic with `steal_diagnostic`.
     pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) {
         let mut inner = self.inner.borrow_mut();
         inner.stash((span, key), diag);
     }
 
-    /// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key.
+    /// Steal a previously stashed diagnostic with the given `Span` and [`StashKey`] as the key.
     pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> {
         let mut inner = self.inner.borrow_mut();
         inner.steal((span, key)).map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
index 4ee7b6c42bbf5015e912de73beb059df4ece742b..192f54171cee6885d1d327f6397908b6d3afaab0 100644 (file)
@@ -8,20 +8,21 @@ build = false
 doctest = false
 
 [dependencies]
-rustc_serialize = { path = "../rustc_serialize" }
-tracing = "0.1"
-rustc_span = { path = "../rustc_span" }
-rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+crossbeam-channel = "0.5.0"
 rustc_ast_passes = { path = "../rustc_ast_passes" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_attr = { path = "../rustc_attr" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_feature = { path = "../rustc_feature" }
+rustc_lexer = { path = "../rustc_lexer" }
 rustc_lint_defs = { path = "../rustc_lint_defs" }
 rustc_macros = { path = "../rustc_macros" }
-rustc_lexer = { path = "../rustc_lexer" }
 rustc_parse = { path = "../rustc_parse" }
+rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-rustc_ast = { path = "../rustc_ast" }
-crossbeam-channel = "0.5.0"
+thin-vec = "0.2.8"
+tracing = "0.1"
index 95fff929d46fec32ff55fdb5666afe3884b9f6d7..04fe6c4007e948fd106f14fb95947ae1003e3090 100644 (file)
@@ -1436,7 +1436,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
                             let crate_matches = if c.starts_with("allsorts-rental") {
                                 true
                             } else {
-                                let mut version = c.trim_start_matches("rental-").split(".");
+                                let mut version = c.trim_start_matches("rental-").split('.');
                                 version.next() == Some("0")
                                     && version.next() == Some("5")
                                     && version
index 8aa72e142f82c25193f58353f6ccb58da650a1dc..e17cba1478ab6e939eb3153cf76565e4dffb3446 100644 (file)
@@ -1,13 +1,12 @@
 use crate::base::ExtCtxt;
-
 use rustc_ast::attr;
 use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp};
 use rustc_data_structures::sync::Lrc;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-
 use rustc_span::Span;
+use thin_vec::ThinVec;
 
 impl<'a> ExtCtxt<'a> {
     pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path {
@@ -28,7 +27,7 @@ pub fn path_all(
     ) -> ast::Path {
         assert!(!idents.is_empty());
         let add_root = global && !idents[0].is_path_segment_keyword();
-        let mut segments = Vec::with_capacity(idents.len() + add_root as usize);
+        let mut segments = ThinVec::with_capacity(idents.len() + add_root as usize);
         if add_root {
             segments.push(ast::PathSegment::path_root(span));
         }
@@ -532,15 +531,15 @@ pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::
         // here, but that's not entirely clear.
         self.expr(
             span,
-            ast::ExprKind::Closure(
-                ast::ClosureBinder::NotPresent,
-                ast::CaptureBy::Ref,
-                ast::Async::No,
-                ast::Movability::Movable,
+            ast::ExprKind::Closure(Box::new(ast::Closure {
+                binder: ast::ClosureBinder::NotPresent,
+                capture_clause: ast::CaptureBy::Ref,
+                asyncness: ast::Async::No,
+                movability: ast::Movability::Movable,
                 fn_decl,
                 body,
-                span,
-            ),
+                fn_decl_span: span,
+            })),
         )
     }
 
index c02680b77fb152e5cd6bc9f2c5d15be21e9ada66..6c7063ca28b35b5fcc580180d41fe5a3e90872ba 100644 (file)
@@ -495,7 +495,6 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>(
     // hacky, but speeds up the `html5ever` benchmark significantly. (Issue
     // 68836 suggests a more comprehensive but more complex change to deal with
     // this situation.)
-    // FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match.
     let parser = parser_from_cx(sess, arg.clone(), T::recovery());
     // Try each arm's matchers.
     let mut tt_parser = TtParser::new(name);
index faaf3b3fea58916ae2740546351fcfbc1cb0301a..97b1871028ec043075f2f6a7f5cdc1bafc411c8a 100644 (file)
@@ -1,14 +1,12 @@
 use crate::expand::{AstFragment, AstFragmentKind};
-
 use rustc_ast as ast;
 use rustc_ast::mut_visit::*;
 use rustc_ast::ptr::P;
+use rustc_data_structures::fx::FxHashMap;
 use rustc_span::source_map::DUMMY_SP;
 use rustc_span::symbol::Ident;
-
 use smallvec::{smallvec, SmallVec};
-
-use rustc_data_structures::fx::FxHashMap;
+use thin_vec::ThinVec;
 
 pub fn placeholder(
     kind: AstFragmentKind,
@@ -17,7 +15,7 @@ pub fn placeholder(
 ) -> AstFragment {
     fn mac_placeholder() -> P<ast::MacCall> {
         P(ast::MacCall {
-            path: ast::Path { span: DUMMY_SP, segments: Vec::new(), tokens: None },
+            path: ast::Path { span: DUMMY_SP, segments: ThinVec::new(), tokens: None },
             args: P(ast::MacArgs::Empty),
             prior_type_ascription: None,
         })
index 5cf2fdde392547979af15534f35bf10917cd814f..ae49a76a087838bf60d316f0cdd12dee2308b89b 100644 (file)
@@ -506,6 +506,8 @@ pub fn set(&self, features: &mut Features, span: Span) {
     (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
     /// Allows lints part of the strict provenance effort.
     (active, strict_provenance, "1.61.0", Some(95228), None),
+    /// Allows string patterns to dereference values to match them.
+    (active, string_deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), None),
     /// Allows the use of `#[target_feature]` on safe functions.
     (active, target_feature_11, "1.45.0", Some(69098), None),
     /// Allows using `#[thread_local]` on `static` items.
index 7d8b859a6b4077a76edb6330f132624b832b8f65..e0a3864506548f186e95c15387f8b7f7526ba1f0 100644 (file)
@@ -2720,6 +2720,12 @@ pub enum IsAsync {
     NotAsync,
 }
 
+impl IsAsync {
+    pub fn is_async(self) -> bool {
+        self == IsAsync::Async
+    }
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
 pub enum Defaultness {
     Default { has_value: bool },
index a55224d10972abf01a57e95933d174bab7481941..b68dd25996b116cd5c60c8027c4a9f0ae46c19dc 100644 (file)
@@ -95,6 +95,14 @@ pub fn from_name(name: Symbol) -> Option<Self> {
                 }
             }
 
+            /// Returns the name of the `LangItem` enum variant.
+            // This method is used by Clippy for internal lints.
+            pub fn variant_name(self) -> &'static str {
+                match self {
+                    $( LangItem::$variant => stringify!($variant), )*
+                }
+            }
+
             pub fn target(self) -> Target {
                 match self {
                     $( LangItem::$variant => $target, )*
@@ -270,6 +278,8 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
     TryTraitBranch,          sym::branch,              branch_fn,                  Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
     TryTraitFromYeet,        sym::from_yeet,           from_yeet_fn,               Target::Fn,             GenericRequirement::None;
 
+    PointerSized,            sym::pointer_sized,       pointer_sized,              Target::Trait,          GenericRequirement::Exact(0);
+
     PollReady,               sym::Ready,               poll_ready_variant,         Target::Variant,        GenericRequirement::None;
     PollPending,             sym::Pending,             poll_pending_variant,       Target::Variant,        GenericRequirement::None;
 
@@ -302,6 +312,8 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
     Range,                   sym::Range,               range_struct,               Target::Struct,         GenericRequirement::None;
     RangeToInclusive,        sym::RangeToInclusive,    range_to_inclusive_struct,  Target::Struct,         GenericRequirement::None;
     RangeTo,                 sym::RangeTo,             range_to_struct,            Target::Struct,         GenericRequirement::None;
+
+    String,                  sym::String,              string,                     Target::Struct,         GenericRequirement::None;
 }
 
 pub enum GenericRequirement {
index 16c40cf1299cb7f5edbd0b4129622c23d5d859bb..83b95fe0e911ec055f08c426b50d498a2f583a66 100644 (file)
@@ -115,7 +115,7 @@ fn projected_ty_from_poly_trait_ref(
     /// (e.g., resolve) that is translated into a ty-error. This is
     /// used to help suppress derived errors typeck might otherwise
     /// report.
-    fn set_tainted_by_errors(&self);
+    fn set_tainted_by_errors(&self, e: ErrorGuaranteed);
 
     fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
 }
@@ -2620,8 +2620,12 @@ pub fn res_to_ty(
                 }
             }
             Res::Err => {
-                self.set_tainted_by_errors();
-                self.tcx().ty_error()
+                let e = self
+                    .tcx()
+                    .sess
+                    .delay_span_bug(path.span, "path with `Res:Err` but no error emitted");
+                self.set_tainted_by_errors(e);
+                self.tcx().ty_error_with_guaranteed(e)
             }
             _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
         }
index f76b282fa76d54123c3dd95ad12c7d7d2389f479..b4805de961889a2fcb8c1da77ee829a219b8e32f 100644 (file)
@@ -449,8 +449,8 @@ fn check_opaque_meets_bounds<'tcx>(
 
     let misc_cause = traits::ObligationCause::misc(span, hir_id);
 
-    match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_ty) {
-        Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok),
+    match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
+        Ok(()) => {}
         Err(ty_err) => {
             tcx.sess.delay_span_bug(
                 span,
index 5a222031c5610eacb43303ef8aa6daa239701a79..e68df228c6b5186ae13871f1d88eca4c4afbae3f 100644 (file)
@@ -402,10 +402,8 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
         unnormalized_trait_sig.inputs_and_output.iter().chain(trait_sig.inputs_and_output.iter()),
     );
 
-    match infcx.at(&cause, param_env).eq(trait_return_ty, impl_return_ty) {
-        Ok(infer::InferOk { value: (), obligations }) => {
-            ocx.register_obligations(obligations);
-        }
+    match ocx.eq(&cause, param_env, trait_return_ty, impl_return_ty) {
+        Ok(()) => {}
         Err(terr) => {
             let mut diag = struct_span_err!(
                 tcx.sess,
@@ -442,10 +440,8 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
     // the lifetimes of the return type, but do this after unifying just the
     // return types, since we want to avoid duplicating errors from
     // `compare_predicate_entailment`.
-    match infcx.at(&cause, param_env).eq(trait_fty, impl_fty) {
-        Ok(infer::InferOk { value: (), obligations }) => {
-            ocx.register_obligations(obligations);
-        }
+    match ocx.eq(&cause, param_env, trait_fty, impl_fty) {
+        Ok(()) => {}
         Err(terr) => {
             // This function gets called during `compare_predicate_entailment` when normalizing a
             // signature that contains RPITIT. When the method signatures don't match, we have to
@@ -688,9 +684,7 @@ fn report_trait_method_mismatch<'tcx>(
                 // Suggestion to change output type. We do not suggest in `async` functions
                 // to avoid complex logic or incorrect output.
                 match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
-                    ImplItemKind::Fn(ref sig, _)
-                        if sig.header.asyncness == hir::IsAsync::NotAsync =>
-                    {
+                    ImplItemKind::Fn(ref sig, _) if !sig.header.asyncness.is_async() => {
                         let msg = "change the output type to match the trait";
                         let ap = Applicability::MachineApplicable;
                         match sig.decl.output {
index 2f64a88f03afee960de39d40c1ecdab032e55fd3..a738ee4a14887ae60c0d41d7e2ff8d98aa429750 100644 (file)
@@ -518,7 +518,7 @@ fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
         ty
     }
 
-    fn set_tainted_by_errors(&self) {
+    fn set_tainted_by_errors(&self, _: ErrorGuaranteed) {
         // There's no obvious place to track this, so just let it go.
     }
 
index 4359124646df15b984a0662344532fe93821feca..9c77387c238fe43016efe1b4f1b538fe7e0883d1 100644 (file)
@@ -728,7 +728,8 @@ fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
         && let Some(trait_path_segment) = path.segments.get(0) {
             let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params();
 
-            if num_assoc_fn_excess_args == num_trait_generics_except_self - num_generic_args_supplied_to_trait {
+            if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args == num_trait_generics_except_self
+            {
                 if let Some(span) = self.gen_args.span_ext()
                 && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
                     let sugg = vec![
index 7d3129f7ea730567e0bbaefbdc263ca0c27c5f5f..e5dc4b06c0ba620ade32f1d8a79b7feab64bd322 100644 (file)
@@ -33,6 +33,7 @@
 use crate::type_error_struct;
 use rustc_errors::{struct_span_err, Applicability, DelayDm, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir as hir;
+use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::cast::{CastKind, CastTy};
@@ -67,7 +68,7 @@ pub struct CastCheck<'tcx> {
 /// The kind of pointer and associated metadata (thin, length or vtable) - we
 /// only allow casts between fat pointers if their metadata have the same
 /// kind.
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, TypeVisitable, TypeFoldable)]
 enum PointerKind<'tcx> {
     /// No metadata attached, ie pointer to sized type or foreign type
     Thin,
@@ -76,11 +77,11 @@ enum PointerKind<'tcx> {
     /// Slice
     Length,
     /// The unsize info of this projection
-    OfProjection(&'tcx ty::ProjectionTy<'tcx>),
+    OfProjection(ty::ProjectionTy<'tcx>),
     /// The unsize info of this opaque ty
     OfOpaque(DefId, SubstsRef<'tcx>),
     /// The unsize info of this parameter
-    OfParam(&'tcx ty::ParamTy),
+    OfParam(ty::ParamTy),
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -118,9 +119,9 @@ fn pointer_kind(
             // Pointers to foreign types are thin, despite being unsized
             ty::Foreign(..) => Some(PointerKind::Thin),
             // We should really try to normalize here.
-            ty::Projection(ref pi) => Some(PointerKind::OfProjection(pi)),
+            ty::Projection(pi) => Some(PointerKind::OfProjection(pi)),
             ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)),
-            ty::Param(ref p) => Some(PointerKind::OfParam(p)),
+            ty::Param(p) => Some(PointerKind::OfParam(p)),
             // Insufficient type information.
             ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None,
 
@@ -909,7 +910,7 @@ fn check_ptr_ptr_cast(
         }
 
         // vtable kinds must match
-        if cast_kind == expr_kind {
+        if fcx.tcx.erase_regions(cast_kind) == fcx.tcx.erase_regions(expr_kind) {
             Ok(CastKind::PtrPtrCast)
         } else {
             Err(CastError::DifferingKinds)
index 174b43313825e1b770760d191e3249529beacc89..af0b7f62ae3195f6ce058bde7b0cf97be631efc1 100644 (file)
@@ -775,7 +775,7 @@ fn coerce_dyn_star(
 
         // Check the obligations of the cast -- for example, when casting
         // `usize` to `dyn* Clone + 'static`:
-        let obligations = predicates
+        let mut obligations: Vec<_> = predicates
             .iter()
             .map(|predicate| {
                 // For each existential predicate (e.g., `?Self: Clone`) substitute
@@ -785,16 +785,33 @@ fn coerce_dyn_star(
                 let predicate = predicate.with_self_ty(self.tcx, a);
                 Obligation::new(self.tcx, self.cause.clone(), self.param_env, predicate)
             })
-            // Enforce the region bound (e.g., `usize: 'static`, in our example).
-            .chain([Obligation::new(
+            .chain([
+                // Enforce the region bound (e.g., `usize: 'static`, in our example).
+                Obligation::new(
+                    self.tcx,
+                    self.cause.clone(),
+                    self.param_env,
+                    ty::Binder::dummy(ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
+                        a, b_region,
+                    ))),
+                ),
+            ])
+            .collect();
+
+        // Enforce that the type is `usize`/pointer-sized. For now, only those
+        // can be coerced to `dyn*`, except for `dyn* -> dyn*` upcasts.
+        if !a.is_dyn_star() {
+            obligations.push(Obligation::new(
                 self.tcx,
                 self.cause.clone(),
                 self.param_env,
-                self.tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
-                    ty::OutlivesPredicate(a, b_region),
-                ))),
-            )])
-            .collect();
+                ty::Binder::dummy(ty::TraitRef::new(
+                    self.tcx.require_lang_item(hir::LangItem::PointerSized, Some(self.cause.span)),
+                    self.tcx.mk_substs_trait(a, &[]),
+                ))
+                .to_poly_trait_predicate(),
+            ));
+        }
 
         Ok(InferOk {
             value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b),
@@ -1544,7 +1561,9 @@ pub(crate) fn coerce_inner<'a>(
                 // Mark that we've failed to coerce the types here to suppress
                 // any superfluous errors we might encounter while trying to
                 // emit or provide suggestions on how to fix the initial error.
-                fcx.set_tainted_by_errors();
+                fcx.set_tainted_by_errors(
+                    fcx.tcx.sess.delay_span_bug(cause.span, "coercion error but no error emitted"),
+                );
                 let (expected, found) = if label_expression_as_expected {
                     // In the case where this is a "forced unit", like
                     // `break`, we want to call the `()` "expected"
index 9ca7730daa68d3ee71d2b7db1b03a951841c4be1..5a34ab401749f74491f92a45ec04a1b0786e5434 100644 (file)
@@ -154,7 +154,10 @@ pub fn demand_coerce_diag(
             Err(e) => e,
         };
 
-        self.set_tainted_by_errors();
+        self.set_tainted_by_errors(self.tcx.sess.delay_span_bug(
+            expr.span,
+            "`TypeError` when attempting coercion but no error emitted",
+        ));
         let expr = expr.peel_drop_temps();
         let cause = self.misc(expr.span);
         let expr_ty = self.resolve_vars_with_obligations(checked_ty);
index afac6e7d94a8116ca0ef9916c61c569d1f24dbfb..32265bcca45349ee4e6bbede9e058b4e543c3e80 100644 (file)
@@ -1,4 +1,5 @@
 //! Errors emitted by `rustc_hir_analysis`.
+use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_middle::ty::Ty;
 use rustc_span::{symbol::Ident, Span};
@@ -133,3 +134,41 @@ pub struct OpMethodGenericParams {
     pub span: Span,
     pub method_name: String,
 }
+
+pub struct TypeMismatchFruTypo {
+    /// Span of the LHS of the range
+    pub expr_span: Span,
+    /// Span of the `..RHS` part of the range
+    pub fru_span: Span,
+    /// Rendered expression of the RHS of the range
+    pub expr: Option<String>,
+}
+
+impl AddToDiagnostic for TypeMismatchFruTypo {
+    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
+    where
+        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
+    {
+        diag.set_arg("expr", self.expr.as_deref().unwrap_or("NONE"));
+
+        // Only explain that `a ..b` is a range if it's split up
+        if self.expr_span.between(self.fru_span).is_empty() {
+            diag.span_note(
+                self.expr_span.to(self.fru_span),
+                rustc_errors::fluent::hir_typeck_fru_note,
+            );
+        } else {
+            let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into();
+            multispan.push_span_label(self.expr_span, rustc_errors::fluent::hir_typeck_fru_expr);
+            multispan.push_span_label(self.fru_span, rustc_errors::fluent::hir_typeck_fru_expr2);
+            diag.span_note(multispan, rustc_errors::fluent::hir_typeck_fru_note);
+        }
+
+        diag.span_suggestion(
+            self.expr_span.shrink_to_hi(),
+            rustc_errors::fluent::hir_typeck_fru_suggestion,
+            ", ",
+            Applicability::MaybeIncorrect,
+        );
+    }
+}
index 13a03b33de815bad406e8aa0b52ceb7d6e3c74e5..2764de751b08bc3fd52211d37500ddfa27bd58d8 100644 (file)
@@ -5,6 +5,7 @@
 use crate::cast;
 use crate::coercion::CoerceMany;
 use crate::coercion::DynamicCoerceMany;
+use crate::errors::TypeMismatchFruTypo;
 use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
 use crate::errors::{
     FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
@@ -527,12 +528,14 @@ pub(crate) fn check_expr_path(
             self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
         let ty = match res {
             Res::Err => {
-                self.set_tainted_by_errors();
-                tcx.ty_error()
+                let e =
+                    self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
+                self.set_tainted_by_errors(e);
+                tcx.ty_error_with_guaranteed(e)
             }
             Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
-                report_unexpected_variant_res(tcx, res, qpath, expr.span);
-                tcx.ty_error()
+                let e = report_unexpected_variant_res(tcx, res, qpath, expr.span);
+                tcx.ty_error_with_guaranteed(e)
             }
             _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
         };
@@ -1614,10 +1617,16 @@ fn check_expr_struct_fields(
                 self.demand_coerce_diag(&field.expr, ty, field_type, None, AllowTwoPhase::No);
 
             if let Some(mut diag) = diag {
-                if idx == ast_fields.len() - 1 && remaining_fields.is_empty() {
-                    self.suggest_fru_from_range(field, variant, substs, &mut diag);
+                if idx == ast_fields.len() - 1 {
+                    if remaining_fields.is_empty() {
+                        self.suggest_fru_from_range(field, variant, substs, &mut diag);
+                        diag.emit();
+                    } else {
+                        diag.stash(field.span, StashKey::MaybeFruTypo);
+                    }
+                } else {
+                    diag.emit();
                 }
-                diag.emit();
             }
         }
 
@@ -1875,19 +1884,39 @@ fn suggest_fru_from_range(
                 .map(|adt| adt.did())
                 != range_def_id
         {
-            let instead = self
+            // Suppress any range expr type mismatches
+            if let Some(mut diag) = self
+                .tcx
+                .sess
+                .diagnostic()
+                .steal_diagnostic(last_expr_field.span, StashKey::MaybeFruTypo)
+            {
+                diag.delay_as_bug();
+            }
+
+            // Use a (somewhat arbitrary) filtering heuristic to avoid printing
+            // expressions that are either too long, or have control character
+            //such as newlines in them.
+            let expr = self
                 .tcx
                 .sess
                 .source_map()
                 .span_to_snippet(range_end.expr.span)
-                .map(|s| format!(" from `{s}`"))
-                .unwrap_or_default();
-            err.span_suggestion(
-                range_start.span.shrink_to_hi(),
-                &format!("to set the remaining fields{instead}, separate the last named field with a comma"),
-                ",",
-                Applicability::MaybeIncorrect,
-            );
+                .ok()
+                .filter(|s| s.len() < 25 && !s.contains(|c: char| c.is_control()));
+
+            let fru_span = self
+                .tcx
+                .sess
+                .source_map()
+                .span_extend_while(range_start.span, |c| c.is_whitespace())
+                .unwrap_or(range_start.span).shrink_to_hi().to(range_end.span);
+
+            err.subdiagnostic(TypeMismatchFruTypo {
+                expr_span: range_start.span,
+                fru_span,
+                expr,
+            });
         }
     }
 
@@ -1962,7 +1991,11 @@ fn report_unknown_field(
         expr_span: Span,
     ) {
         if variant.is_recovered() {
-            self.set_tainted_by_errors();
+            self.set_tainted_by_errors(
+                self.tcx
+                    .sess
+                    .delay_span_bug(expr_span, "parser recovered but no error was emitted"),
+            );
             return;
         }
         let mut err = self.err_ctxt().type_error_struct_with_diag(
index 5d44092a5f68e33c440e652e24608bf9745ba161..ac6b0924ab572498a4cc36f9fe8187f1b93b38ed 100644 (file)
@@ -104,7 +104,7 @@ fn fallback_if_possible(
         // type, `?T` is not considered unsolved, but `?I` is. The
         // same is true for float variables.)
         let fallback = match ty.kind() {
-            _ if self.is_tainted_by_errors() => self.tcx.ty_error(),
+            _ if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e),
             ty::Infer(ty::IntVar(_)) => self.tcx.types.i32,
             ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64,
             _ => match diverging_fallback.get(&ty) {
index c826a886ca6415ea099c145cc7ee1416f85d1500..b85a23257286b6ddfad19fffb788d93e567a8001 100644 (file)
@@ -140,8 +140,8 @@ pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
         debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag());
         self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
 
-        if ty.references_error() {
-            self.set_tainted_by_errors();
+        if let Err(e) = ty.error_reported() {
+            self.set_tainted_by_errors(e);
         }
     }
 
@@ -528,7 +528,7 @@ fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
     pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
         match self.typeck_results.borrow().node_types().get(id) {
             Some(&t) => t,
-            None if self.is_tainted_by_errors() => self.tcx.ty_error(),
+            None if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e),
             None => {
                 bug!(
                     "no type for node {}: {} in fcx {}",
@@ -543,7 +543,7 @@ pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
     pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
         match self.typeck_results.borrow().node_types().get(id) {
             Some(&t) => Some(t),
-            None if self.is_tainted_by_errors() => Some(self.tcx.ty_error()),
+            None if let Some(e) = self.tainted_by_errors() => Some(self.tcx.ty_error_with_guaranteed(e)),
             None => None,
         }
     }
@@ -1148,9 +1148,9 @@ pub fn instantiate_value_path(
                 explicit_late_bound = ExplicitLateBound::Yes;
             }
 
-            if let Err(GenericArgCountMismatch { reported: Some(_), .. }) = arg_count.correct {
+            if let Err(GenericArgCountMismatch { reported: Some(e), .. }) = arg_count.correct {
                 infer_args_for_err.insert(index);
-                self.set_tainted_by_errors(); // See issue #53251.
+                self.set_tainted_by_errors(e); // See issue #53251.
             }
         }
 
@@ -1440,12 +1440,12 @@ pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
         if !ty.is_ty_var() {
             ty
         } else {
-            if !self.is_tainted_by_errors() {
+            let e = self.tainted_by_errors().unwrap_or_else(|| {
                 self.err_ctxt()
                     .emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true)
-                    .emit();
-            }
-            let err = self.tcx.ty_error();
+                    .emit()
+            });
+            let err = self.tcx.ty_error_with_guaranteed(e);
             self.demand_suptype(sp, err, ty);
             err
         }
index c3833b4872d99073379d15c96a380966f95d5437..a31ab9c8b23b899c00dcad27aad6b7f8816e9a54 100644 (file)
@@ -511,8 +511,11 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
             tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var())
         }
 
-        self.set_tainted_by_errors();
         let tcx = self.tcx;
+        // FIXME: taint after emitting errors and pass through an `ErrorGuaranteed`
+        self.set_tainted_by_errors(
+            tcx.sess.delay_span_bug(call_span, "no errors reported for args"),
+        );
 
         // Get the argument span in the context of the call span so that
         // suggestions and labels are (more) correct when an arg is a
@@ -1207,7 +1210,9 @@ pub fn check_struct_path(
         let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
         let variant = match def {
             Res::Err => {
-                self.set_tainted_by_errors();
+                self.set_tainted_by_errors(
+                    self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"),
+                );
                 return None;
             }
             Res::Def(DefKind::Variant, _) => match ty.kind() {
index d5e4b6de581c3551a2af1020a282790f0807f431..177d521d2804cd1e1ff08f4e769229b64fd28f4a 100644 (file)
@@ -4,6 +4,7 @@
 mod suggestions;
 
 pub use _impl::*;
+use rustc_errors::ErrorGuaranteed;
 pub use suggestions::*;
 
 use crate::coercion::DynamicCoerceMany;
@@ -289,8 +290,8 @@ fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
         }
     }
 
-    fn set_tainted_by_errors(&self) {
-        self.infcx.set_tainted_by_errors()
+    fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
+        self.infcx.set_tainted_by_errors(e)
     }
 
     fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
index 316ecb0ed52e43ede435315efc195462f63f4bc8..9f5aadca967bd4748d0ccaafd4d7bec42fade531 100644 (file)
@@ -464,7 +464,7 @@ pub fn suggest_deref_ref_or_into(
                     ref_cnt += 1;
                 }
                 if let ty::Adt(adt, _) = peeled.kind()
-                    && self.tcx.is_diagnostic_item(sym::String, adt.did())
+                    && Some(adt.did()) == self.tcx.lang_items().string()
                 {
                     err.span_suggestion_verbose(
                         expr.span.shrink_to_hi(),
index 6fd609aeaa060f781220c9f96d63326b7d09bdd7..334d6d0aa6c209838c6a042895e8d94eab3e7742 100644 (file)
@@ -53,7 +53,7 @@
 use crate::coercion::DynamicCoerceMany;
 use crate::gather_locals::GatherLocalsVisitor;
 use rustc_data_structures::unord::UnordSet;
-use rustc_errors::{struct_span_err, MultiSpan};
+use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::intravisit::Visitor;
@@ -344,7 +344,7 @@ fn typeck_with_fallback<'tcx>(
 
         fcx.select_all_obligations_or_error();
 
-        if !fcx.infcx.is_tainted_by_errors() {
+        if let None = fcx.infcx.tainted_by_errors() {
             fcx.check_transmutes();
         }
 
@@ -428,7 +428,12 @@ fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut Breakable
     }
 }
 
-fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<'_>, span: Span) {
+fn report_unexpected_variant_res(
+    tcx: TyCtxt<'_>,
+    res: Res,
+    qpath: &hir::QPath<'_>,
+    span: Span,
+) -> ErrorGuaranteed {
     struct_span_err!(
         tcx.sess,
         span,
@@ -437,7 +442,7 @@ fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<'
         res.descr(),
         rustc_hir_pretty::qpath_to_string(qpath),
     )
-    .emit();
+    .emit()
 }
 
 /// Controls whether the arguments are tupled. This is used for the call
index 362f1c3430041a45e668c263b825e7f790a2fbc9..0b5dc946c1deffa589f20f036542cfacc7edd6a8 100644 (file)
@@ -133,7 +133,7 @@ fn resolve_vars_if_possible<T>(&self, value: T) -> T
     }
 
     fn is_tainted_by_errors(&self) -> bool {
-        self.infcx.is_tainted_by_errors()
+        self.infcx.tainted_by_errors().is_some()
     }
 
     fn resolve_type_vars_or_error(
index e2c5edd0e8833bfa32936b65faa2e1c748d6ab69..8190163cba15b4bb8fde3ae5d1f86f3aa2c0439b 100644 (file)
@@ -114,7 +114,7 @@ pub fn report_method_error(
         let report_candidates = |span: Span,
                                  err: &mut Diagnostic,
                                  sources: &mut Vec<CandidateSource>,
-                                 sugg_span: Span| {
+                                 sugg_span: Option<Span>| {
             sources.sort();
             sources.dedup();
             // Dynamic limit to avoid hiding just one candidate, which is silly.
@@ -175,7 +175,8 @@ pub fn report_method_error(
                         } else {
                             err.note(&note_str);
                         }
-                        if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) {
+                        if let Some(sugg_span) = sugg_span
+                            && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) {
                             let path = self.tcx.def_path_str(trait_ref.def_id);
 
                             let ty = match item.kind {
@@ -224,20 +225,22 @@ pub fn report_method_error(
                             err.span_note(item_span, msg);
                             None
                         };
-                        let path = self.tcx.def_path_str(trait_did);
-                        print_disambiguation_help(
-                            item_name,
-                            args,
-                            err,
-                            path,
-                            rcvr_ty,
-                            item.kind,
-                            item.def_id,
-                            sugg_span,
-                            idx,
-                            self.tcx.sess.source_map(),
-                            item.fn_has_self_parameter,
-                        );
+                        if let Some(sugg_span) = sugg_span {
+                            let path = self.tcx.def_path_str(trait_did);
+                            print_disambiguation_help(
+                                item_name,
+                                args,
+                                err,
+                                path,
+                                rcvr_ty,
+                                item.kind,
+                                item.def_id,
+                                sugg_span,
+                                idx,
+                                self.tcx.sess.source_map(),
+                                item.fn_has_self_parameter,
+                            );
+                        }
                     }
                 }
             }
@@ -407,9 +410,9 @@ pub fn report_method_error(
                         sugg_span,
                     );
 
-                    report_candidates(span, &mut err, &mut static_candidates, sugg_span);
+                    report_candidates(span, &mut err, &mut static_candidates, None);
                 } else if static_candidates.len() > 1 {
-                    report_candidates(span, &mut err, &mut static_candidates, sugg_span);
+                    report_candidates(span, &mut err, &mut static_candidates, Some(sugg_span));
                 }
 
                 let mut bound_spans = vec![];
@@ -818,10 +821,10 @@ trait bound{s}",
                                 ty.is_str()
                                     || matches!(
                                         ty.kind(),
-                                        ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did())
+                                        ty::Adt(adt, _) if Some(adt.did()) == self.tcx.lang_items().string()
                                     )
                             }
-                            ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did()),
+                            ty::Adt(adt, _) => Some(adt.did()) == self.tcx.lang_items().string(),
                             _ => false,
                         };
                         if is_string_or_ref_str && item_name.name == sym::iter {
@@ -1015,7 +1018,7 @@ trait bound{s}",
                 );
                 err.span_label(item_name.span, format!("multiple `{}` found", item_name));
 
-                report_candidates(span, &mut err, &mut sources, sugg_span);
+                report_candidates(span, &mut err, &mut sources, Some(sugg_span));
                 err.emit();
             }
 
@@ -1915,12 +1918,12 @@ fn check_for_deref_method(
                         | ty::Str
                         | ty::Projection(_)
                         | ty::Param(_) => format!("{deref_ty}"),
-                        // we need to test something like  <&[_]>::len
+                        // we need to test something like  <&[_]>::len or <(&[u32])>::len
                         // and Vec::function();
-                        // <&[_]>::len doesn't need an extra "<>" between
+                        // <&[_]>::len or <&[u32]>::len doesn't need an extra "<>" between
                         // but for Adt type like Vec::function()
                         // we would suggest <[_]>::function();
-                        _ if self.tcx.sess.source_map().span_wrapped_by_angle_bracket(ty.span)  => format!("{deref_ty}"),
+                        _ if self.tcx.sess.source_map().span_wrapped_by_angle_or_parentheses(ty.span)  => format!("{deref_ty}"),
                         _ => format!("<{deref_ty}>"),
                     };
                     err.span_suggestion_verbose(
index 38b3dd218a9719b4b28fcc41ff354c66bb50c42b..adc7a21f265a82be3cec68264b95a88ee6c42ef2 100644 (file)
@@ -556,9 +556,9 @@ fn check_str_addition(
         let rm_borrow_msg = "remove the borrow to obtain an owned `String`";
         let to_owned_msg = "create an owned `String` from a string reference";
 
+        let string_type = self.tcx.lang_items().string();
         let is_std_string = |ty: Ty<'tcx>| {
-            ty.ty_adt_def()
-                .map_or(false, |ty_def| self.tcx.is_diagnostic_item(sym::String, ty_def.did()))
+            ty.ty_adt_def().map_or(false, |ty_def| Some(ty_def.did()) == string_type)
         };
 
         match (lhs_ty.kind(), rhs_ty.kind()) {
index eb10f3e2c107f8f943b9d17c30cd8238b5fc9d8f..1d021f19104eae943f302a68c64b3f1b1e193b00 100644 (file)
@@ -401,6 +401,16 @@ fn check_pat_lit(
             }
         }
 
+        if self.tcx.features().string_deref_patterns && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind {
+            let tcx = self.tcx;
+            let expected = self.resolve_vars_if_possible(expected);
+            pat_ty = match expected.kind() {
+                ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => expected,
+                ty::Str => tcx.mk_static_str(),
+                _ => pat_ty,
+            };
+        }
+
         // Somewhat surprising: in this case, the subtyping relation goes the
         // opposite way as the other cases. Actually what we really want is not
         // a subtyping relation at all but rather that there exists a LUB
@@ -839,12 +849,13 @@ fn check_pat_path(
         let (res, opt_ty, segments) = path_resolution;
         match res {
             Res::Err => {
-                self.set_tainted_by_errors();
-                return tcx.ty_error();
+                let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
+                self.set_tainted_by_errors(e);
+                return tcx.ty_error_with_guaranteed(e);
             }
             Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => {
-                report_unexpected_variant_res(tcx, res, qpath, pat.span);
-                return tcx.ty_error();
+                let e = report_unexpected_variant_res(tcx, res, qpath, pat.span);
+                return tcx.ty_error_with_guaranteed(e);
             }
             Res::SelfCtor(..)
             | Res::Def(
@@ -985,9 +996,9 @@ fn check_pat_tuple_struct(
         ti: TopInfo<'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
-        let on_error = || {
+        let on_error = |e| {
             for pat in subpats {
-                self.check_pat(pat, tcx.ty_error(), def_bm, ti);
+                self.check_pat(pat, tcx.ty_error_with_guaranteed(e), def_bm, ti);
             }
         };
         let report_unexpected_res = |res: Res| {
@@ -1014,36 +1025,39 @@ fn check_pat_tuple_struct(
                     err.span_label(pat.span, "not a tuple variant or struct");
                 }
             }
-            err.emit();
-            on_error();
+            let e = err.emit();
+            on_error(e);
+            e
         };
 
         // Resolve the path and check the definition for errors.
         let (res, opt_ty, segments) =
             self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
         if res == Res::Err {
-            self.set_tainted_by_errors();
-            on_error();
-            return self.tcx.ty_error();
+            let e = tcx.sess.delay_span_bug(pat.span, "`Res:Err` but no error emitted");
+            self.set_tainted_by_errors(e);
+            on_error(e);
+            return tcx.ty_error_with_guaranteed(e);
         }
 
         // Type-check the path.
         let (pat_ty, res) =
             self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
         if !pat_ty.is_fn() {
-            report_unexpected_res(res);
-            return tcx.ty_error();
+            let e = report_unexpected_res(res);
+            return tcx.ty_error_with_guaranteed(e);
         }
 
         let variant = match res {
             Res::Err => {
-                self.set_tainted_by_errors();
-                on_error();
-                return tcx.ty_error();
+                let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted");
+                self.set_tainted_by_errors(e);
+                on_error(e);
+                return tcx.ty_error_with_guaranteed(e);
             }
             Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
-                report_unexpected_res(res);
-                return tcx.ty_error();
+                let e = report_unexpected_res(res);
+                return tcx.ty_error_with_guaranteed(e);
             }
             Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
             _ => bug!("unexpected pattern resolution: {:?}", res),
@@ -1082,9 +1096,9 @@ fn check_pat_tuple_struct(
             }
         } else {
             // Pattern has wrong number of fields.
-            self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
-            on_error();
-            return tcx.ty_error();
+            let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
+            on_error(e);
+            return tcx.ty_error_with_guaranteed(e);
         }
         pat_ty
     }
@@ -1098,7 +1112,7 @@ fn e0023(
         fields: &'tcx [ty::FieldDef],
         expected: Ty<'tcx>,
         had_err: bool,
-    ) {
+    ) -> ErrorGuaranteed {
         let subpats_ending = pluralize!(subpats.len());
         let fields_ending = pluralize!(fields.len());
 
@@ -1245,7 +1259,7 @@ fn e0023(
             }
         }
 
-        err.emit();
+        err.emit()
     }
 
     fn check_pat_tuple(
index 2eca40d678a849c48633b738d34bf022907c88ce..6c2ee35fa50da5b1daef213e9941db8fc3510113 100644 (file)
@@ -83,10 +83,8 @@ pub fn resolve_type_vars_in_body(
         wbcx.typeck_results.treat_byte_string_as_slice =
             mem::take(&mut self.typeck_results.borrow_mut().treat_byte_string_as_slice);
 
-        if self.is_tainted_by_errors() {
-            // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted.
-            wbcx.typeck_results.tainted_by_errors =
-                Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+        if let Some(e) = self.tainted_by_errors() {
+            wbcx.typeck_results.tainted_by_errors = Some(e);
         }
 
         debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results);
@@ -674,10 +672,8 @@ fn resolve<T>(&mut self, x: T, span: &dyn Locatable) -> T
         // We may have introduced e.g. `ty::Error`, if inference failed, make sure
         // to mark the `TypeckResults` as tainted in that case, so that downstream
         // users of the typeck results don't produce extra errors, or worse, ICEs.
-        if resolver.replaced_with_error {
-            // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted.
-            self.typeck_results.tainted_by_errors =
-                Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+        if let Some(e) = resolver.replaced_with_error {
+            self.typeck_results.tainted_by_errors = Some(e);
         }
 
         x
@@ -708,8 +704,8 @@ struct Resolver<'cx, 'tcx> {
     span: &'cx dyn Locatable,
     body: &'tcx hir::Body<'tcx>,
 
-    /// Set to `true` if any `Ty` or `ty::Const` had to be replaced with an `Error`.
-    replaced_with_error: bool,
+    /// Set to `Some` if any `Ty` or `ty::Const` had to be replaced with an `Error`.
+    replaced_with_error: Option<ErrorGuaranteed>,
 }
 
 impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
@@ -718,12 +714,14 @@ fn new(
         span: &'cx dyn Locatable,
         body: &'tcx hir::Body<'tcx>,
     ) -> Resolver<'cx, 'tcx> {
-        Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: false }
+        Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: None }
     }
 
-    fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) {
-        if !self.tcx.sess.has_errors().is_some() {
-            self.infcx
+    fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed {
+        match self.tcx.sess.has_errors() {
+            Some(e) => e,
+            None => self
+                .infcx
                 .err_ctxt()
                 .emit_inference_failure_err(
                     Some(self.body.id()),
@@ -732,7 +730,7 @@ fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) {
                     E0282,
                     false,
                 )
-                .emit();
+                .emit(),
         }
     }
 }
@@ -773,9 +771,9 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
             }
             Err(_) => {
                 debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
-                self.report_error(t);
-                self.replaced_with_error = true;
-                self.tcx().ty_error()
+                let e = self.report_error(t);
+                self.replaced_with_error = Some(e);
+                self.tcx().ty_error_with_guaranteed(e)
             }
         }
     }
@@ -790,9 +788,9 @@ fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
             Ok(ct) => self.tcx.erase_regions(ct),
             Err(_) => {
                 debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
-                self.report_error(ct);
-                self.replaced_with_error = true;
-                self.tcx().const_error(ct.ty())
+                let e = self.report_error(ct);
+                self.replaced_with_error = Some(e);
+                self.tcx().const_error_with_guaranteed(ct.ty(), e)
             }
         }
     }
index fd3b3e4d59fa699d7570a708814025e0519e7e3e..b9ed6b28c220d1f47172421bedf05f593f661dd9 100644 (file)
@@ -34,7 +34,7 @@
 use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
 use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
 use rustc_span::symbol::Symbol;
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
 
 use std::cell::{Cell, RefCell};
 use std::fmt;
@@ -1208,7 +1208,8 @@ pub fn fresh_substs_for_item(&self, span: Span, def_id: DefId) -> SubstsRef<'tcx
     /// reporting errors that often occur as a result of earlier
     /// errors, but where it's hard to be 100% sure (e.g., unresolved
     /// inference variables, regionck errors).
-    pub fn is_tainted_by_errors(&self) -> bool {
+    #[must_use = "this method does not have any side effects"]
+    pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
         debug!(
             "is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
              tainted_by_errors={})",
@@ -1217,19 +1218,25 @@ pub fn is_tainted_by_errors(&self) -> bool {
             self.tainted_by_errors.get().is_some()
         );
 
+        if let Some(e) = self.tainted_by_errors.get() {
+            return Some(e);
+        }
+
         if self.tcx.sess.err_count() > self.err_count_on_creation {
-            return true; // errors reported since this infcx was made
+            // errors reported since this infcx was made
+            let e = self.tcx.sess.has_errors().unwrap();
+            self.set_tainted_by_errors(e);
+            return Some(e);
         }
-        self.tainted_by_errors.get().is_some()
+
+        None
     }
 
     /// Set the "tainted by errors" flag to true. We call this when we
     /// observe an error from a prior pass.
-    pub fn set_tainted_by_errors(&self) {
-        debug!("set_tainted_by_errors()");
-        self.tainted_by_errors.set(Some(
-            self.tcx.sess.delay_span_bug(DUMMY_SP, "`InferCtxt` incorrectly tainted by errors"),
-        ));
+    pub fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
+        debug!("set_tainted_by_errors(ErrorGuaranteed)");
+        self.tainted_by_errors.set(Some(e));
     }
 
     pub fn skip_region_resolution(&self) {
@@ -1270,7 +1277,7 @@ pub fn resolve_regions(
             let mut inner = self.inner.borrow_mut();
             let inner = &mut *inner;
             assert!(
-                self.is_tainted_by_errors() || inner.region_obligations.is_empty(),
+                self.tainted_by_errors().is_some() || inner.region_obligations.is_empty(),
                 "region_obligations not empty: {:#?}",
                 inner.region_obligations
             );
@@ -1707,7 +1714,7 @@ pub fn resolve_regions_and_report_errors(
     ) {
         let errors = self.resolve_regions(outlives_env);
 
-        if !self.is_tainted_by_errors() {
+        if let None = self.tainted_by_errors() {
             // As a heuristic, just skip reporting region errors
             // altogether if other errors have been reported while
             // this infcx was in use.  This is totally hokey but
index 600f94f095eace0056fc0af4292245a197946f0f..167a82d4499a188603895a21b2bfe9349d628341 100644 (file)
@@ -556,8 +556,9 @@ fn relate_with_variance<T: Relate<'tcx>>(
         self.ambient_variance_info = self.ambient_variance_info.xform(info);
 
         debug!(?self.ambient_variance);
-
-        let r = self.relate(a, b)?;
+        // In a bivariant context this always succeeds.
+        let r =
+            if self.ambient_variance == ty::Variance::Bivariant { a } else { self.relate(a, b)? };
 
         self.ambient_variance = old_ambient_variance;
 
index 8c8445a4d9eb847695970878ea591acacce012d6..bd3c5780b891bb28efae312459722b10febf7e43 100644 (file)
@@ -116,9 +116,9 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
                 Ok(a)
             }
 
-            (&ty::Error(_), _) | (_, &ty::Error(_)) => {
-                infcx.set_tainted_by_errors();
-                Ok(self.tcx().ty_error())
+            (&ty::Error(e), _) | (_, &ty::Error(e)) => {
+                infcx.set_tainted_by_errors(e);
+                Ok(self.tcx().ty_error_with_guaranteed(e))
             }
 
             (&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
index 2e526733df974b6e33a7c287505c46f200669f33..e67dec31dcee377d3387929efe32c87cbcc44bdd 100644 (file)
@@ -53,4 +53,4 @@ rustc_target = { path = "../rustc_target" }
 
 [features]
 llvm = ['rustc_codegen_llvm']
-rustc_use_parallel_compiler = ['rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler']
+rustc_use_parallel_compiler = ['rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler', 'rustc_errors/rustc_use_parallel_compiler']
index aee870dd29d652bb533ae8f3f231a655c293b664..fc760ee3b8fa03281a3fd88bf768f894ca81e208 100644 (file)
@@ -212,7 +212,10 @@ fn visit_expr_post(&mut self, e: &'a ast::Expr) {
         // Explicitly check for lints associated with 'closure_id', since
         // it does not have a corresponding AST node
         match e.kind {
-            ast::ExprKind::Closure(_, _, ast::Async::Yes { closure_id, .. }, ..)
+            ast::ExprKind::Closure(box ast::Closure {
+                asyncness: ast::Async::Yes { closure_id, .. },
+                ..
+            })
             | ast::ExprKind::Async(_, closure_id, ..) => self.check_id(closure_id),
             _ => {}
         }
index 6ad2e0294b9b0af0774f81ed9422479c691e2a0a..83e6f4e33bed8ecf227c65d3571c3d58c05f3562 100644 (file)
@@ -148,7 +148,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
                 ty::Ref(_, r, _) if *r.kind() == ty::Str,
             ) || matches!(
                 ty.ty_adt_def(),
-                Some(ty_def) if cx.tcx.is_diagnostic_item(sym::String, ty_def.did()),
+                Some(ty_def) if Some(ty_def.did()) == cx.tcx.lang_items().string(),
             );
 
             let infcx = cx.tcx.infer_ctxt().build();
index 9ae34013ecb8ae17ef44687e653d75ee220f0c4a..cdf279313a6726e0985cdd0d51c45d11576c7618 100644 (file)
@@ -582,7 +582,7 @@ fn emit_unused_delims(
                 let sm = cx.sess().source_map();
                 let lo_replace =
                     if keep_space.0 &&
-                        let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(" ") {
+                        let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(' ') {
                         " ".to_string()
                         } else {
                             "".to_string()
@@ -590,7 +590,7 @@ fn emit_unused_delims(
 
                 let hi_replace =
                     if keep_space.1 &&
-                        let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(" ") {
+                        let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(' ') {
                         " ".to_string()
                         } else {
                             "".to_string()
@@ -651,7 +651,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
             ref call_or_other => {
                 let (args_to_check, ctx) = match *call_or_other {
                     Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg),
-                    MethodCall(_, _, ref args, _) => (&args[..], UnusedDelimsCtx::MethodArg),
+                    MethodCall(ref call) => (&call.args[..], UnusedDelimsCtx::MethodArg),
                     // actual catch-all arm
                     _ => {
                         return;
index 1b2cde605556dcd4ee0141333c06cab68fca5a7d..3c50827c1abc33abba077405029d7a91aaa61e2c 100644 (file)
@@ -4,7 +4,6 @@ version = "0.0.0"
 edition = "2021"
 
 [dependencies]
-atty = "0.2"
 tracing = "0.1.28"
 tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
 tracing-tree = "0.2.0"
index 458f5e87baeacff3d4d72e44cb95b8f5c2874ef0..ddf29c488c933284433fd2f63376c2d7367e28cf 100644 (file)
 
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
+#![feature(is_terminal)]
 
 use std::env::{self, VarError};
 use std::fmt::{self, Display};
-use std::io;
+use std::io::{self, IsTerminal};
 use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter};
 use tracing_subscriber::layer::SubscriberExt;
 
@@ -93,11 +94,11 @@ pub fn init_env_logger(env: &str) -> Result<(), Error> {
 }
 
 pub fn stdout_isatty() -> bool {
-    atty::is(atty::Stream::Stdout)
+    io::stdout().is_terminal()
 }
 
 pub fn stderr_isatty() -> bool {
-    atty::is(atty::Stream::Stderr)
+    io::stderr().is_terminal()
 }
 
 #[derive(Debug)]
index ba06f61299f37d22a18d86fd291b21757bc60e3a..dff088b9bdfa66140867a8cc88f7e400a6c29961 100644 (file)
@@ -830,5 +830,5 @@ pub(super) fn should_generate_set_arg(field: &Field) -> bool {
 }
 
 pub(super) fn is_doc_comment(attr: &Attribute) -> bool {
-    attr.path.segments.last().unwrap().ident.to_string() == "doc"
+    attr.path.segments.last().unwrap().ident == "doc"
 }
index 5f6e498dbeaa23bb0c8811f4be9d9605955c5edd..fc1167c105ae89c57faad7e5639fb4b738ab3a3e 100644 (file)
@@ -4,7 +4,6 @@ version = "0.0.0"
 edition = "2021"
 
 [lib]
-doctest = false
 
 [dependencies]
 bitflags = "1.2.1"
index 680240703465f284726de2a262bd18880b46710c..f8a69f3c7d53f7b6a11de06c47f625eb3120ee70 100644 (file)
@@ -11,6 +11,8 @@
 use std::ops::Range;
 use std::ptr;
 
+use either::{Left, Right};
+
 use rustc_ast::Mutability;
 use rustc_data_structures::intern::Interned;
 use rustc_span::DUMMY_SP;
@@ -503,11 +505,11 @@ pub fn write_scalar(
         // `to_bits_or_ptr_internal` is the right method because we just want to store this data
         // as-is into memory.
         let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? {
-            Err(val) => {
-                let (provenance, offset) = val.into_parts();
+            Right(ptr) => {
+                let (provenance, offset) = ptr.into_parts();
                 (u128::from(offset.bytes()), Some(provenance))
             }
-            Ok(data) => (data, None),
+            Left(data) => (data, None),
         };
 
         let endian = cx.data_layout().endian;
index ae0dbad8b08d737c0de6467fdb6994a1e37f1c05..bd9cd53e11578b2442d0a981d1c3b6dd7fe1a8a2 100644 (file)
@@ -144,7 +144,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             AlreadyReported(ErrorGuaranteed { .. }) => {
                 write!(
                     f,
-                    "an error has already been reported elsewhere (this sould not usually be printed)"
+                    "an error has already been reported elsewhere (this should not usually be printed)"
                 )
             }
             Layout(ref err) => write!(f, "{err}"),
index ac5fddb7ad1eb9f2ffe29c4d7c869e8e3e8418e8..770c3ed05e8d2650557c62735f054a870aa7f432 100644 (file)
@@ -1,6 +1,8 @@
 use std::convert::{TryFrom, TryInto};
 use std::fmt;
 
+use either::{Either, Left, Right};
+
 use rustc_apfloat::{
     ieee::{Double, Single},
     Float,
@@ -293,10 +295,10 @@ pub fn from_f64(f: Double) -> Self {
     pub fn to_bits_or_ptr_internal(
         self,
         target_size: Size,
-    ) -> Result<Result<u128, Pointer<Prov>>, ScalarSizeMismatch> {
+    ) -> Result<Either<u128, Pointer<Prov>>, ScalarSizeMismatch> {
         assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST");
         Ok(match self {
-            Scalar::Int(int) => Ok(int.to_bits(target_size).map_err(|size| {
+            Scalar::Int(int) => Left(int.to_bits(target_size).map_err(|size| {
                 ScalarSizeMismatch { target_size: target_size.bytes(), data_size: size.bytes() }
             })?),
             Scalar::Ptr(ptr, sz) => {
@@ -306,7 +308,7 @@ pub fn to_bits_or_ptr_internal(
                         data_size: sz.into(),
                     });
                 }
-                Err(ptr)
+                Right(ptr)
             }
         })
     }
@@ -318,8 +320,8 @@ pub fn to_pointer(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, Pointer<O
             .to_bits_or_ptr_internal(cx.pointer_size())
             .map_err(|s| err_ub!(ScalarSizeMismatch(s)))?
         {
-            Err(ptr) => Ok(ptr.into()),
-            Ok(bits) => {
+            Right(ptr) => Ok(ptr.into()),
+            Left(bits) => {
                 let addr = u64::try_from(bits).unwrap();
                 Ok(Pointer::from_addr(addr))
             }
index 1564cf414bd251bda3ccd4f26b815986b8aa8141..027720134370016af69dab5d4d5acfd156bd6246 100644 (file)
     /// a generic type parameter will panic if you call this method on it:
     ///
     /// ```
+    /// use std::fmt::Debug;
+    ///
     /// pub trait Foo<T: Debug> {}
     /// ```
     ///
index 05382bd887cd9e2bb92b4c706109b21953e43e9c..1890c0e24bb4419c1ec17750293b75764b4a0167 100644 (file)
@@ -924,10 +924,13 @@ pub fn error_msg(&self) -> Cow<'static, str> {
             }
             ObjectSafetyViolation::Method(
                 name,
-                MethodViolationCode::ReferencesImplTraitInTrait,
+                MethodViolationCode::ReferencesImplTraitInTrait(_),
                 _,
             ) => format!("method `{}` references an `impl Trait` type in its return type", name)
                 .into(),
+            ObjectSafetyViolation::Method(name, MethodViolationCode::AsyncFn, _) => {
+                format!("method `{}` is `async`", name).into()
+            }
             ObjectSafetyViolation::Method(
                 name,
                 MethodViolationCode::WhereClauseReferencesSelf,
@@ -1035,7 +1038,10 @@ pub enum MethodViolationCode {
     ReferencesSelfOutput,
 
     /// e.g., `fn foo(&self) -> impl Sized`
-    ReferencesImplTraitInTrait,
+    ReferencesImplTraitInTrait(Span),
+
+    /// e.g., `async fn foo(&self)`
+    AsyncFn,
 
     /// e.g., `fn foo(&self) where Self: Clone`
     WhereClauseReferencesSelf,
index dc13374f992eb7589f6eb919b50024314ab5d1ba..d6044ceb0cafc4088a4913c2e5515754c911f8de 100644 (file)
 use rustc_target::spec::abi;
 
 use std::borrow::Cow;
+use std::collections::hash_map::DefaultHasher;
 use std::fmt;
+use std::hash::{Hash, Hasher};
+use std::path::PathBuf;
+
+use super::print::PrettyPrinter;
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable, Lift)]
 pub struct ExpectedFound<T> {
@@ -985,6 +990,38 @@ fn constrain_associated_type_structured_suggestion(
         false
     }
 
+    pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) {
+        let length_limit = 50;
+        let type_limit = 4;
+        let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS)
+            .pretty_print_type(ty)
+            .expect("could not write to `String`")
+            .into_buffer();
+        if regular.len() <= length_limit {
+            return (regular, None);
+        }
+        let short = FmtPrinter::new_with_limit(
+            self,
+            hir::def::Namespace::TypeNS,
+            rustc_session::Limit(type_limit),
+        )
+        .pretty_print_type(ty)
+        .expect("could not write to `String`")
+        .into_buffer();
+        if regular == short {
+            return (regular, None);
+        }
+        // Multiple types might be shortened in a single error, ensure we create a file for each.
+        let mut s = DefaultHasher::new();
+        ty.hash(&mut s);
+        let hash = s.finish();
+        let path = self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None);
+        match std::fs::write(&path, &regular) {
+            Ok(_) => (short, Some(path)),
+            Err(_) => (regular, None),
+        }
+    }
+
     fn format_generic_args(self, args: &[ty::GenericArg<'tcx>]) -> String {
         FmtPrinter::new(self, hir::def::Namespace::TypeNS)
             .path_generic_args(Ok, args)
index 279a728ea392257d6ed8afb639122c211079dafe..786eced61d6e93fe9ac6c0e85242bfbc4157fb72 100644 (file)
@@ -5,7 +5,7 @@
 //!
 //! # Example
 //! ```rust
-//! enum Void {}
+//! #![feature(never_type)]
 //! mod a {
 //!     pub mod b {
 //!         pub struct SecretlyUninhabited {
@@ -15,6 +15,7 @@
 //! }
 //!
 //! mod c {
+//!     enum Void {}
 //!     pub struct AlsoSecretlyUninhabited {
 //!         _priv: Void,
 //!     }
@@ -35,7 +36,7 @@
 //! `Foo`.
 //!
 //! # Example
-//! ```rust
+//! ```ignore(illustrative)
 //! let foo_result: Result<T, Foo> = ... ;
 //! let Ok(t) = foo_result;
 //! ```
index ae0f158ede99a17e1ed5f6362b98f8c41898e3d8..a792d2694b3b9f08e70a4c3d3eb7ba72b4c0f8b1 100644 (file)
@@ -276,28 +276,45 @@ pub fn has_polymorphic_mir_body(&self) -> bool {
     }
 }
 
-impl<'tcx> fmt::Display for Instance<'tcx> {
+fn fmt_instance(
+    f: &mut fmt::Formatter<'_>,
+    instance: &Instance<'_>,
+    type_length: rustc_session::Limit,
+) -> fmt::Result {
+    ty::tls::with(|tcx| {
+        let substs = tcx.lift(instance.substs).expect("could not lift for printing");
+
+        let s = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length)
+            .print_def_path(instance.def_id(), substs)?
+            .into_buffer();
+        f.write_str(&s)
+    })?;
+
+    match instance.def {
+        InstanceDef::Item(_) => Ok(()),
+        InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
+        InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
+        InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
+        InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
+        InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
+        InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
+        InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
+        InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
+        InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
+    }
+}
+
+pub struct ShortInstance<'a, 'tcx>(pub &'a Instance<'tcx>, pub usize);
+
+impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            let substs = tcx.lift(self.substs).expect("could not lift for printing");
-            let s = FmtPrinter::new(tcx, Namespace::ValueNS)
-                .print_def_path(self.def_id(), substs)?
-                .into_buffer();
-            f.write_str(&s)
-        })?;
+        fmt_instance(f, self.0, rustc_session::Limit(self.1))
+    }
+}
 
-        match self.def {
-            InstanceDef::Item(_) => Ok(()),
-            InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
-            InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
-            InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
-            InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
-            InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
-            InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
-            InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
-            InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
-            InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
-        }
+impl<'tcx> fmt::Display for Instance<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        ty::tls::with(|tcx| fmt_instance(f, self, tcx.type_length_limit()))
     }
 }
 
index f9a762261e2cea1f20765e41ee8654b492309e1d..a770c6a2e99bee226bab8368096db8c66e174b4f 100644 (file)
@@ -84,7 +84,7 @@
     GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType,
     UserTypeAnnotationIndex,
 };
-pub use self::instance::{Instance, InstanceDef};
+pub use self::instance::{Instance, InstanceDef, ShortInstance};
 pub use self::list::List;
 pub use self::parameterized::ParameterizedOverTcx;
 pub use self::rvalue_scopes::RvalueScopes;
index 48e803597b02e1aaa9666d709128abc301debf78..023c9d26c42e303700d09d182e80a25c7fb5b5ad 100644 (file)
@@ -13,6 +13,7 @@
 use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
 use rustc_session::config::TrimmedDefPaths;
 use rustc_session::cstore::{ExternCrate, ExternCrateSource};
+use rustc_session::Limit;
 use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_target::abi::Size;
 use rustc_target::spec::abi::Abi;
@@ -1583,6 +1584,8 @@ pub struct FmtPrinterData<'a, 'tcx> {
     region_index: usize,
     binder_depth: usize,
     printed_type_count: usize,
+    type_length_limit: Limit,
+    truncated: bool,
 
     pub region_highlight_mode: RegionHighlightMode<'tcx>,
 
@@ -1605,6 +1608,10 @@ fn deref_mut(&mut self) -> &mut Self::Target {
 
 impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
     pub fn new(tcx: TyCtxt<'tcx>, ns: Namespace) -> Self {
+        Self::new_with_limit(tcx, ns, tcx.type_length_limit())
+    }
+
+    pub fn new_with_limit(tcx: TyCtxt<'tcx>, ns: Namespace, type_length_limit: Limit) -> Self {
         FmtPrinter(Box::new(FmtPrinterData {
             tcx,
             // Estimated reasonable capacity to allocate upfront based on a few
@@ -1617,6 +1624,8 @@ pub fn new(tcx: TyCtxt<'tcx>, ns: Namespace) -> Self {
             region_index: 0,
             binder_depth: 0,
             printed_type_count: 0,
+            type_length_limit,
+            truncated: false,
             region_highlight_mode: RegionHighlightMode::new(tcx),
             ty_infer_name_resolver: None,
             const_infer_name_resolver: None,
@@ -1751,11 +1760,11 @@ fn print_region(self, region: ty::Region<'tcx>) -> Result<Self::Region, Self::Er
     }
 
     fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
-        let type_length_limit = self.tcx.type_length_limit();
-        if type_length_limit.value_within_limit(self.printed_type_count) {
+        if self.type_length_limit.value_within_limit(self.printed_type_count) {
             self.printed_type_count += 1;
             self.pretty_print_type(ty)
         } else {
+            self.truncated = true;
             write!(self, "...")?;
             Ok(self)
         }
@@ -2194,11 +2203,9 @@ fn name_by_region_index(
 
         define_scoped_cx!(self);
 
-        let possible_names =
-            ('a'..='z').rev().map(|s| Symbol::intern(&format!("'{s}"))).collect::<Vec<_>>();
+        let possible_names = ('a'..='z').rev().map(|s| Symbol::intern(&format!("'{s}")));
 
         let mut available_names = possible_names
-            .into_iter()
             .filter(|name| !self.used_region_names.contains(&name))
             .collect::<Vec<_>>();
         debug!(?available_names);
index c726fa3a33fff2d397251703813e79b7bc2881ca..2baa3bfcb6401f3570ee79012cab627d0a6b11f9 100644 (file)
@@ -8,6 +8,7 @@ edition = "2021"
 [dependencies]
 rustc_arena = { path = "../rustc_arena" }
 tracing = "0.1"
+either = "1"
 rustc_middle = { path = "../rustc_middle" }
 rustc_apfloat = { path = "../rustc_apfloat" }
 rustc_attr = { path = "../rustc_attr" }
index b597ecfaa4d6d28b66ca9d844fffa7daea1023cf..af0d7879c576ac266741d0d58a2ac1ddd43b1af8 100644 (file)
@@ -240,6 +240,39 @@ pub(super) fn perform_test(
             }
 
             TestKind::Eq { value, ty } => {
+                let tcx = self.tcx;
+                if let ty::Adt(def, _) = ty.kind() && Some(def.did()) == tcx.lang_items().string() {
+                    if !tcx.features().string_deref_patterns {
+                        bug!("matching on `String` went through without enabling string_deref_patterns");
+                    }
+                    let re_erased = tcx.lifetimes.re_erased;
+                    let ref_string = self.temp(tcx.mk_imm_ref(re_erased, ty), test.span);
+                    let ref_str_ty = tcx.mk_imm_ref(re_erased, tcx.types.str_);
+                    let ref_str = self.temp(ref_str_ty, test.span);
+                    let deref = tcx.require_lang_item(LangItem::Deref, None);
+                    let method = trait_method(tcx, deref, sym::deref, ty, &[]);
+                    let eq_block = self.cfg.start_new_block();
+                    self.cfg.push_assign(block, source_info, ref_string, Rvalue::Ref(re_erased, BorrowKind::Shared, place));
+                    self.cfg.terminate(
+                        block,
+                        source_info,
+                        TerminatorKind::Call {
+                            func: Operand::Constant(Box::new(Constant {
+                                span: test.span,
+                                user_ty: None,
+                                literal: method,
+                            })),
+                            args: vec![Operand::Move(ref_string)],
+                            destination: ref_str,
+                            target: Some(eq_block),
+                            cleanup: None,
+                            from_hir_call: false,
+                            fn_span: source_info.span
+                        }
+                    );
+                    self.non_scalar_compare(eq_block, make_target_blocks, source_info, value, ref_str, ref_str_ty);
+                    return;
+                }
                 if !ty.is_scalar() {
                     // Use `PartialEq::eq` instead of `BinOp::Eq`
                     // (the binop can only handle primitives)
index 595abc8f66870d5e6d7be56c88df9dfc0dc2f828..d60e8722cb61d5c443e20ef22d8c061d100781e0 100644 (file)
 //! wildcards, see [`SplitWildcard`]; for integer ranges, see [`SplitIntRange`]; for slices, see
 //! [`SplitVarLenSlice`].
 
-use self::Constructor::*;
-use self::SliceKind::*;
+use std::cell::Cell;
+use std::cmp::{self, max, min, Ordering};
+use std::fmt;
+use std::iter::{once, IntoIterator};
+use std::ops::RangeInclusive;
 
-use super::compare_const_vals;
-use super::usefulness::{MatchCheckCtxt, PatCtxt};
+use smallvec::{smallvec, SmallVec};
 
 use rustc_data_structures::captures::Captures;
-use rustc_index::vec::Idx;
-
 use rustc_hir::{HirId, RangeEnd};
+use rustc_index::vec::Idx;
 use rustc_middle::mir::{self, Field};
 use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange};
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{Integer, Size, VariantIdx};
 
-use smallvec::{smallvec, SmallVec};
-use std::cell::Cell;
-use std::cmp::{self, max, min, Ordering};
-use std::fmt;
-use std::iter::{once, IntoIterator};
-use std::ops::RangeInclusive;
+use self::Constructor::*;
+use self::SliceKind::*;
+
+use super::compare_const_vals;
+use super::usefulness::{MatchCheckCtxt, PatCtxt};
 
 /// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
 fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> {
@@ -147,11 +147,7 @@ fn from_constant<'tcx>(
                         // straight to the result, after doing a bit of checking. (We
                         // could remove this branch and just fall through, which
                         // is more general but much slower.)
-                        if let Ok(Ok(bits)) = scalar.to_bits_or_ptr_internal(target_size) {
-                            return Some(bits);
-                        } else {
-                            return None;
-                        }
+                        return scalar.to_bits_or_ptr_internal(target_size).unwrap().left();
                     }
                     mir::ConstantKind::Ty(c) => match c.kind() {
                         ty::ConstKind::Value(_) => bug!(
index db4b0a3deda9dba74aea18e8e184eac255f55b70..cc69a1bb02db19cac318ec2c149bd18d7dcfc9bf 100644 (file)
@@ -899,7 +899,7 @@ fn debug_with_context_rec<V: Debug + Eq>(
         let info_elem = map.places[child].proj_elem.unwrap();
         let child_place_str = match info_elem {
             TrackElem::Field(field) => {
-                if place_str.starts_with("*") {
+                if place_str.starts_with('*') {
                     format!("({}).{}", place_str, field.index())
                 } else {
                     format!("{}.{}", place_str, field.index())
index 53545cff0cb34f398f7e6bf27af8e0e1e57fbd0d..962536669e0db41301c4eb337f91d1896204c65a 100644 (file)
@@ -9,6 +9,7 @@ edition = "2021"
 itertools = "0.10.1"
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
+either = "1"
 rustc_ast = { path = "../rustc_ast" }
 rustc_attr = { path = "../rustc_attr" }
 rustc_data_structures = { path = "../rustc_data_structures" }
index 3f5890040c394112e9afab059c7d3db0990f4493..b0514e033566c9a65ebe8f5484a41d74ddb39898 100644 (file)
@@ -3,6 +3,8 @@
 
 use std::cell::Cell;
 
+use either::Right;
+
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::DefKind;
@@ -429,7 +431,7 @@ fn get_const(&self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
         // Try to read the local as an immediate so that if it is representable as a scalar, we can
         // handle it as such, but otherwise, just return the value as is.
         Some(match self.ecx.read_immediate_raw(&op) {
-            Ok(Ok(imm)) => imm.into(),
+            Ok(Right(imm)) => imm.into(),
             _ => op,
         })
     }
@@ -743,7 +745,7 @@ fn replace_with_const(
         // FIXME> figure out what to do when read_immediate_raw fails
         let imm = self.use_ecx(|this| this.ecx.read_immediate_raw(value));
 
-        if let Some(Ok(imm)) = imm {
+        if let Some(Right(imm)) = imm {
             match *imm {
                 interpret::Immediate::Scalar(scalar) => {
                     *rval = Rvalue::Use(self.operand_from_scalar(
index 786063d538c0a7c923af72d273518b4af13eaffb..0ab67228f3f400fae076b6a06e5898320b7f1856 100644 (file)
@@ -1,10 +1,10 @@
 //! Propagates constants for early reporting of statically known
 //! assertion failures
 
-use crate::const_prop::CanConstProp;
-use crate::const_prop::ConstPropMachine;
-use crate::const_prop::ConstPropMode;
-use crate::MirLint;
+use std::cell::Cell;
+
+use either::{Left, Right};
+
 use rustc_const_eval::interpret::Immediate;
 use rustc_const_eval::interpret::{
     self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar, StackPopCleanup,
 use rustc_span::Span;
 use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
 use rustc_trait_selection::traits;
-use std::cell::Cell;
+
+use crate::const_prop::CanConstProp;
+use crate::const_prop::ConstPropMachine;
+use crate::const_prop::ConstPropMode;
+use crate::MirLint;
 
 /// The maximum number of bytes that we'll allocate space for a local or the return value.
 /// Needed for #66397, because otherwise we eval into large places and that can cause OOM or just
 /// Severely regress performance.
 const MAX_ALLOC_LIMIT: u64 = 1024;
+
 pub struct ConstProp;
 
 impl<'tcx> MirLint<'tcx> for ConstProp {
@@ -243,7 +248,7 @@ fn get_const(&self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
         // Try to read the local as an immediate so that if it is representable as a scalar, we can
         // handle it as such, but otherwise, just return the value as is.
         Some(match self.ecx.read_immediate_raw(&op) {
-            Ok(Ok(imm)) => imm.into(),
+            Ok(Left(imm)) => imm.into(),
             _ => op,
         })
     }
@@ -266,7 +271,7 @@ fn use_ecx<F, T>(&mut self, source_info: SourceInfo, f: F) -> Option<T>
         F: FnOnce(&mut Self) -> InterpResult<'tcx, T>,
     {
         // Overwrite the PC -- whatever the interpreter does to it does not make any sense anyway.
-        self.ecx.frame_mut().loc = Err(source_info.span);
+        self.ecx.frame_mut().loc = Right(source_info.span);
         match f(self) {
             Ok(val) => Some(val),
             Err(error) => {
index 780b91d9215d5e2c08c68d32c9a081efff1a66b6..d7dd5fc8528454ca76c0a78ce2f1decdbedb437f 100644 (file)
@@ -1,7 +1,6 @@
 //! Inlining pass for MIR functions
 use crate::deref_separator::deref_finder;
 use rustc_attr::InlineAttr;
-use rustc_const_eval::transform::validate::equal_up_to_regions;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::Idx;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
@@ -14,7 +13,8 @@
 use rustc_target::abi::VariantIdx;
 use rustc_target::spec::abi::Abi;
 
-use super::simplify::{remove_dead_blocks, CfgSimplifier};
+use crate::simplify::{remove_dead_blocks, CfgSimplifier};
+use crate::util;
 use crate::MirPass;
 use std::iter;
 use std::ops::{Range, RangeFrom};
@@ -180,7 +180,7 @@ fn try_inlining(
         let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() };
         let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty;
         let output_type = callee_body.return_ty();
-        if !equal_up_to_regions(self.tcx, self.param_env, output_type, destination_ty) {
+        if !util::is_subtype(self.tcx, self.param_env, output_type, destination_ty) {
             trace!(?output_type, ?destination_ty);
             return Err("failed to normalize return type");
         }
@@ -200,7 +200,7 @@ fn try_inlining(
                 arg_tuple_tys.iter().zip(callee_body.args_iter().skip(skipped_args))
             {
                 let input_type = callee_body.local_decls[input].ty;
-                if !equal_up_to_regions(self.tcx, self.param_env, arg_ty, input_type) {
+                if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) {
                     trace!(?arg_ty, ?input_type);
                     return Err("failed to normalize tuple argument type");
                 }
@@ -209,7 +209,7 @@ fn try_inlining(
             for (arg, input) in args.iter().zip(callee_body.args_iter()) {
                 let input_type = callee_body.local_decls[input].ty;
                 let arg_ty = arg.ty(&caller_body.local_decls, self.tcx);
-                if !equal_up_to_regions(self.tcx, self.param_env, arg_ty, input_type) {
+                if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) {
                     trace!(?arg_ty, ?input_type);
                     return Err("failed to normalize argument type");
                 }
@@ -847,7 +847,7 @@ fn visit_projection_elem(
             let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
             let parent_ty = parent.ty(&self.callee_body.local_decls, self.tcx);
             let check_equal = |this: &mut Self, f_ty| {
-                if !equal_up_to_regions(this.tcx, this.param_env, ty, f_ty) {
+                if !util::is_equal_up_to_subtyping(this.tcx, this.param_env, ty, f_ty) {
                     trace!(?ty, ?f_ty);
                     this.validation = Err("failed to normalize projection type");
                     return;
index cdf8011d4f5ab778dd9977c5cbba75ab95bb746c..d74893bf0f0e3354bc5b04daacb86d7cb252461c 100644 (file)
 use rustc_session::Limit;
 use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP};
 use rustc_target::abi::Size;
-use std::iter;
 use std::ops::Range;
 use std::path::PathBuf;
 
@@ -541,29 +540,23 @@ fn collect_items_rec<'tcx>(
 }
 
 /// Format instance name that is already known to be too long for rustc.
-/// Show only the first and last 32 characters to avoid blasting
+/// Show only the first 2 types if it is longer than 32 characters to avoid blasting
 /// the user's terminal with thousands of lines of type-name.
 ///
 /// If the type name is longer than before+after, it will be written to a file.
 fn shrunk_instance_name<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: &Instance<'tcx>,
-    before: usize,
-    after: usize,
 ) -> (String, Option<PathBuf>) {
     let s = instance.to_string();
 
     // Only use the shrunk version if it's really shorter.
     // This also avoids the case where before and after slices overlap.
-    if s.chars().nth(before + after + 1).is_some() {
-        // An iterator of all byte positions including the end of the string.
-        let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
-
-        let shrunk = format!(
-            "{before}...{after}",
-            before = &s[..positions().nth(before).unwrap_or(s.len())],
-            after = &s[positions().rev().nth(after).unwrap_or(0)..],
-        );
+    if s.chars().nth(33).is_some() {
+        let shrunk = format!("{}", ty::ShortInstance(instance, 4));
+        if shrunk == s {
+            return (s, None);
+        }
 
         let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None);
         let written_to_path = std::fs::write(&path, s).ok().map(|_| path);
@@ -599,7 +592,7 @@ fn check_recursion_limit<'tcx>(
     if !recursion_limit.value_within_limit(adjusted_recursion_depth) {
         let def_span = tcx.def_span(def_id);
         let def_path_str = tcx.def_path_str(def_id);
-        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
+        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
         let mut path = PathBuf::new();
         let was_written = if written_to_path.is_some() {
             path = written_to_path.unwrap();
@@ -641,7 +634,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
     //
     // Bail out in these cases to avoid that bad user experience.
     if !tcx.type_length_limit().value_within_limit(type_length) {
-        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
+        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
         let span = tcx.def_span(instance.def_id());
         let mut path = PathBuf::new();
         let was_written = if written_to_path.is_some() {
index a5c94e164033477db935fa1cf08f6105facde717..dbcfb390333100ae34ce0be134cd5f5d27584e02 100644 (file)
@@ -7,15 +7,16 @@ edition = "2021"
 
 [dependencies]
 bitflags = "1.0"
-tracing = "0.1"
+rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
 rustc_feature = { path = "../rustc_feature" }
 rustc_lexer = { path = "../rustc_lexer" }
 rustc_macros = { path = "../rustc_macros" }
-rustc_errors = { path = "../rustc_errors" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-rustc_ast = { path = "../rustc_ast" }
+thin-vec = "0.2.8"
+tracing = "0.1"
 unicode-normalization = "0.1.11"
 unicode-width = "0.1.4"
index 724d92254a4554dd2a888b2effb91b31e92f80de..211450250fdf44a1fc7f8f9d86cf7bc83bd5da04 100644 (file)
@@ -1219,3 +1219,11 @@ pub(crate) struct FnPtrWithGenericsSugg {
     pub arity: usize,
     pub for_param_list_exists: bool,
 }
+
+#[derive(Diagnostic)]
+#[diag(parser_unexpected_if_with_if)]
+pub(crate) struct UnexpectedIfWithIf(
+    #[primary_span]
+    #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
+    pub Span,
+);
index 0bbe073fe2af4621c19f95e570bdd13367249e82..2558ac801addd18c6a3a492db233d7245292787f 100644 (file)
@@ -18,6 +18,7 @@
 };
 
 use crate::lexer::UnmatchedBrace;
+use crate::parser;
 use rustc_ast as ast;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
-use std::ops::{Deref, DerefMut};
-
 use std::mem::take;
-
-use crate::parser;
+use std::ops::{Deref, DerefMut};
+use thin_vec::{thin_vec, ThinVec};
+use tracing::{debug, trace};
 
 /// Creates a placeholder argument.
 pub(super) fn dummy_arg(ident: Ident) -> Param {
@@ -65,7 +65,7 @@ pub(super) fn dummy_arg(ident: Ident) -> Param {
 pub(super) trait RecoverQPath: Sized + 'static {
     const PATH_STYLE: PathStyle = PathStyle::Expr;
     fn to_ty(&self) -> Option<P<Ty>>;
-    fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self;
+    fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self;
 }
 
 impl RecoverQPath for Ty {
@@ -73,7 +73,7 @@ impl RecoverQPath for Ty {
     fn to_ty(&self) -> Option<P<Ty>> {
         Some(P(self.clone()))
     }
-    fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
+    fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
         Self {
             span: path.span,
             kind: TyKind::Path(qself, path),
@@ -87,7 +87,7 @@ impl RecoverQPath for Pat {
     fn to_ty(&self) -> Option<P<Ty>> {
         self.to_ty()
     }
-    fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
+    fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
         Self {
             span: path.span,
             kind: PatKind::Path(qself, path),
@@ -101,7 +101,7 @@ impl RecoverQPath for Expr {
     fn to_ty(&self) -> Option<P<Ty>> {
         self.to_ty()
     }
-    fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
+    fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
         Self {
             span: path.span,
             kind: ExprKind::Path(qself, path),
@@ -638,8 +638,11 @@ pub fn maybe_suggest_struct_literal(
             //     field: value,
             // }
             let mut snapshot = self.create_snapshot_for_diagnostic();
-            let path =
-                Path { segments: vec![], span: self.prev_token.span.shrink_to_lo(), tokens: None };
+            let path = Path {
+                segments: ThinVec::new(),
+                span: self.prev_token.span.shrink_to_lo(),
+                tokens: None,
+            };
             let struct_expr = snapshot.parse_struct_expr(None, path, false);
             let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No);
             return Some(match (struct_expr, block_tail) {
@@ -1426,7 +1429,7 @@ pub(super) fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
     ) -> PResult<'a, P<T>> {
         self.expect(&token::ModSep)?;
 
-        let mut path = ast::Path { segments: Vec::new(), span: DUMMY_SP, tokens: None };
+        let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None };
         self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?;
         path.span = ty_span.to(self.prev_token.span);
 
@@ -1437,7 +1440,7 @@ pub(super) fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
         });
 
         let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`.
-        Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path)))
+        Ok(P(T::recovered(Some(P(QSelf { ty, path_span, position: 0 })), path)))
     }
 
     pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
@@ -1657,14 +1660,14 @@ pub(super) fn recover_parens_around_for_head(
                 let left = begin_par_sp;
                 let right = self.prev_token.span;
                 let left_snippet = if let Ok(snip) = sm.span_to_prev_source(left) &&
-                        !snip.ends_with(" ") {
+                        !snip.ends_with(' ') {
                                 " ".to_string()
                             } else {
                                 "".to_string()
                             };
 
                 let right_snippet = if let Ok(snip) = sm.span_to_next_source(right) &&
-                        !snip.starts_with(" ") {
+                        !snip.starts_with(' ') {
                                 " ".to_string()
                             } else {
                                 "".to_string()
@@ -2434,7 +2437,7 @@ pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
                                             None,
                                             Path {
                                                 span: new_span,
-                                                segments: vec![
+                                                segments: thin_vec![
                                                     PathSegment::from_ident(*old_ident),
                                                     PathSegment::from_ident(*ident),
                                                 ],
index c9629ea49e0bf7247e7caaf84cf7457bec65d1d3..fe7401786a0291ebf8e20dc56d3dddca76c816d3 100644 (file)
@@ -21,8 +21,8 @@
     NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub,
     OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
     RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere,
-    StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedTokenAfterLabel,
-    UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
+    StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedIfWithIf,
+    UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
 };
 use crate::maybe_recover_from_interpolated_ty_qpath;
 use core::mem;
@@ -840,7 +840,7 @@ fn parse_and_disallow_postfix_after_cast(
                     ExprKind::Index(_, _) => "indexing",
                     ExprKind::Try(_) => "`?`",
                     ExprKind::Field(_, _) => "a field access",
-                    ExprKind::MethodCall(_, _, _, _) => "a method call",
+                    ExprKind::MethodCall(_) => "a method call",
                     ExprKind::Call(_, _) => "a function call",
                     ExprKind::Await(_) => "`.await`",
                     ExprKind::Err => return Ok(with_postfix),
@@ -1262,24 +1262,32 @@ fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Exp
         }
 
         let fn_span_lo = self.token.span;
-        let mut segment = self.parse_path_segment(PathStyle::Expr, None)?;
-        self.check_trailing_angle_brackets(&segment, &[&token::OpenDelim(Delimiter::Parenthesis)]);
-        self.check_turbofish_missing_angle_brackets(&mut segment);
+        let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
+        self.check_trailing_angle_brackets(&seg, &[&token::OpenDelim(Delimiter::Parenthesis)]);
+        self.check_turbofish_missing_angle_brackets(&mut seg);
 
         if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
             // Method call `expr.f()`
             let args = self.parse_paren_expr_seq()?;
             let fn_span = fn_span_lo.to(self.prev_token.span);
             let span = lo.to(self.prev_token.span);
-            Ok(self.mk_expr(span, ExprKind::MethodCall(segment, self_arg, args, fn_span)))
+            Ok(self.mk_expr(
+                span,
+                ExprKind::MethodCall(Box::new(ast::MethodCall {
+                    seg,
+                    receiver: self_arg,
+                    args,
+                    span: fn_span,
+                })),
+            ))
         } else {
             // Field access `expr.f`
-            if let Some(args) = segment.args {
+            if let Some(args) = seg.args {
                 self.sess.emit_err(FieldExpressionWithGeneric(args.span()));
             }
 
             let span = lo.to(self.prev_token.span);
-            Ok(self.mk_expr(span, ExprKind::Field(self_arg, segment.ident)))
+            Ok(self.mk_expr(span, ExprKind::Field(self_arg, seg.ident)))
         }
     }
 
@@ -1498,7 +1506,7 @@ fn parse_path_start_expr(&mut self) -> PResult<'a, P<Expr>> {
             });
             (lo.to(self.prev_token.span), ExprKind::MacCall(mac))
         } else if self.check(&token::OpenDelim(Delimiter::Brace)) &&
-            let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path) {
+            let Some(expr) = self.maybe_parse_struct_expr(&qself, &path) {
                 if qself.is_some() {
                     self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
                 }
@@ -2049,9 +2057,9 @@ fn parse_closure_expr(&mut self) -> PResult<'a, P<Expr>> {
         };
 
         let capture_clause = self.parse_capture_clause()?;
-        let decl = self.parse_fn_block_decl()?;
+        let fn_decl = self.parse_fn_block_decl()?;
         let decl_hi = self.prev_token.span;
-        let mut body = match decl.output {
+        let mut body = match fn_decl.output {
             FnRetTy::Default(_) => {
                 let restrictions = self.restrictions - Restrictions::STMT_EXPR;
                 self.parse_expr_res(restrictions, None)?
@@ -2070,12 +2078,7 @@ fn parse_closure_expr(&mut self) -> PResult<'a, P<Expr>> {
 
         if self.token.kind == TokenKind::Semi
             && matches!(self.token_cursor.frame.delim_sp, Some((Delimiter::Parenthesis, _)))
-            // HACK: This is needed so we can detect whether we're inside a macro,
-            // where regular assumptions about what tokens can follow other tokens
-            // don't necessarily apply.
             && self.may_recover()
-            // FIXME(Nilstrieb): Remove this check once `may_recover` actually stops recovery
-            && self.subparser_name.is_none()
         {
             // It is likely that the closure body is a block but where the
             // braces have been removed. We will recover and eat the next
@@ -2087,15 +2090,15 @@ fn parse_closure_expr(&mut self) -> PResult<'a, P<Expr>> {
 
         let closure = self.mk_expr(
             lo.to(body.span),
-            ExprKind::Closure(
+            ExprKind::Closure(Box::new(ast::Closure {
                 binder,
                 capture_clause,
                 asyncness,
                 movability,
-                decl,
+                fn_decl,
                 body,
-                lo.to(decl_hi),
-            ),
+                fn_decl_span: lo.to(decl_hi),
+            })),
         );
 
         // Disable recovery for closure body
@@ -2231,6 +2234,7 @@ fn parse_if_after_cond(&mut self, lo: Span, mut cond: P<Expr>) -> PResult<'a, P<
                 if let Some(block) = recover_block_from_condition(self) {
                     block
                 } else {
+                    self.error_on_extra_if(&cond)?;
                     // Parse block, which will always fail, but we can add a nice note to the error
                     self.parse_block().map_err(|mut err| {
                         err.span_note(
@@ -2367,6 +2371,16 @@ fn error_on_if_block_attrs(
         });
     }
 
+    fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> {
+        if let ExprKind::Binary(Spanned { span: binop_span, node: binop}, _, right) = &cond.kind &&
+            let BinOpKind::And = binop &&
+            let ExprKind::If(cond, ..) = &right.kind {
+                    Err(self.sess.create_err(UnexpectedIfWithIf(binop_span.shrink_to_hi().to(cond.span.shrink_to_lo()))))
+            } else {
+                Ok(())
+            }
+    }
+
     /// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
     fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
         // Record whether we are about to parse `for (`.
@@ -2800,7 +2814,7 @@ fn is_certainly_not_a_block(&self) -> bool {
 
     fn maybe_parse_struct_expr(
         &mut self,
-        qself: Option<&ast::QSelf>,
+        qself: &Option<P<ast::QSelf>>,
         path: &ast::Path,
     ) -> Option<PResult<'a, P<Expr>>> {
         let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
@@ -2808,7 +2822,7 @@ fn maybe_parse_struct_expr(
             if let Err(err) = self.expect(&token::OpenDelim(Delimiter::Brace)) {
                 return Some(Err(err));
             }
-            let expr = self.parse_struct_expr(qself.cloned(), path.clone(), true);
+            let expr = self.parse_struct_expr(qself.clone(), path.clone(), true);
             if let (Ok(expr), false) = (&expr, struct_allowed) {
                 // This is a struct literal, but we don't can't accept them here.
                 self.sess.emit_err(StructLiteralNotAllowedHere {
@@ -2939,7 +2953,7 @@ pub(super) fn parse_struct_fields(
     /// Precondition: already parsed the '{'.
     pub(super) fn parse_struct_expr(
         &mut self,
-        qself: Option<ast::QSelf>,
+        qself: Option<P<ast::QSelf>>,
         pth: ast::Path,
         recover: bool,
     ) -> PResult<'a, P<Expr>> {
index 494f0cf56a80f6c82f8dc5fe408f5dde81b8c25d..e5f58ca38946334116dcd58fe031ef3c4dddcbfd 100644 (file)
@@ -3,7 +3,6 @@
 use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
 use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
-
 use rustc_ast::ast::*;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, TokenKind};
 use rustc_span::source_map::{self, Span};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::DUMMY_SP;
-
 use std::convert::TryFrom;
 use std::mem;
+use thin_vec::ThinVec;
+use tracing::debug;
 
 impl<'a> Parser<'a> {
     /// Parses a source module as a crate. This is the main entry point for the parser.
@@ -972,7 +972,8 @@ fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemInfo
     fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
         let lo = self.token.span;
 
-        let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo(), tokens: None };
+        let mut prefix =
+            ast::Path { segments: ThinVec::new(), span: lo.shrink_to_lo(), tokens: None };
         let kind = if self.check(&token::OpenDelim(Delimiter::Brace))
             || self.check(&token::BinOp(token::Star))
             || self.is_import_coupler()
index b3af37a5f7029241d538fe34d1a31abdb179b340..0e202645a39b85a5e82a296345e7a23ea785d0fb 100644 (file)
@@ -889,7 +889,7 @@ fn parse_pat_ident(&mut self, binding_annotation: BindingAnnotation) -> PResult<
     }
 
     /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
-    fn parse_pat_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
+    fn parse_pat_struct(&mut self, qself: Option<P<QSelf>>, path: Path) -> PResult<'a, PatKind> {
         if qself.is_some() {
             // Feature gate the use of qualified paths in patterns
             self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
@@ -906,7 +906,11 @@ fn parse_pat_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a,
     }
 
     /// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`).
-    fn parse_pat_tuple_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
+    fn parse_pat_tuple_struct(
+        &mut self,
+        qself: Option<P<QSelf>>,
+        path: Path,
+    ) -> PResult<'a, PatKind> {
         let (fields, _) = self.parse_paren_comma_seq(|p| {
             p.parse_pat_allow_top_alt(
                 None,
index d46565dea893119d48736a56d5ac8190ac79285a..2d432e3f5bd65500b5ab8279efb4bd9298eaef62 100644 (file)
@@ -11,8 +11,9 @@
 use rustc_errors::{pluralize, Applicability, PResult};
 use rustc_span::source_map::{BytePos, Span};
 use rustc_span::symbol::{kw, sym, Ident};
-
 use std::mem;
+use thin_vec::ThinVec;
+use tracing::debug;
 
 /// Specifies how to parse a path.
 #[derive(Copy, Clone, PartialEq)]
@@ -48,7 +49,7 @@ impl<'a> Parser<'a> {
     /// `<T as U>::a`
     /// `<T as U>::F::a<S>` (without disambiguator)
     /// `<T as U>::F::a::<S>` (with disambiguator)
-    pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, Path)> {
+    pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (P<QSelf>, Path)> {
         let lo = self.prev_token.span;
         let ty = self.parse_ty()?;
 
@@ -63,7 +64,7 @@ pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, Pa
             path_span = path_lo.to(self.prev_token.span);
         } else {
             path_span = self.token.span.to(self.token.span);
-            path = ast::Path { segments: Vec::new(), span: path_span, tokens: None };
+            path = ast::Path { segments: ThinVec::new(), span: path_span, tokens: None };
         }
 
         // See doc comment for `unmatched_angle_bracket_count`.
@@ -77,7 +78,7 @@ pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, Pa
             self.expect(&token::ModSep)?;
         }
 
-        let qself = QSelf { ty, path_span, position: path.segments.len() };
+        let qself = P(QSelf { ty, path_span, position: path.segments.len() });
         self.parse_path_segments(&mut path.segments, style, None)?;
 
         Ok((
@@ -179,7 +180,7 @@ pub(super) fn parse_path_inner(
         }
 
         let lo = self.token.span;
-        let mut segments = Vec::new();
+        let mut segments = ThinVec::new();
         let mod_sep_ctxt = self.token.span.ctxt();
         if self.eat(&token::ModSep) {
             segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
@@ -191,7 +192,7 @@ pub(super) fn parse_path_inner(
 
     pub(super) fn parse_path_segments(
         &mut self,
-        segments: &mut Vec<PathSegment>,
+        segments: &mut ThinVec<PathSegment>,
         style: PathStyle,
         ty_generics: Option<&Generics>,
     ) -> PResult<'a, ()> {
index 6b8cd0713732d34f0eb52dce3b2ff0a2ff32fd51..acb9bd8e78a4a57077e348f4e369eabd910f9730 100644 (file)
@@ -353,7 +353,7 @@ fn check_generic_attr(
                 attr.span,
                 OnlyHasEffectOn {
                     attr_name: attr.name_or_empty(),
-                    target_name: allowed_target.name().replace(" ", "_"),
+                    target_name: allowed_target.name().replace(' ', "_"),
                 },
             );
         }
index d4722234a8f1e05e2c1b8e3a3a65620649ca3fdd..5d0224c35f3645a8716d2820e8d8a4f0f49914e9 100644 (file)
@@ -772,7 +772,7 @@ fn warn_multiple_dead_codes(
         self.tcx.emit_spanned_lint(
             lint,
             tcx.hir().local_def_id_to_hir_id(first_id),
-            MultiSpan::from_spans(spans.clone()),
+            MultiSpan::from_spans(spans),
             diag,
         );
     }
index d66db1d7a0dd5de3b532fde233be4b55fe70cead..7c3a0f8f277b5b6480016958e3b3b7a5c24759f0 100644 (file)
@@ -7,10 +7,8 @@ edition = "2021"
 
 [dependencies]
 bitflags = "1.2.1"
-tracing = "0.1"
-rustc_ast = { path = "../rustc_ast" }
 rustc_arena = { path = "../rustc_arena" }
-rustc_middle = { path = "../rustc_middle" }
+rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_attr = { path = "../rustc_attr" }
 rustc_data_structures = { path = "../rustc_data_structures" }
@@ -19,8 +17,12 @@ rustc_expand = { path = "../rustc_expand" }
 rustc_feature = { path = "../rustc_feature" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
+rustc_macros = { path = "../rustc_macros" }
 rustc_metadata = { path = "../rustc_metadata" }
+rustc_middle = { path = "../rustc_middle" }
 rustc_query_system = { path = "../rustc_query_system" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+thin-vec = "0.2.8"
+tracing = "0.1"
index d36e0f61d9161967b94106cb90bd59e63bb7a7ef..b1cee06849dd98f753c1904498bf73bd9190f64a 100644 (file)
@@ -262,11 +262,11 @@ fn visit_anon_const(&mut self, constant: &'a AnonConst) {
     fn visit_expr(&mut self, expr: &'a Expr) {
         let parent_def = match expr.kind {
             ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id),
-            ExprKind::Closure(_, _, asyncness, ..) => {
+            ExprKind::Closure(ref closure) => {
                 // Async closures desugar to closures inside of closures, so
                 // we must create two defs.
                 let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span);
-                match asyncness {
+                match closure.asyncness {
                     Async::Yes { closure_id, .. } => {
                         self.create_def(closure_id, DefPathData::ClosureExpr, expr.span)
                     }
index a12918b2979906021789ef8f5936bc59eb42c02c..bc3a710e84bd046b9213e2086f850d30f47236e8 100644 (file)
@@ -25,7 +25,9 @@
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, Span, SyntaxContext};
+use thin_vec::ThinVec;
 
+use crate::errors as errs;
 use crate::imports::{Import, ImportKind, ImportResolver};
 use crate::late::{PatternSource, Rib};
 use crate::path_names_to_string;
@@ -597,78 +599,41 @@ pub(crate) fn into_struct_error(
 
                 err
             }
-            ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0403,
-                    "the name `{}` is already used for a generic \
-                     parameter in this item's generic parameters",
-                    name,
-                );
-                err.span_label(span, "already used");
-                err.span_label(first_use_span, format!("first use of `{}`", name));
-                err
-            }
+            ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => self
+                .session
+                .create_err(errs::NameAlreadyUsedInParameterList { span, first_use_span, name }),
             ResolutionError::MethodNotMemberOfTrait(method, trait_, candidate) => {
-                let mut err = struct_span_err!(
-                    self.session,
+                self.session.create_err(errs::MethodNotMemberOfTrait {
                     span,
-                    E0407,
-                    "method `{}` is not a member of trait `{}`",
                     method,
-                    trait_
-                );
-                err.span_label(span, format!("not a member of trait `{}`", trait_));
-                if let Some(candidate) = candidate {
-                    err.span_suggestion(
-                        method.span,
-                        "there is an associated function with a similar name",
-                        candidate.to_ident_string(),
-                        Applicability::MaybeIncorrect,
-                    );
-                }
-                err
+                    trait_,
+                    sub: candidate.map(|c| errs::AssociatedFnWithSimilarNameExists {
+                        span: method.span,
+                        candidate: c,
+                    }),
+                })
             }
             ResolutionError::TypeNotMemberOfTrait(type_, trait_, candidate) => {
-                let mut err = struct_span_err!(
-                    self.session,
+                self.session.create_err(errs::TypeNotMemberOfTrait {
                     span,
-                    E0437,
-                    "type `{}` is not a member of trait `{}`",
                     type_,
-                    trait_
-                );
-                err.span_label(span, format!("not a member of trait `{}`", trait_));
-                if let Some(candidate) = candidate {
-                    err.span_suggestion(
-                        type_.span,
-                        "there is an associated type with a similar name",
-                        candidate.to_ident_string(),
-                        Applicability::MaybeIncorrect,
-                    );
-                }
-                err
+                    trait_,
+                    sub: candidate.map(|c| errs::AssociatedTypeWithSimilarNameExists {
+                        span: type_.span,
+                        candidate: c,
+                    }),
+                })
             }
             ResolutionError::ConstNotMemberOfTrait(const_, trait_, candidate) => {
-                let mut err = struct_span_err!(
-                    self.session,
+                self.session.create_err(errs::ConstNotMemberOfTrait {
                     span,
-                    E0438,
-                    "const `{}` is not a member of trait `{}`",
                     const_,
-                    trait_
-                );
-                err.span_label(span, format!("not a member of trait `{}`", trait_));
-                if let Some(candidate) = candidate {
-                    err.span_suggestion(
-                        const_.span,
-                        "there is an associated constant with a similar name",
-                        candidate.to_ident_string(),
-                        Applicability::MaybeIncorrect,
-                    );
-                }
-                err
+                    trait_,
+                    sub: candidate.map(|c| errs::AssociatedConstWithSimilarNameExists {
+                        span: const_.span,
+                        candidate: c,
+                    }),
+                })
             }
             ResolutionError::VariableNotBoundInPattern(binding_error, parent_scope) => {
                 let BindingError { name, target, origin, could_be_path } = binding_error;
@@ -730,128 +695,78 @@ pub(crate) fn into_struct_error(
                 err
             }
             ResolutionError::VariableBoundWithDifferentMode(variable_name, first_binding_span) => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0409,
-                    "variable `{}` is bound inconsistently across alternatives separated by `|`",
-                    variable_name
-                );
-                err.span_label(span, "bound in different ways");
-                err.span_label(first_binding_span, "first binding");
-                err
-            }
-            ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0415,
-                    "identifier `{}` is bound more than once in this parameter list",
-                    identifier
-                );
-                err.span_label(span, "used as parameter more than once");
-                err
-            }
-            ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
-                let mut err = struct_span_err!(
-                    self.session,
+                self.session.create_err(errs::VariableBoundWithDifferentMode {
                     span,
-                    E0416,
-                    "identifier `{}` is bound more than once in the same pattern",
-                    identifier
-                );
-                err.span_label(span, "used in a pattern more than once");
-                err
-            }
+                    first_binding_span,
+                    variable_name,
+                })
+            }
+            ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => self
+                .session
+                .create_err(errs::IdentifierBoundMoreThanOnceInParameterList { span, identifier }),
+            ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => self
+                .session
+                .create_err(errs::IdentifierBoundMoreThanOnceInSamePattern { span, identifier }),
             ResolutionError::UndeclaredLabel { name, suggestion } => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0426,
-                    "use of undeclared label `{}`",
-                    name
-                );
-
-                err.span_label(span, format!("undeclared label `{}`", name));
-
-                match suggestion {
+                let ((sub_reachable, sub_reachable_suggestion), sub_unreachable) = match suggestion
+                {
                     // A reachable label with a similar name exists.
-                    Some((ident, true)) => {
-                        err.span_label(ident.span, "a label with a similar name is reachable");
-                        err.span_suggestion(
-                            span,
-                            "try using similarly named label",
-                            ident.name,
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
+                    Some((ident, true)) => (
+                        (
+                            Some(errs::LabelWithSimilarNameReachable(ident.span)),
+                            Some(errs::TryUsingSimilarlyNamedLabel {
+                                span,
+                                ident_name: ident.name,
+                            }),
+                        ),
+                        None,
+                    ),
                     // An unreachable label with a similar name exists.
-                    Some((ident, false)) => {
-                        err.span_label(
-                            ident.span,
-                            "a label with a similar name exists but is unreachable",
-                        );
-                    }
+                    Some((ident, false)) => (
+                        (None, None),
+                        Some(errs::UnreachableLabelWithSimilarNameExists {
+                            ident_span: ident.span,
+                        }),
+                    ),
                     // No similarly-named labels exist.
-                    None => (),
-                }
-
-                err
+                    None => ((None, None), None),
+                };
+                self.session.create_err(errs::UndeclaredLabel {
+                    span,
+                    name,
+                    sub_reachable,
+                    sub_reachable_suggestion,
+                    sub_unreachable,
+                })
             }
             ResolutionError::SelfImportsOnlyAllowedWithin { root, span_with_rename } => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0429,
-                    "{}",
-                    "`self` imports are only allowed within a { } list"
-                );
-
                 // None of the suggestions below would help with a case like `use self`.
-                if !root {
+                let (suggestion, mpart_suggestion) = if root {
+                    (None, None)
+                } else {
                     // use foo::bar::self        -> foo::bar
                     // use foo::bar::self as abc -> foo::bar as abc
-                    err.span_suggestion(
-                        span,
-                        "consider importing the module directly",
-                        "",
-                        Applicability::MachineApplicable,
-                    );
+                    let suggestion = errs::SelfImportsOnlyAllowedWithinSuggestion { span };
 
                     // use foo::bar::self        -> foo::bar::{self}
                     // use foo::bar::self as abc -> foo::bar::{self as abc}
-                    let braces = vec![
-                        (span_with_rename.shrink_to_lo(), "{".to_string()),
-                        (span_with_rename.shrink_to_hi(), "}".to_string()),
-                    ];
-                    err.multipart_suggestion(
-                        "alternatively, use the multi-path `use` syntax to import `self`",
-                        braces,
-                        Applicability::MachineApplicable,
-                    );
-                }
-                err
+                    let mpart_suggestion = errs::SelfImportsOnlyAllowedWithinMultipartSuggestion {
+                        multipart_start: span_with_rename.shrink_to_lo(),
+                        multipart_end: span_with_rename.shrink_to_hi(),
+                    };
+                    (Some(suggestion), Some(mpart_suggestion))
+                };
+                self.session.create_err(errs::SelfImportsOnlyAllowedWithin {
+                    span,
+                    suggestion,
+                    mpart_suggestion,
+                })
             }
             ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0430,
-                    "`self` import can only appear once in an import list"
-                );
-                err.span_label(span, "can only appear once in an import list");
-                err
+                self.session.create_err(errs::SelfImportCanOnlyAppearOnceInTheList { span })
             }
             ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0431,
-                    "`self` import can only appear in an import list with \
-                                                a non-empty prefix"
-                );
-                err.span_label(span, "can only appear in an import list with a non-empty prefix");
-                err
+                self.session.create_err(errs::SelfImportOnlyInImportListWithNonEmptyPrefix { span })
             }
             ResolutionError::FailedToResolve { label, suggestion } => {
                 let mut err =
@@ -869,23 +784,9 @@ pub(crate) fn into_struct_error(
                 err
             }
             ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0434,
-                    "{}",
-                    "can't capture dynamic environment in a fn item"
-                );
-                err.help("use the `|| { ... }` closure form instead");
-                err
+                self.session.create_err(errs::CannotCaptureDynamicEnvironmentInFnItem { span })
             }
-            ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg, current) => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0435,
-                    "attempt to use a non-constant value in a constant"
-                );
+            ResolutionError::AttemptToUseNonConstantValueInConstant(ident, suggestion, current) => {
                 // let foo =...
                 //     ^^^ given this Span
                 // ------- get this Span to have an applicable suggestion
@@ -899,23 +800,34 @@ pub(crate) fn into_struct_error(
                     .source_map()
                     .span_extend_to_prev_str(ident.span, current, true, false);
 
-                match sp {
+                let ((with, with_label), without) = match sp {
                     Some(sp) if !self.session.source_map().is_multiline(sp) => {
                         let sp = sp.with_lo(BytePos(sp.lo().0 - (current.len() as u32)));
-                        err.span_suggestion(
-                            sp,
-                            &format!("consider using `{}` instead of `{}`", sugg, current),
-                            format!("{} {}", sugg, ident),
-                            Applicability::MaybeIncorrect,
-                        );
-                        err.span_label(span, "non-constant value");
-                    }
-                    _ => {
-                        err.span_label(ident.span, &format!("this would need to be a `{}`", sugg));
+                        (
+                        (Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion {
+                                span: sp,
+                                ident,
+                                suggestion,
+                                current,
+                            }), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})),
+                            None,
+                        )
                     }
-                }
+                    _ => (
+                        (None, None),
+                        Some(errs::AttemptToUseNonConstantValueInConstantWithoutSuggestion {
+                            ident_span: ident.span,
+                            suggestion,
+                        }),
+                    ),
+                };
 
-                err
+                self.session.create_err(errs::AttemptToUseNonConstantValueInConstant {
+                    span,
+                    with,
+                    with_label,
+                    without,
+                })
             }
             ResolutionError::BindingShadowsSomethingUnacceptable {
                 shadowing_binding,
@@ -924,135 +836,80 @@ pub(crate) fn into_struct_error(
                 article,
                 shadowed_binding,
                 shadowed_binding_span,
-            } => {
-                let shadowed_binding_descr = shadowed_binding.descr();
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0530,
-                    "{}s cannot shadow {}s",
-                    shadowing_binding.descr(),
-                    shadowed_binding_descr,
-                );
-                err.span_label(
-                    span,
-                    format!("cannot be named the same as {} {}", article, shadowed_binding_descr),
-                );
-                match (shadowing_binding, shadowed_binding) {
+            } => self.session.create_err(errs::BindingShadowsSomethingUnacceptable {
+                span,
+                shadowing_binding,
+                shadowed_binding,
+                article,
+                sub_suggestion: match (shadowing_binding, shadowed_binding) {
                     (
                         PatternSource::Match,
                         Res::Def(DefKind::Ctor(CtorOf::Variant | CtorOf::Struct, CtorKind::Fn), _),
-                    ) => {
-                        err.span_suggestion(
-                            span,
-                            "try specify the pattern arguments",
-                            format!("{}(..)", name),
-                            Applicability::Unspecified,
-                        );
-                    }
-                    _ => (),
-                }
-                let msg =
-                    format!("the {} `{}` is {} here", shadowed_binding_descr, name, participle);
-                err.span_label(shadowed_binding_span, msg);
-                err
-            }
+                    ) => Some(errs::BindingShadowsSomethingUnacceptableSuggestion { span, name }),
+                    _ => None,
+                },
+                shadowed_binding_span,
+                participle,
+                name,
+            }),
             ResolutionError::ForwardDeclaredGenericParam => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0128,
-                    "generic parameters with a default cannot use \
-                                                forward declared identifiers"
-                );
-                err.span_label(span, "defaulted generic parameters cannot be forward declared");
-                err
+                self.session.create_err(errs::ForwardDeclaredGenericParam { span })
             }
             ResolutionError::ParamInTyOfConstParam(name) => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0770,
-                    "the type of const parameters must not depend on other generic parameters"
-                );
-                err.span_label(
-                    span,
-                    format!("the type must not depend on the parameter `{}`", name),
-                );
-                err
+                self.session.create_err(errs::ParamInTyOfConstParam { span, name })
             }
             ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
-                let mut err = self.session.struct_span_err(
+                self.session.create_err(errs::ParamInNonTrivialAnonConst {
                     span,
-                    "generic parameters may not be used in const operations",
-                );
-                err.span_label(span, &format!("cannot perform const operation using `{}`", name));
-
-                if is_type {
-                    err.note("type parameters may not be used in const expressions");
-                } else {
-                    err.help(&format!(
-                        "const parameters may only be used as standalone arguments, i.e. `{}`",
-                        name
-                    ));
-                }
-
-                if self.session.is_nightly_build() {
-                    err.help(
-                        "use `#![feature(generic_const_exprs)]` to allow generic const expressions",
-                    );
-                }
-
-                err
+                    name,
+                    sub_is_type: if is_type {
+                        errs::ParamInNonTrivialAnonConstIsType::AType
+                    } else {
+                        errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
+                    },
+                    help: self
+                        .session
+                        .is_nightly_build()
+                        .then_some(errs::ParamInNonTrivialAnonConstHelp),
+                })
             }
             ResolutionError::SelfInGenericParamDefault => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0735,
-                    "generic parameters cannot use `Self` in their defaults"
-                );
-                err.span_label(span, "`Self` in generic parameter default");
-                err
+                self.session.create_err(errs::SelfInGenericParamDefault { span })
             }
             ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
-                let mut err = struct_span_err!(
-                    self.session,
+                let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =
+                    match suggestion {
+                        // A reachable label with a similar name exists.
+                        Some((ident, true)) => (
+                            (
+                                Some(errs::UnreachableLabelSubLabel { ident_span: ident.span }),
+                                Some(errs::UnreachableLabelSubSuggestion {
+                                    span,
+                                    // intentionally taking 'ident.name' instead of 'ident' itself, as this
+                                    // could be used in suggestion context
+                                    ident_name: ident.name,
+                                }),
+                            ),
+                            None,
+                        ),
+                        // An unreachable label with a similar name exists.
+                        Some((ident, false)) => (
+                            (None, None),
+                            Some(errs::UnreachableLabelSubLabelUnreachable {
+                                ident_span: ident.span,
+                            }),
+                        ),
+                        // No similarly-named labels exist.
+                        None => ((None, None), None),
+                    };
+                self.session.create_err(errs::UnreachableLabel {
                     span,
-                    E0767,
-                    "use of unreachable label `{}`",
                     name,
-                );
-
-                err.span_label(definition_span, "unreachable label defined here");
-                err.span_label(span, format!("unreachable label `{}`", name));
-                err.note(
-                    "labels are unreachable through functions, closures, async blocks and modules",
-                );
-
-                match suggestion {
-                    // A reachable label with a similar name exists.
-                    Some((ident, true)) => {
-                        err.span_label(ident.span, "a label with a similar name is reachable");
-                        err.span_suggestion(
-                            span,
-                            "try using similarly named label",
-                            ident.name,
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                    // An unreachable label with a similar name exists.
-                    Some((ident, false)) => {
-                        err.span_label(
-                            ident.span,
-                            "a label with a similar name exists but is also unreachable",
-                        );
-                    }
-                    // No similarly-named labels exist.
-                    None => (),
-                }
-
-                err
+                    definition_span,
+                    sub_suggestion,
+                    sub_suggestion_label,
+                    sub_unreachable_label,
+                })
             }
             ResolutionError::TraitImplMismatch {
                 name,
@@ -1073,25 +930,10 @@ pub(crate) fn into_struct_error(
                 err.span_label(trait_item_span, "item in trait");
                 err
             }
-            ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0201,
-                    "duplicate definitions with name `{}`:",
-                    name,
-                );
-                err.span_label(old_span, "previous definition here");
-                err.span_label(trait_item_span, "item in trait");
-                err.span_label(span, "duplicate definition");
-                err
-            }
-            ResolutionError::InvalidAsmSym => {
-                let mut err = self.session.struct_span_err(span, "invalid `sym` operand");
-                err.span_label(span, "is a local variable");
-                err.help("`sym` operands must refer to either a function or a static");
-                err
-            }
+            ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => self
+                .session
+                .create_err(errs::TraitImplDuplicate { span, name, trait_item_span, old_span }),
+            ResolutionError::InvalidAsmSym => self.session.create_err(errs::InvalidAsmSym { span }),
         }
     }
 
@@ -1101,48 +943,27 @@ pub(crate) fn report_vis_error(
     ) -> ErrorGuaranteed {
         match vis_resolution_error {
             VisResolutionError::Relative2018(span, path) => {
-                let mut err = self.session.struct_span_err(
+                self.session.create_err(errs::Relative2018 {
                     span,
-                    "relative paths are not supported in visibilities in 2018 edition or later",
-                );
-                err.span_suggestion(
-                    path.span,
-                    "try",
-                    format!("crate::{}", pprust::path_to_string(&path)),
-                    Applicability::MaybeIncorrect,
-                );
-                err
+                    path_span: path.span,
+                    // intentionally converting to String, as the text would also be used as
+                    // in suggestion context
+                    path_str: pprust::path_to_string(&path),
+                })
+            }
+            VisResolutionError::AncestorOnly(span) => {
+                self.session.create_err(errs::AncestorOnly(span))
             }
-            VisResolutionError::AncestorOnly(span) => struct_span_err!(
-                self.session,
-                span,
-                E0742,
-                "visibilities can only be restricted to ancestor modules"
-            ),
             VisResolutionError::FailedToResolve(span, label, suggestion) => {
                 self.into_struct_error(span, ResolutionError::FailedToResolve { label, suggestion })
             }
             VisResolutionError::ExpectedFound(span, path_str, res) => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0577,
-                    "expected module, found {} `{}`",
-                    res.descr(),
-                    path_str
-                );
-                err.span_label(span, "not a module");
-                err
+                self.session.create_err(errs::ExpectedFound { span, res, path_str })
             }
-            VisResolutionError::Indeterminate(span) => struct_span_err!(
-                self.session,
-                span,
-                E0578,
-                "cannot determine resolution for the visibility"
-            ),
-            VisResolutionError::ModuleOnly(span) => {
-                self.session.struct_span_err(span, "visibility must resolve to a module")
+            VisResolutionError::Indeterminate(span) => {
+                self.session.create_err(errs::Indeterminate(span))
             }
+            VisResolutionError::ModuleOnly(span) => self.session.create_err(errs::ModuleOnly(span)),
         }
         .emit()
     }
@@ -1295,7 +1116,7 @@ fn lookup_import_candidates_from_module<FilterFn>(
     {
         let mut candidates = Vec::new();
         let mut seen_modules = FxHashSet::default();
-        let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), true)];
+        let mut worklist = vec![(start_module, ThinVec::<ast::PathSegment>::new(), true)];
         let mut worklist_via_import = vec![];
 
         while let Some((in_module, path_segments, accessible)) = match worklist.pop() {
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
new file mode 100644 (file)
index 0000000..2c44277
--- /dev/null
@@ -0,0 +1,474 @@
+use rustc_macros::{Diagnostic, Subdiagnostic};
+use rustc_span::{
+    symbol::{Ident, Symbol},
+    Span,
+};
+
+use crate::{late::PatternSource, Res};
+
+#[derive(Diagnostic)]
+#[diag(resolve_parent_module_reset_for_binding, code = "E0637")]
+pub(crate) struct ParentModuleResetForBinding;
+
+#[derive(Diagnostic)]
+#[diag(resolve_ampersand_used_without_explicit_lifetime_name, code = "E0637")]
+#[note]
+pub(crate) struct AmpersandUsedWithoutExplicitLifetimeName(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_underscore_lifetime_name_cannot_be_used_here, code = "E0637")]
+#[note]
+pub(crate) struct UnderscoreLifetimeNameCannotBeUsedHere(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_crate_may_not_be_imported)]
+pub(crate) struct CrateMayNotBeImprted(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_crate_root_imports_must_be_named_explicitly)]
+pub(crate) struct CrateRootNamesMustBeNamedExplicitly(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_crate_root_imports_must_be_named_explicitly)]
+pub(crate) struct ResolutionError(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_name_is_already_used_as_generic_parameter, code = "E0403")]
+pub(crate) struct NameAlreadyUsedInParameterList {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[label(first_use_of_name)]
+    pub(crate) first_use_span: Span,
+    pub(crate) name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_method_not_member_of_trait, code = "E0407")]
+pub(crate) struct MethodNotMemberOfTrait {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) method: Ident,
+    pub(crate) trait_: String,
+    #[subdiagnostic]
+    pub(crate) sub: Option<AssociatedFnWithSimilarNameExists>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    resolve_associated_fn_with_similar_name_exists,
+    code = "{candidate}",
+    applicability = "maybe-incorrect"
+)]
+pub(crate) struct AssociatedFnWithSimilarNameExists {
+    #[primary_span]
+    pub(crate) span: Span,
+    pub(crate) candidate: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_type_not_member_of_trait, code = "E0437")]
+pub(crate) struct TypeNotMemberOfTrait {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) type_: Ident,
+    pub(crate) trait_: String,
+    #[subdiagnostic]
+    pub(crate) sub: Option<AssociatedTypeWithSimilarNameExists>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    resolve_associated_type_with_similar_name_exists,
+    code = "{candidate}",
+    applicability = "maybe-incorrect"
+)]
+pub(crate) struct AssociatedTypeWithSimilarNameExists {
+    #[primary_span]
+    pub(crate) span: Span,
+    pub(crate) candidate: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_const_not_member_of_trait, code = "E0438")]
+pub(crate) struct ConstNotMemberOfTrait {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) const_: Ident,
+    pub(crate) trait_: String,
+    #[subdiagnostic]
+    pub(crate) sub: Option<AssociatedConstWithSimilarNameExists>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    resolve_associated_const_with_similar_name_exists,
+    code = "{candidate}",
+    applicability = "maybe-incorrect"
+)]
+pub(crate) struct AssociatedConstWithSimilarNameExists {
+    #[primary_span]
+    pub(crate) span: Span,
+    pub(crate) candidate: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_variable_bound_with_different_mode, code = "E0409")]
+pub(crate) struct VariableBoundWithDifferentMode {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[label(first_binding_span)]
+    pub(crate) first_binding_span: Span,
+    pub(crate) variable_name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_ident_bound_more_than_once_in_parameter_list, code = "E0415")]
+pub(crate) struct IdentifierBoundMoreThanOnceInParameterList {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) identifier: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_ident_bound_more_than_once_in_same_pattern, code = "E0416")]
+pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) identifier: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_undeclared_label, code = "E0426")]
+pub(crate) struct UndeclaredLabel {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) name: Symbol,
+    #[subdiagnostic]
+    pub(crate) sub_reachable: Option<LabelWithSimilarNameReachable>,
+    #[subdiagnostic]
+    pub(crate) sub_reachable_suggestion: Option<TryUsingSimilarlyNamedLabel>,
+    #[subdiagnostic]
+    pub(crate) sub_unreachable: Option<UnreachableLabelWithSimilarNameExists>,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_label_with_similar_name_reachable)]
+pub(crate) struct LabelWithSimilarNameReachable(#[primary_span] pub(crate) Span);
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    resolve_try_using_similarly_named_label,
+    code = "{ident_name}",
+    applicability = "maybe-incorrect"
+)]
+pub(crate) struct TryUsingSimilarlyNamedLabel {
+    #[primary_span]
+    pub(crate) span: Span,
+    pub(crate) ident_name: Symbol,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_unreachable_label_with_similar_name_exists)]
+pub(crate) struct UnreachableLabelWithSimilarNameExists {
+    #[primary_span]
+    pub(crate) ident_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_self_import_can_only_appear_once_in_the_list, code = "E0430")]
+pub(crate) struct SelfImportCanOnlyAppearOnceInTheList {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_self_import_only_in_import_list_with_non_empty_prefix, code = "E0431")]
+pub(crate) struct SelfImportOnlyInImportListWithNonEmptyPrefix {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_cannot_capture_dynamic_environment_in_fn_item, code = "E0434")]
+#[help]
+pub(crate) struct CannotCaptureDynamicEnvironmentInFnItem {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_attempt_to_use_non_constant_value_in_constant, code = "E0435")]
+pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> {
+    #[primary_span]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) with: Option<AttemptToUseNonConstantValueInConstantWithSuggestion<'a>>,
+    #[subdiagnostic]
+    pub(crate) with_label: Option<AttemptToUseNonConstantValueInConstantLabelWithSuggestion>,
+    #[subdiagnostic]
+    pub(crate) without: Option<AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a>>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion,
+    code = "{suggestion} {ident}",
+    applicability = "maybe-incorrect"
+)]
+pub(crate) struct AttemptToUseNonConstantValueInConstantWithSuggestion<'a> {
+    #[primary_span]
+    pub(crate) span: Span,
+    pub(crate) ident: Ident,
+    pub(crate) suggestion: &'a str,
+    pub(crate) current: &'a str,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion)]
+pub(crate) struct AttemptToUseNonConstantValueInConstantLabelWithSuggestion {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion)]
+pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> {
+    #[primary_span]
+    pub(crate) ident_span: Span,
+    pub(crate) suggestion: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_self_imports_only_allowed_within, code = "E0429")]
+pub(crate) struct SelfImportsOnlyAllowedWithin {
+    #[primary_span]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) suggestion: Option<SelfImportsOnlyAllowedWithinSuggestion>,
+    #[subdiagnostic]
+    pub(crate) mpart_suggestion: Option<SelfImportsOnlyAllowedWithinMultipartSuggestion>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    resolve_self_imports_only_allowed_within_suggestion,
+    code = "",
+    applicability = "machine-applicable"
+)]
+pub(crate) struct SelfImportsOnlyAllowedWithinSuggestion {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(
+    resolve_self_imports_only_allowed_within_multipart_suggestion,
+    applicability = "machine-applicable"
+)]
+pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion {
+    #[suggestion_part(code = "{{")]
+    pub(crate) multipart_start: Span,
+    #[suggestion_part(code = "}}")]
+    pub(crate) multipart_end: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_binding_shadows_something_unacceptable, code = "E0530")]
+pub(crate) struct BindingShadowsSomethingUnacceptable<'a> {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) shadowing_binding: PatternSource,
+    pub(crate) shadowed_binding: Res,
+    pub(crate) article: &'a str,
+    #[subdiagnostic]
+    pub(crate) sub_suggestion: Option<BindingShadowsSomethingUnacceptableSuggestion>,
+    #[label(label_shadowed_binding)]
+    pub(crate) shadowed_binding_span: Span,
+    pub(crate) participle: &'a str,
+    pub(crate) name: Symbol,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    resolve_binding_shadows_something_unacceptable_suggestion,
+    code = "{name}(..)",
+    applicability = "unspecified"
+)]
+pub(crate) struct BindingShadowsSomethingUnacceptableSuggestion {
+    #[primary_span]
+    pub(crate) span: Span,
+    pub(crate) name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_forward_declared_generic_param, code = "E0128")]
+pub(crate) struct ForwardDeclaredGenericParam {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_param_in_ty_of_const_param, code = "E0770")]
+pub(crate) struct ParamInTyOfConstParam {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_self_in_generic_param_default, code = "E0735")]
+pub(crate) struct SelfInGenericParamDefault {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_param_in_non_trivial_anon_const)]
+pub(crate) struct ParamInNonTrivialAnonConst {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) name: Symbol,
+    #[subdiagnostic]
+    pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType,
+    #[subdiagnostic]
+    pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>,
+}
+
+#[derive(Subdiagnostic)]
+#[help(resolve_param_in_non_trivial_anon_const_help)]
+pub(crate) struct ParamInNonTrivialAnonConstHelp;
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamInNonTrivialAnonConstIsType {
+    #[note(resolve_param_in_non_trivial_anon_const_sub_type)]
+    AType,
+    #[help(resolve_param_in_non_trivial_anon_const_sub_non_type)]
+    NotAType { name: Symbol },
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_unreachable_label, code = "E0767")]
+#[note]
+pub(crate) struct UnreachableLabel {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) name: Symbol,
+    #[label(label_definition_span)]
+    pub(crate) definition_span: Span,
+    #[subdiagnostic]
+    pub(crate) sub_suggestion: Option<UnreachableLabelSubSuggestion>,
+    #[subdiagnostic]
+    pub(crate) sub_suggestion_label: Option<UnreachableLabelSubLabel>,
+    #[subdiagnostic]
+    pub(crate) sub_unreachable_label: Option<UnreachableLabelSubLabelUnreachable>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    resolve_unreachable_label_suggestion_use_similarly_named,
+    code = "{ident_name}",
+    applicability = "maybe-incorrect"
+)]
+pub(crate) struct UnreachableLabelSubSuggestion {
+    #[primary_span]
+    pub(crate) span: Span,
+    pub(crate) ident_name: Symbol,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_unreachable_label_similar_name_reachable)]
+pub(crate) struct UnreachableLabelSubLabel {
+    #[primary_span]
+    pub(crate) ident_span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_unreachable_label_similar_name_unreachable)]
+pub(crate) struct UnreachableLabelSubLabelUnreachable {
+    #[primary_span]
+    pub(crate) ident_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_trait_impl_mismatch, code = "{code}")]
+pub(crate) struct TraitImplMismatch {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) name: Symbol,
+    pub(crate) kind: String,
+    #[label(label_trait_item)]
+    pub(crate) trait_item_span: Span,
+    pub(crate) trait_path: String,
+    pub(crate) code: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_invalid_asm_sym)]
+#[help]
+pub(crate) struct InvalidAsmSym {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_trait_impl_duplicate, code = "E0201")]
+pub(crate) struct TraitImplDuplicate {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[label(old_span_label)]
+    pub(crate) old_span: Span,
+    #[label(trait_item_span)]
+    pub(crate) trait_item_span: Span,
+    pub(crate) name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_relative_2018)]
+pub(crate) struct Relative2018 {
+    #[primary_span]
+    pub(crate) span: Span,
+    #[suggestion(code = "crate::{path_str}", applicability = "maybe-incorrect")]
+    pub(crate) path_span: Span,
+    pub(crate) path_str: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_ancestor_only, code = "E0742")]
+pub(crate) struct AncestorOnly(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_expected_found, code = "E0577")]
+pub(crate) struct ExpectedFound {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) res: Res,
+    pub(crate) path_str: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_indeterminate, code = "E0578")]
+pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_module_only)]
+pub(crate) struct ModuleOnly(#[primary_span] pub(crate) Span);
index ede67813883d6b2643464e886c8f769156b6c7e8..5072d2aad1669ff99e10c879563db2606aa237a8 100644 (file)
@@ -16,7 +16,7 @@
 use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
 use rustc_ast::*;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
-use rustc_errors::DiagnosticId;
+use rustc_errors::{DiagnosticArgValue, DiagnosticId, IntoDiagnosticArg};
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@@ -31,6 +31,7 @@
 
 use rustc_span::source_map::{respan, Spanned};
 use std::assert_matches::debug_assert_matches;
+use std::borrow::Cow;
 use std::collections::{hash_map::Entry, BTreeSet};
 use std::mem::{replace, swap, take};
 
@@ -78,6 +79,12 @@ pub fn descr(self) -> &'static str {
     }
 }
 
+impl IntoDiagnosticArg for PatternSource {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
+    }
+}
+
 /// Denotes whether the context for the set of already bound bindings is a `Product`
 /// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`.
 /// See those functions for more information.
@@ -648,7 +655,7 @@ fn visit_ty(&mut self, ty: &'ast Ty) {
             }
             TyKind::Path(ref qself, ref path) => {
                 self.diagnostic_metadata.current_type_path = Some(ty);
-                self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
+                self.smart_resolve_path(ty.id, &qself, path, PathSource::Type);
 
                 // Check whether we should interpret this as a bare trait object.
                 if qself.is_none()
@@ -749,7 +756,7 @@ fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {
                 this.visit_generic_params(&tref.bound_generic_params, false);
                 this.smart_resolve_path(
                     tref.trait_ref.ref_id,
-                    None,
+                    &None,
                     &tref.trait_ref.path,
                     PathSource::Trait(AliasPossibility::Maybe),
                 );
@@ -978,7 +985,7 @@ fn visit_generic_arg(&mut self, arg: &'ast GenericArg) {
                                 |this| {
                                     this.smart_resolve_path(
                                         ty.id,
-                                        qself.as_ref(),
+                                        qself,
                                         path,
                                         PathSource::Expr(None),
                                     );
@@ -1138,12 +1145,7 @@ fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
         self.with_rib(ValueNS, InlineAsmSymRibKind, |this| {
             this.with_rib(TypeNS, InlineAsmSymRibKind, |this| {
                 this.with_label_rib(InlineAsmSymRibKind, |this| {
-                    this.smart_resolve_path(
-                        sym.id,
-                        sym.qself.as_ref(),
-                        &sym.path,
-                        PathSource::Expr(None),
-                    );
+                    this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None));
                     visit::walk_inline_asm_sym(this, sym);
                 });
             })
@@ -2571,7 +2573,7 @@ fn with_optional_trait_ref<T>(
             self.diagnostic_metadata.currently_processing_impl_trait =
                 Some((trait_ref.clone(), self_type.clone()));
             let res = self.smart_resolve_path_fragment(
-                None,
+                &None,
                 &path,
                 PathSource::Trait(AliasPossibility::No),
                 Finalize::new(trait_ref.ref_id, trait_ref.path.span),
@@ -3094,7 +3096,7 @@ fn resolve_pattern_inner(
                 PatKind::TupleStruct(ref qself, ref path, ref sub_patterns) => {
                     self.smart_resolve_path(
                         pat.id,
-                        qself.as_ref(),
+                        qself,
                         path,
                         PathSource::TupleStruct(
                             pat.span,
@@ -3103,10 +3105,10 @@ fn resolve_pattern_inner(
                     );
                 }
                 PatKind::Path(ref qself, ref path) => {
-                    self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat);
+                    self.smart_resolve_path(pat.id, qself, path, PathSource::Pat);
                 }
                 PatKind::Struct(ref qself, ref path, ..) => {
-                    self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Struct);
+                    self.smart_resolve_path(pat.id, qself, path, PathSource::Struct);
                 }
                 PatKind::Or(ref ps) => {
                     // Add a new set of bindings to the stack. `Or` here records that when a
@@ -3299,7 +3301,7 @@ fn try_resolve_as_non_binding(
     fn smart_resolve_path(
         &mut self,
         id: NodeId,
-        qself: Option<&QSelf>,
+        qself: &Option<P<QSelf>>,
         path: &Path,
         source: PathSource<'ast>,
     ) {
@@ -3313,7 +3315,7 @@ fn smart_resolve_path(
 
     fn smart_resolve_path_fragment(
         &mut self,
-        qself: Option<&QSelf>,
+        qself: &Option<P<QSelf>>,
         path: &[Segment],
         source: PathSource<'ast>,
         finalize: Finalize,
@@ -3534,7 +3536,7 @@ fn should_report_errs(&self) -> bool {
     // Resolve in alternative namespaces if resolution in the primary namespace fails.
     fn resolve_qpath_anywhere(
         &mut self,
-        qself: Option<&QSelf>,
+        qself: &Option<P<QSelf>>,
         path: &[Segment],
         primary_ns: Namespace,
         span: Span,
@@ -3578,7 +3580,7 @@ fn resolve_qpath_anywhere(
     /// Handles paths that may refer to associated items.
     fn resolve_qpath(
         &mut self,
-        qself: Option<&QSelf>,
+        qself: &Option<P<QSelf>>,
         path: &[Segment],
         ns: Namespace,
         finalize: Finalize,
@@ -3608,7 +3610,7 @@ fn resolve_qpath(
             // but with `qself` set to `None`.
             let ns = if qself.position + 1 == path.len() { ns } else { TypeNS };
             let partial_res = self.smart_resolve_path_fragment(
-                None,
+                &None,
                 &path[..=qself.position],
                 PathSource::TraitItem(ns),
                 Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span),
@@ -3791,12 +3793,12 @@ fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
         // Next, resolve the node.
         match expr.kind {
             ExprKind::Path(ref qself, ref path) => {
-                self.smart_resolve_path(expr.id, qself.as_ref(), path, PathSource::Expr(parent));
+                self.smart_resolve_path(expr.id, qself, path, PathSource::Expr(parent));
                 visit::walk_expr(self, expr);
             }
 
             ExprKind::Struct(ref se) => {
-                self.smart_resolve_path(expr.id, se.qself.as_ref(), &se.path, PathSource::Struct);
+                self.smart_resolve_path(expr.id, &se.qself, &se.path, PathSource::Struct);
                 visit::walk_expr(self, expr);
             }
 
@@ -3866,12 +3868,12 @@ fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
             ExprKind::Field(ref subexpression, _) => {
                 self.resolve_expr(subexpression, Some(expr));
             }
-            ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _) => {
+            ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, .. }) => {
                 self.resolve_expr(receiver, Some(expr));
-                for argument in arguments {
-                    self.resolve_expr(argument, None);
+                for arg in args {
+                    self.resolve_expr(arg, None);
                 }
-                self.visit_path_segment(segment);
+                self.visit_path_segment(seg);
             }
 
             ExprKind::Call(ref callee, ref arguments) => {
@@ -3913,7 +3915,12 @@ fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
             // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
             // resolve the arguments within the proper scopes so that usages of them inside the
             // closure are detected as upvars rather than normal closure arg usages.
-            ExprKind::Closure(_, _, Async::Yes { .. }, _, ref fn_decl, ref body, _span) => {
+            ExprKind::Closure(box ast::Closure {
+                asyncness: Async::Yes { .. },
+                ref fn_decl,
+                ref body,
+                ..
+            }) => {
                 self.with_rib(ValueNS, NormalRibKind, |this| {
                     this.with_label_rib(ClosureOrAsyncRibKind, |this| {
                         // Resolve arguments:
@@ -3933,7 +3940,10 @@ fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
                 });
             }
             // For closures, ClosureOrAsyncRibKind is added in visit_fn
-            ExprKind::Closure(ClosureBinder::For { ref generic_params, span }, ..) => {
+            ExprKind::Closure(box ast::Closure {
+                binder: ClosureBinder::For { ref generic_params, span },
+                ..
+            }) => {
                 self.with_generic_param_rib(
                     &generic_params,
                     NormalRibKind,
@@ -3990,9 +4000,9 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &'ast Expr) {
                 let traits = self.traits_in_scope(ident, ValueNS);
                 self.r.trait_map.insert(expr.id, traits);
             }
-            ExprKind::MethodCall(ref segment, ..) => {
+            ExprKind::MethodCall(ref call) => {
                 debug!("(recording candidate traits for expr) recording traits for {}", expr.id);
-                let traits = self.traits_in_scope(segment.ident, ValueNS);
+                let traits = self.traits_in_scope(call.seg.ident, ValueNS);
                 self.r.trait_map.insert(expr.id, traits);
             }
             _ => {
index 95eff92ef5e2471775f13aa5fa13cd2e84eb5532..e0c927dd1e7602ac12e1550cbddb892359e86109 100644 (file)
@@ -8,7 +8,7 @@
 use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt};
 use rustc_ast::{
     self as ast, AssocItemKind, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind,
-    NodeId, Path, Ty, TyKind, DUMMY_NODE_ID,
+    MethodCall, NodeId, Path, Ty, TyKind, DUMMY_NODE_ID,
 };
 use rustc_ast_pretty::pprust::path_segment_to_string;
 use rustc_data_structures::fx::FxHashSet;
@@ -33,6 +33,8 @@
 use std::iter;
 use std::ops::Deref;
 
+use thin_vec::ThinVec;
+
 type Res = def::Res<ast::NodeId>;
 
 /// A field or associated item from self type suggested in case of resolution failure.
@@ -78,7 +80,7 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str
     let path_len = suggestion.path.segments.len();
     let enum_path = ast::Path {
         span: suggestion.path.span,
-        segments: suggestion.path.segments[0..path_len - 1].to_vec(),
+        segments: suggestion.path.segments[0..path_len - 1].iter().cloned().collect(),
         tokens: None,
     };
     let enum_path_string = path_names_to_string(&enum_path);
@@ -1022,11 +1024,7 @@ fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diagnost
             };
 
         // Confirm that the target is an associated type.
-        let (ty, position, path) = if let ast::TyKind::Path(
-            Some(ast::QSelf { ty, position, .. }),
-            path,
-        ) = &bounded_ty.kind
-        {
+        let (ty, position, path) = if let ast::TyKind::Path(Some(qself), path) = &bounded_ty.kind {
             // use this to verify that ident is a type param.
             let Some(partial_res) = self.r.partial_res_map.get(&bounded_ty.id) else {
                 return false;
@@ -1037,7 +1035,7 @@ fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diagnost
             ) {
                 return false;
             }
-            (ty, position, path)
+            (&qself.ty, qself.position, path)
         } else {
             return false;
         };
@@ -1073,12 +1071,12 @@ fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diagnost
                                     .source_map()
                                     .span_to_snippet(ty.span) // Account for `<&'a T as Foo>::Bar`.
                                     .unwrap_or_else(|_| constrain_ident.to_string()),
-                                path.segments[..*position]
+                                path.segments[..position]
                                     .iter()
                                     .map(|segment| path_segment_to_string(segment))
                                     .collect::<Vec<_>>()
                                     .join("::"),
-                                path.segments[*position..]
+                                path.segments[position..]
                                     .iter()
                                     .map(|segment| path_segment_to_string(segment))
                                     .collect::<Vec<_>>()
@@ -1170,7 +1168,9 @@ fn smart_resolve_context_dependent_help(
 
             let (lhs_span, rhs_span) = match &expr.kind {
                 ExprKind::Field(base, ident) => (base.span, ident.span),
-                ExprKind::MethodCall(_, receiver, _, span) => (receiver.span, *span),
+                ExprKind::MethodCall(box MethodCall { receiver, span, .. }) => {
+                    (receiver.span, *span)
+                }
                 _ => return false,
             };
 
@@ -1833,7 +1833,7 @@ fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) ->
     fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {
         let mut result = None;
         let mut seen_modules = FxHashSet::default();
-        let mut worklist = vec![(self.r.graph_root, Vec::new())];
+        let mut worklist = vec![(self.r.graph_root, ThinVec::new())];
 
         while let Some((in_module, path_segments)) = worklist.pop() {
             // abort if the module is already found
index 9ca3588fff4510e4c2d43c3e16ae17a9cd0144fe..f9ae3b58172725eefc65025acd2332026b3f7143 100644 (file)
@@ -73,6 +73,7 @@
 mod def_collector;
 mod diagnostics;
 mod effective_visibilities;
+mod errors;
 mod ident;
 mod imports;
 mod late;
index 103521983578bc4d8670429afd93e6c3dde5cb6e..d602acec53e3214998c52ffa1f52ca334428f916 100644 (file)
@@ -562,7 +562,10 @@ pub fn track_errors<F, T>(&self, f: F) -> Result<T, ErrorGuaranteed>
         if self.err_count() == old_count {
             Ok(result)
         } else {
-            Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
+            Err(self.delay_span_bug(
+                rustc_span::DUMMY_SP,
+                "`self.err_count()` changed but an error was not emitted",
+            ))
         }
     }
     #[allow(rustc::untranslatable_diagnostic)]
index 7ea028b12efc41f40fe19250c427ddd5608e68bf..e8d129d733c1e340c10b76bbc28cb2e3b3646c08 100644 (file)
@@ -753,10 +753,11 @@ pub fn span_until_char(&self, sp: Span, c: char) -> Span {
         }
     }
 
-    /// Given a 'Span', tries to tell if the next character is '>'
-    /// and the previous charactoer is '<' after skipping white space
-    /// return true if wrapped by '<>'
-    pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool {
+    /// Given a 'Span', tries to tell if it's wrapped by "<>" or "()"
+    /// the algorithm searches if the next character is '>' or ')' after skipping white space
+    /// then searches the previous charactoer to match '<' or '(' after skipping white space
+    /// return true if wrapped by '<>' or '()'
+    pub fn span_wrapped_by_angle_or_parentheses(&self, span: Span) -> bool {
         self.span_to_source(span, |src, start_index, end_index| {
             if src.get(start_index..end_index).is_none() {
                 return Ok(false);
@@ -764,11 +765,17 @@ pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool {
             // test the right side to match '>' after skipping white space
             let end_src = &src[end_index..];
             let mut i = 0;
+            let mut found_right_parentheses = false;
+            let mut found_right_angle = false;
             while let Some(cc) = end_src.chars().nth(i) {
                 if cc == ' ' {
                     i = i + 1;
                 } else if cc == '>' {
                     // found > in the right;
+                    found_right_angle = true;
+                    break;
+                } else if cc == ')' {
+                    found_right_parentheses = true;
                     break;
                 } else {
                     // failed to find '>' return false immediately
@@ -786,6 +793,16 @@ pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool {
                     i = i - 1;
                 } else if cc == '<' {
                     // found < in the left
+                    if !found_right_angle {
+                        // skip something like "(< )>"
+                        return Ok(false);
+                    }
+                    break;
+                } else if cc == '(' {
+                    if !found_right_parentheses {
+                        // skip something like "<(>)"
+                        return Ok(false);
+                    }
                     break;
                 } else {
                     // failed to find '<' return false immediately
index 02848bcffb298b43440ada72efc8a5ffd7c0a544..1b109ca6b11dd0d851c4e0470cd5c21b62c12030 100644 (file)
         plugins,
         pointee_trait,
         pointer,
+        pointer_sized,
         poll,
         position,
         post_dash_lto: "post-lto",
         str_trim_end,
         str_trim_start,
         strict_provenance,
+        string_deref_patterns,
         stringify,
         struct_field_attributes,
         struct_inherit,
index c5a6f9893b6f9ec49a0a49123a2ae974bf3228d2..0c559ec04a413f1e86aab9052148956e89b5a5f3 100644 (file)
@@ -3,6 +3,7 @@
 use crate::spec::{self, HasTargetSpec};
 use rustc_span::Symbol;
 use std::fmt;
+use std::str::FromStr;
 
 mod aarch64;
 mod amdgpu;
@@ -737,6 +738,33 @@ pub fn adjust_for_foreign_abi<C>(
     }
 }
 
+impl FromStr for Conv {
+    type Err = String;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "C" => Ok(Conv::C),
+            "Rust" => Ok(Conv::Rust),
+            "RustCold" => Ok(Conv::Rust),
+            "ArmAapcs" => Ok(Conv::ArmAapcs),
+            "CCmseNonSecureCall" => Ok(Conv::CCmseNonSecureCall),
+            "Msp430Intr" => Ok(Conv::Msp430Intr),
+            "PtxKernel" => Ok(Conv::PtxKernel),
+            "X86Fastcall" => Ok(Conv::X86Fastcall),
+            "X86Intr" => Ok(Conv::X86Intr),
+            "X86Stdcall" => Ok(Conv::X86Stdcall),
+            "X86ThisCall" => Ok(Conv::X86ThisCall),
+            "X86VectorCall" => Ok(Conv::X86VectorCall),
+            "X86_64SysV" => Ok(Conv::X86_64SysV),
+            "X86_64Win64" => Ok(Conv::X86_64Win64),
+            "AmdGpuKernel" => Ok(Conv::AmdGpuKernel),
+            "AvrInterrupt" => Ok(Conv::AvrInterrupt),
+            "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt),
+            _ => Err(format!("'{}' is not a valid value for entry function call convetion.", s)),
+        }
+    }
+}
+
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 mod size_asserts {
index b5d926352122898d2e19a64dfc03715af116437d..75bb76a9de0878afe6f0faa1e65f7adf5f73a580 100644 (file)
@@ -89,3 +89,28 @@ fn to_json(&self) -> Json {
         }
     }
 }
+
+impl ToJson for crate::abi::call::Conv {
+    fn to_json(&self) -> Json {
+        let s = match self {
+            Self::C => "C",
+            Self::Rust => "Rust",
+            Self::RustCold => "RustCold",
+            Self::ArmAapcs => "ArmAapcs",
+            Self::CCmseNonSecureCall => "CCmseNonSecureCall",
+            Self::Msp430Intr => "Msp430Intr",
+            Self::PtxKernel => "PtxKernel",
+            Self::X86Fastcall => "X86Fastcall",
+            Self::X86Intr => "X86Intr",
+            Self::X86Stdcall => "X86Stdcall",
+            Self::X86ThisCall => "X86ThisCall",
+            Self::X86VectorCall => "X86VectorCall",
+            Self::X86_64SysV => "X86_64SysV",
+            Self::X86_64Win64 => "X86_64Win64",
+            Self::AmdGpuKernel => "AmdGpuKernel",
+            Self::AvrInterrupt => "AvrInterrupt",
+            Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt",
+        };
+        Json::String(s.to_owned())
+    }
+}
index 664592b02a12443cc34ebbd6b94f90498de57728..6d936d2cb9ff0463e13ff9d6802a76b38dea4f1c 100644 (file)
@@ -34,6 +34,7 @@
 //! the target's settings, though `target-feature` and `link-args` will *add*
 //! to the list specified by the target, rather than replace.
 
+use crate::abi::call::Conv;
 use crate::abi::Endian;
 use crate::json::{Json, ToJson};
 use crate::spec::abi::{lookup as lookup_abi, Abi};
@@ -1668,6 +1669,14 @@ pub struct TargetOptions {
     /// Whether the target supports stack canary checks. `true` by default,
     /// since this is most common among tier 1 and tier 2 targets.
     pub supports_stack_protector: bool,
+
+    // The name of entry function.
+    // Default value is "main"
+    pub entry_name: StaticCow<str>,
+
+    // The ABI of entry function.
+    // Default value is `Conv::C`, i.e. C call convention
+    pub entry_abi: Conv,
 }
 
 /// Add arguments for the given flavor and also for its "twin" flavors
@@ -1884,6 +1893,8 @@ fn default() -> TargetOptions {
             c_enum_min_bits: 32,
             generate_arange_section: true,
             supports_stack_protector: true,
+            entry_name: "main".into(),
+            entry_abi: Conv::C,
         }
     }
 }
@@ -2404,6 +2415,18 @@ macro_rules! key {
                     }
                 }
             } );
+            ($key_name:ident, Conv) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
+                    match Conv::from_str(s) {
+                        Ok(c) => {
+                            base.$key_name = c;
+                            Some(Ok(()))
+                        }
+                        Err(e) => Some(Err(e))
+                    }
+                })).unwrap_or(Ok(()))
+            } );
         }
 
         if let Some(j) = obj.remove("target-endian") {
@@ -2523,6 +2546,8 @@ macro_rules! key {
         key!(c_enum_min_bits, u64);
         key!(generate_arange_section, bool);
         key!(supports_stack_protector, bool);
+        key!(entry_name);
+        key!(entry_abi, Conv)?;
 
         if base.is_builtin {
             // This can cause unfortunate ICEs later down the line.
@@ -2773,6 +2798,8 @@ macro_rules! target_option_val {
         target_option_val!(c_enum_min_bits);
         target_option_val!(generate_arange_section);
         target_option_val!(supports_stack_protector);
+        target_option_val!(entry_name);
+        target_option_val!(entry_abi);
 
         if let Some(abi) = self.default_adjusted_cabi {
             d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json());
index ae29c9f5617911245a6d733ddab8647f1d45204b..f8346e515d70c57ab0a3e693a65871e4ad4a4c1a 100644 (file)
@@ -125,6 +125,21 @@ pub fn eq<T: ToTrace<'tcx>>(
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
     }
 
+    /// Checks whether `expected` is a subtype of `actual`: `expected <: actual`.
+    pub fn sub<T: ToTrace<'tcx>>(
+        &self,
+        cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        expected: T,
+        actual: T,
+    ) -> Result<(), TypeError<'tcx>> {
+        self.infcx
+            .at(cause, param_env)
+            .sup(expected, actual)
+            .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
+    }
+
+    /// Checks whether `expected` is a supertype of `actual`: `expected :> actual`.
     pub fn sup<T: ToTrace<'tcx>>(
         &self,
         cause: &ObligationCause<'tcx>,
@@ -132,13 +147,10 @@ pub fn sup<T: ToTrace<'tcx>>(
         expected: T,
         actual: T,
     ) -> Result<(), TypeError<'tcx>> {
-        match self.infcx.at(cause, param_env).sup(expected, actual) {
-            Ok(InferOk { obligations, value: () }) => {
-                self.register_obligations(obligations);
-                Ok(())
-            }
-            Err(e) => Err(e),
-        }
+        self.infcx
+            .at(cause, param_env)
+            .sup(expected, actual)
+            .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
     }
 
     pub fn select_where_possible(&self) -> Vec<FulfillmentError<'tcx>> {
index f087afa20bacaabaafa023a54787cb4788820be0..c3547f64b5c9c747e1aa9c7a2804452e95a3f85b 100644 (file)
@@ -22,6 +22,7 @@
     MultiSpan, Style,
 };
 use rustc_hir as hir;
+use rustc_hir::def::Namespace;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::GenericParam;
@@ -34,6 +35,7 @@
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::print::{FmtPrinter, Print};
 use rustc_middle::ty::{
     self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
     TypeVisitable,
@@ -109,7 +111,10 @@ fn report_overflow_error<T>(
         suggest_increasing_limit: bool,
     ) -> !
     where
-        T: fmt::Display + TypeFoldable<'tcx>;
+        T: fmt::Display
+            + TypeFoldable<'tcx>
+            + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
+        <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
 
     fn suggest_new_overflow_limit(&self, err: &mut Diagnostic);
 
@@ -468,15 +473,31 @@ fn report_overflow_error<T>(
         suggest_increasing_limit: bool,
     ) -> !
     where
-        T: fmt::Display + TypeFoldable<'tcx>,
+        T: fmt::Display
+            + TypeFoldable<'tcx>
+            + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
+        <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
     {
         let predicate = self.resolve_vars_if_possible(obligation.predicate.clone());
+        let mut pred_str = predicate.to_string();
+        if pred_str.len() > 50 {
+            // We don't need to save the type to a file, we will be talking about this type already
+            // in a separate note when we explain the obligation, so it will be available that way.
+            pred_str = predicate
+                .print(FmtPrinter::new_with_limit(
+                    self.tcx,
+                    Namespace::TypeNS,
+                    rustc_session::Limit(6),
+                ))
+                .unwrap()
+                .into_buffer();
+        }
         let mut err = struct_span_err!(
             self.tcx.sess,
             obligation.cause.span,
             E0275,
             "overflow evaluating the requirement `{}`",
-            predicate
+            pred_str,
         );
 
         if suggest_increasing_limit {
@@ -532,9 +553,12 @@ fn report_selection_error(
         root_obligation: &PredicateObligation<'tcx>,
         error: &SelectionError<'tcx>,
     ) {
-        self.set_tainted_by_errors();
         let tcx = self.tcx;
         let mut span = obligation.cause.span;
+        // FIXME: statically guarantee this by tainting after the diagnostic is emitted
+        self.set_tainted_by_errors(
+            tcx.sess.delay_span_bug(span, "`report_selection_error` did not emit an error"),
+        );
 
         let mut err = match *error {
             SelectionError::Unimplemented => {
@@ -1705,7 +1729,7 @@ fn type_category(tcx: TyCtxt<'_>, t: Ty<'_>) -> Option<u32> {
                 ty::Bool => Some(0),
                 ty::Char => Some(1),
                 ty::Str => Some(2),
-                ty::Adt(def, _) if tcx.is_diagnostic_item(sym::String, def.did()) => Some(2),
+                ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => Some(2),
                 ty::Int(..)
                 | ty::Uint(..)
                 | ty::Float(..)
@@ -2060,7 +2084,7 @@ fn maybe_report_ambiguity(
                 // check upstream for type errors and don't add the obligations to
                 // begin with in those cases.
                 if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
-                    if !self.is_tainted_by_errors() {
+                    if let None = self.tainted_by_errors() {
                         self.emit_inference_failure_err(
                             body_id,
                             span,
@@ -2115,16 +2139,16 @@ fn maybe_report_ambiguity(
                         if impls.len() > 1 && impls.len() < 5 && has_non_region_infer {
                             self.annotate_source_of_ambiguity(&mut err, &impls, predicate);
                         } else {
-                            if self.is_tainted_by_errors() {
-                                err.delay_as_bug();
+                            if self.tainted_by_errors().is_some() {
+                                err.cancel();
                                 return;
                             }
                             err.note(&format!("cannot satisfy `{}`", predicate));
                         }
                     }
                     _ => {
-                        if self.is_tainted_by_errors() {
-                            err.delay_as_bug();
+                        if self.tainted_by_errors().is_some() {
+                            err.cancel();
                             return;
                         }
                         err.note(&format!("cannot satisfy `{}`", predicate));
@@ -2226,7 +2250,7 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
                         ] = path.segments
                         && data.trait_ref.def_id == *trait_id
                         && self.tcx.trait_of_item(*item_id) == Some(*trait_id)
-                        && !self.is_tainted_by_errors()
+                        && let None = self.tainted_by_errors()
                     {
                         let (verb, noun) = match self.tcx.associated_item(item_id).kind {
                             ty::AssocKind::Const => ("refer to the", "constant"),
@@ -2295,7 +2319,7 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
                 // with error messages.
                 if arg.references_error()
                     || self.tcx.sess.has_errors().is_some()
-                    || self.is_tainted_by_errors()
+                    || self.tainted_by_errors().is_some()
                 {
                     return;
                 }
@@ -2306,7 +2330,7 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
             ty::PredicateKind::Subtype(data) => {
                 if data.references_error()
                     || self.tcx.sess.has_errors().is_some()
-                    || self.is_tainted_by_errors()
+                    || self.tainted_by_errors().is_some()
                 {
                     // no need to overload user in such cases
                     return;
@@ -2317,7 +2341,7 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
                 self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true)
             }
             ty::PredicateKind::Projection(data) => {
-                if predicate.references_error() || self.is_tainted_by_errors() {
+                if predicate.references_error() || self.tainted_by_errors().is_some() {
                     return;
                 }
                 let subst = data
@@ -2351,7 +2375,7 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
             }
 
             ty::PredicateKind::ConstEvaluatable(data) => {
-                if predicate.references_error() || self.is_tainted_by_errors() {
+                if predicate.references_error() || self.tainted_by_errors().is_some() {
                     return;
                 }
                 let subst = data.walk().find(|g| g.is_non_region_infer());
@@ -2378,7 +2402,7 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
                 }
             }
             _ => {
-                if self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() {
+                if self.tcx.sess.has_errors().is_some() || self.tainted_by_errors().is_some() {
                     return;
                 }
                 let mut err = struct_span_err!(
@@ -2422,7 +2446,7 @@ fn annotate_source_of_ambiguity(
         post.sort();
         post.dedup();
 
-        if self.is_tainted_by_errors()
+        if self.tainted_by_errors().is_some()
             && (crate_names.len() == 1
                 && spans.len() == 0
                 && ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str())
index b8609077036f47286c5fcc3e42a6b4e5374f7859..757977ac5d508774849861a8050d0b084f3da192 100644 (file)
@@ -2733,9 +2733,10 @@ fn note_obligation_cause_code<T>(
                     self.resolve_vars_if_possible(data.derived.parent_trait_pred);
                 parent_trait_pred.remap_constness_diag(param_env);
                 let parent_def_id = parent_trait_pred.def_id();
+                let (self_ty, file) =
+                    self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());
                 let msg = format!(
-                    "required for `{}` to implement `{}`",
-                    parent_trait_pred.skip_binder().self_ty(),
+                    "required for `{self_ty}` to implement `{}`",
                     parent_trait_pred.print_modifiers_and_trait_path()
                 );
                 let mut is_auto_trait = false;
@@ -2764,6 +2765,12 @@ fn note_obligation_cause_code<T>(
                     _ => err.note(&msg),
                 };
 
+                if let Some(file) = file {
+                    err.note(&format!(
+                        "the full type name has been written to '{}'",
+                        file.display(),
+                    ));
+                }
                 let mut parent_predicate = parent_trait_pred;
                 let mut data = &data.derived;
                 let mut count = 0;
@@ -2804,11 +2811,18 @@ fn note_obligation_cause_code<T>(
                         count,
                         pluralize!(count)
                     ));
+                    let (self_ty, file) =
+                        self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());
                     err.note(&format!(
-                        "required for `{}` to implement `{}`",
-                        parent_trait_pred.skip_binder().self_ty(),
+                        "required for `{self_ty}` to implement `{}`",
                         parent_trait_pred.print_modifiers_and_trait_path()
                     ));
+                    if let Some(file) = file {
+                        err.note(&format!(
+                            "the full type name has been written to '{}'",
+                            file.display(),
+                        ));
+                    }
                 }
                 // #74711: avoid a stack overflow
                 ensure_sufficient_stack(|| {
index eaca3eaef0c1fa5f6c2a769a4573283398cc31ae..9745e0137ee9f63f0dc95218d4579ac2d22fd3ad 100644 (file)
@@ -375,6 +375,7 @@ fn object_safety_violation_for_method(
         let span = match (&v, node) {
             (MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span,
             (MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span,
+            (MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span,
             (MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
                 node.fn_decl().map_or(method.ident(tcx).span, |decl| decl.output.span())
             }
@@ -437,8 +438,8 @@ fn virtual_call_violation_for_method<'tcx>(
     if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
         return Some(MethodViolationCode::ReferencesSelfOutput);
     }
-    if contains_illegal_impl_trait_in_trait(tcx, sig.output()) {
-        return Some(MethodViolationCode::ReferencesImplTraitInTrait);
+    if let Some(code) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) {
+        return Some(code);
     }
 
     // We can't monomorphize things like `fn foo<A>(...)`.
@@ -864,16 +865,24 @@ fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
 
 pub fn contains_illegal_impl_trait_in_trait<'tcx>(
     tcx: TyCtxt<'tcx>,
+    fn_def_id: DefId,
     ty: ty::Binder<'tcx, Ty<'tcx>>,
-) -> bool {
+) -> Option<MethodViolationCode> {
+    // This would be caught below, but rendering the error as a separate
+    // `async-specific` message is better.
+    if tcx.asyncness(fn_def_id).is_async() {
+        return Some(MethodViolationCode::AsyncFn);
+    }
+
     // FIXME(RPITIT): Perhaps we should use a visitor here?
-    ty.skip_binder().walk().any(|arg| {
+    ty.skip_binder().walk().find_map(|arg| {
         if let ty::GenericArgKind::Type(ty) = arg.unpack()
             && let ty::Projection(proj) = ty.kind()
+            && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
         {
-            tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
+            Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.item_def_id)))
         } else {
-            false
+            None
         }
     })
 }
index ede6cd607b7fe82d580ae21e34b0c2f6b9f188e0..528b98cf4a1c0915ff33a1471c3ce0fa1019adb1 100644 (file)
@@ -508,7 +508,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
             // This is really important. While we *can* handle this, this has
             // severe performance implications for large opaque types with
             // late-bound regions. See `issue-88862` benchmark.
-            ty::Opaque(def_id, substs) => {
+            ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                 // Only normalize `impl Trait` outside of type inference, usually in codegen.
                 match self.param_env.reveal() {
                     Reveal::UserFacing => ty.super_fold_with(self),
index f5c98558a25256cdb288b89b00c32f3844044775..a875ea1578dcb92d879b7f8ce80751ee13e97c5d 100644 (file)
@@ -198,7 +198,7 @@ fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
             // This is really important. While we *can* handle this, this has
             // severe performance implications for large opaque types with
             // late-bound regions. See `issue-88862` benchmark.
-            ty::Opaque(def_id, substs) => {
+            ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                 // Only normalize `impl Trait` outside of type inference, usually in codegen.
                 match self.param_env.reveal() {
                     Reveal::UserFacing => ty.try_super_fold_with(self),
index 3995ea58db16cad7cec3749f3f0787792e1eaa0f..8183f34bb3c933e5274d9f8cd3858b15c3ea7dd2 100644 (file)
@@ -304,6 +304,8 @@ pub(super) fn assemble_candidates<'o>(
                 self.assemble_candidates_for_transmutability(obligation, &mut candidates);
             } else if lang_items.tuple_trait() == Some(def_id) {
                 self.assemble_candidate_for_tuple(obligation, &mut candidates);
+            } else if lang_items.pointer_sized() == Some(def_id) {
+                self.assemble_candidate_for_ptr_sized(obligation, &mut candidates);
             } else {
                 if lang_items.clone_trait() == Some(def_id) {
                     // Same builtin conditions as `Copy`, i.e., every type which has builtin support
@@ -780,7 +782,9 @@ fn assemble_candidates_for_unsizing(
 
         match (source.kind(), target.kind()) {
             // Trait+Kx+'a -> Trait+Ky+'b (upcasts).
-            (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
+            (&ty::Dynamic(ref data_a, _, dyn_a), &ty::Dynamic(ref data_b, _, dyn_b))
+                if dyn_a == dyn_b =>
+            {
                 // Upcast coercions permit several things:
                 //
                 // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
@@ -841,7 +845,7 @@ fn assemble_candidates_for_unsizing(
             }
 
             // `T` -> `Trait`
-            (_, &ty::Dynamic(..)) => {
+            (_, &ty::Dynamic(_, _, ty::Dyn)) => {
                 candidates.vec.push(BuiltinUnsizeCandidate);
             }
 
@@ -1047,4 +1051,30 @@ fn assemble_candidate_for_tuple(
             | ty::Placeholder(_) => {}
         }
     }
+
+    fn assemble_candidate_for_ptr_sized(
+        &mut self,
+        obligation: &TraitObligation<'tcx>,
+        candidates: &mut SelectionCandidateSet<'tcx>,
+    ) {
+        // The regions of a type don't affect the size of the type
+        let self_ty = self
+            .tcx()
+            .erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate.self_ty()));
+
+        // But if there are inference variables, we have to wait until it's resolved.
+        if self_ty.has_non_region_infer() {
+            candidates.ambiguous = true;
+            return;
+        }
+
+        let usize_layout =
+            self.tcx().layout_of(ty::ParamEnv::empty().and(self.tcx().types.usize)).unwrap().layout;
+        if let Ok(layout) = self.tcx().layout_of(obligation.param_env.and(self_ty))
+            && layout.layout.size() == usize_layout.size()
+            && layout.layout.align().abi == usize_layout.align().abi
+        {
+            candidates.vec.push(BuiltinCandidate { has_nested: false });
+        }
+    }
 }
index 9d43f72b85f15dbaf717e540ad4a16e8792d2d15..a496aed38ac1772ffd00fe25742ed4bbf85ac46c 100644 (file)
@@ -912,7 +912,9 @@ fn confirm_builtin_unsize_candidate(
         let mut nested = vec![];
         match (source.kind(), target.kind()) {
             // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
-            (&ty::Dynamic(ref data_a, r_a, ty::Dyn), &ty::Dynamic(ref data_b, r_b, ty::Dyn)) => {
+            (&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b))
+                if dyn_a == dyn_b =>
+            {
                 // See `assemble_candidates_for_unsizing` for more info.
                 // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
                 let iter = data_a
@@ -931,7 +933,7 @@ fn confirm_builtin_unsize_candidate(
                             .map(ty::Binder::dummy),
                     );
                 let existential_predicates = tcx.mk_poly_existential_predicates(iter);
-                let source_trait = tcx.mk_dynamic(existential_predicates, r_b, ty::Dyn);
+                let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a);
 
                 // Require that the traits involved in this upcast are **equal**;
                 // only the **lifetime bound** is changed.
@@ -1140,7 +1142,7 @@ fn confirm_builtin_unsize_candidate(
                 }));
             }
 
-            _ => bug!(),
+            _ => bug!("source: {source}, target: {target}"),
         };
 
         Ok(ImplSourceBuiltinData { nested })
index c369c5de52bb1a0e992f2610054412d914a5ea0a..a9314b1b85e668944ab4700a1e84b640baa01610 100644 (file)
@@ -33,7 +33,7 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_errors::{Diagnostic, ErrorGuaranteed};
+use rustc_errors::Diagnostic;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::LateBoundRegionConversionTime;
@@ -42,6 +42,7 @@
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::fold::BottomUpFolder;
+use rustc_middle::ty::print::{FmtPrinter, Print};
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::SubstsRef;
 use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
@@ -1081,18 +1082,22 @@ fn add_depth<T: 'cx, I: Iterator<Item = &'cx mut Obligation<'tcx, T>>>(
         it.for_each(|o| o.recursion_depth = cmp::max(min_depth, o.recursion_depth) + 1);
     }
 
-    fn check_recursion_depth<T: Display + TypeFoldable<'tcx>>(
+    fn check_recursion_depth<T>(
         &self,
         depth: usize,
         error_obligation: &Obligation<'tcx, T>,
-    ) -> Result<(), OverflowError> {
+    ) -> Result<(), OverflowError>
+    where
+        T: fmt::Display
+            + TypeFoldable<'tcx>
+            + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
+        <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
+    {
         if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
             match self.query_mode {
                 TraitQueryMode::Standard => {
-                    if self.infcx.is_tainted_by_errors() {
-                        return Err(OverflowError::Error(
-                            ErrorGuaranteed::unchecked_claim_error_was_emitted(),
-                        ));
+                    if let Some(e) = self.infcx.tainted_by_errors() {
+                        return Err(OverflowError::Error(e));
                     }
                     self.infcx.err_ctxt().report_overflow_error(error_obligation, true);
                 }
@@ -1109,11 +1114,17 @@ fn check_recursion_depth<T: Display + TypeFoldable<'tcx>>(
     /// The weird return type of this function allows it to be used with the `try` (`?`)
     /// operator within certain functions.
     #[inline(always)]
-    fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V: Display + TypeFoldable<'tcx>>(
+    fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V>(
         &self,
         obligation: &Obligation<'tcx, T>,
         error_obligation: &Obligation<'tcx, V>,
-    ) -> Result<(), OverflowError> {
+    ) -> Result<(), OverflowError>
+    where
+        V: fmt::Display
+            + TypeFoldable<'tcx>
+            + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
+        <V as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
+    {
         self.check_recursion_depth(obligation.recursion_depth, error_obligation)
     }
 
index 2da64d73d34ac8de76e97e34a6aa2acfc0c150b3..f1835d317e841be4b8c5808ace9d9ca28465df06 100644 (file)
@@ -34,7 +34,9 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq +
             // We don't care about the `obligations`; they are
             // always only region relations, and we are about to
             // erase those anyway:
-            debug_assert_eq!(
+            // This has been seen to fail in RL, so making it a non-debug assertion to better catch
+            // those cases.
+            assert_eq!(
                 normalized_obligations.iter().find(|p| not_outlives_predicate(p.predicate)),
                 None,
             );
index 2a57dad89a77082633f71606729f121e5d087d7d..537fe22a4be72b3bd1f35eb1c51e124a0ca08003 100644 (file)
@@ -10,7 +10,7 @@
 use core::cmp::{self, Ordering};
 use core::fmt;
 use core::hash::{Hash, Hasher};
-use core::iter::{repeat_with, FromIterator};
+use core::iter::{repeat_n, repeat_with, FromIterator};
 use core::marker::PhantomData;
 use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties};
 use core::ops::{Index, IndexMut, Range, RangeBounds};
@@ -2833,7 +2833,12 @@ impl<T: Clone, A: Allocator> VecDeque<T, A> {
     /// ```
     #[stable(feature = "deque_extras", since = "1.16.0")]
     pub fn resize(&mut self, new_len: usize, value: T) {
-        self.resize_with(new_len, || value.clone());
+        if new_len > self.len() {
+            let extra = new_len - self.len();
+            self.extend(repeat_n(value, extra))
+        } else {
+            self.truncate(new_len);
+        }
     }
 }
 
index 008926666c136d5f04fc2a8104d2bbd56e195fda..5e13547abcb70f2dc616e94e0afe3decf06b22ea 100644 (file)
 #![feature(inplace_iteration)]
 #![feature(iter_advance_by)]
 #![feature(iter_next_chunk)]
+#![feature(iter_repeat_n)]
 #![feature(layout_for_ptr)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_uninit_array)]
index f3cbfe27b3eed620adf88462ecba8e7c0dfdf80e..38e31b1802a42f0ee0dcf2f10cb725ba3693e624 100644 (file)
@@ -1091,10 +1091,11 @@ pub fn get_mut(this: &mut Self) -> Option<&mut T> {
     ///
     /// # Safety
     ///
-    /// Any other `Rc` or [`Weak`] pointers to the same allocation must not be dereferenced
-    /// for the duration of the returned borrow.
-    /// This is trivially the case if no such pointers exist,
-    /// for example immediately after `Rc::new`.
+    /// If any other `Rc` or [`Weak`] pointers to the same allocation exist, then
+    /// they must be must not be dereferenced or have active borrows for the duration
+    /// of the returned borrow, and their inner type must be exactly the same as the
+    /// inner type of this Rc (including lifetimes). This is trivially the case if no
+    /// such pointers exist, for example immediately after `Rc::new`.
     ///
     /// # Examples
     ///
@@ -1109,6 +1110,38 @@ pub fn get_mut(this: &mut Self) -> Option<&mut T> {
     /// }
     /// assert_eq!(*x, "foo");
     /// ```
+    /// Other `Rc` pointers to the same allocation must be to the same type.
+    /// ```no_run
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let x: Rc<str> = Rc::from("Hello, world!");
+    /// let mut y: Rc<[u8]> = x.clone().into();
+    /// unsafe {
+    ///     // this is Undefined Behavior, because x's inner type is str, not [u8]
+    ///     Rc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
+    /// }
+    /// println!("{}", &*x); // Invalid UTF-8 in a str
+    /// ```
+    /// Other `Rc` pointers to the same allocation must be to the exact same type, including lifetimes.
+    /// ```no_run
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let x: Rc<&str> = Rc::new("Hello, world!");
+    /// {
+    ///     let s = String::from("Oh, no!");
+    ///     let mut y: Rc<&str> = x.clone().into();
+    ///     unsafe {
+    ///         // this is Undefined Behavior, because x's inner type
+    ///         // is &'long str, not &'short str
+    ///         *Rc::get_mut_unchecked(&mut y) = &s;
+    ///     }
+    /// }
+    /// println!("{}", &*x); // Use-after-free
+    /// ```
     #[inline]
     #[unstable(feature = "get_mut_unchecked", issue = "63292")]
     pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
@@ -1441,48 +1474,6 @@ unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> {
         }
     }
 
-    /// Create an `Rc<[T]>` by reusing the underlying memory
-    /// of a `Vec<T>`. This will return the vector if the existing allocation
-    /// is not large enough.
-    #[cfg(not(no_global_oom_handling))]
-    fn try_from_vec_in_place(mut v: Vec<T>) -> Result<Rc<[T]>, Vec<T>> {
-        let layout_elements = Layout::array::<T>(v.len()).unwrap();
-        let layout_allocation = Layout::array::<T>(v.capacity()).unwrap();
-        let layout_rcbox = rcbox_layout_for_value_layout(layout_elements);
-        let mut ptr = NonNull::new(v.as_mut_ptr()).expect("`Vec<T>` stores `NonNull<T>`");
-        if layout_rcbox.size() > layout_allocation.size()
-            || layout_rcbox.align() > layout_allocation.align()
-        {
-            // Can't fit - calling `grow` would involve `realloc`
-            // (which copies the elements), followed by copying again.
-            return Err(v);
-        }
-        if layout_rcbox.size() < layout_allocation.size()
-            || layout_rcbox.align() < layout_allocation.align()
-        {
-            // We need to shrink the allocation so that it fits
-            // https://doc.rust-lang.org/nightly/std/alloc/trait.Allocator.html#memory-fitting
-            // SAFETY:
-            // - Vec allocates by requesting `Layout::array::<T>(capacity)`, so this capacity matches
-            // - `layout_rcbox` is smaller
-            // If this fails, the ownership has not been transferred
-            if let Ok(p) = unsafe { Global.shrink(ptr.cast(), layout_allocation, layout_rcbox) } {
-                ptr = p.cast();
-            } else {
-                return Err(v);
-            }
-        }
-        // Make sure the vec's memory isn't deallocated now
-        let v = mem::ManuallyDrop::new(v);
-        let ptr: *mut RcBox<[T]> = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), v.len()) as _;
-        unsafe {
-            ptr::copy(ptr.cast::<T>(), &mut (*ptr).value as *mut [T] as *mut T, v.len());
-            ptr::write(&mut (*ptr).strong, Cell::new(1));
-            ptr::write(&mut (*ptr).weak, Cell::new(1));
-            Ok(Self::from_ptr(ptr))
-        }
-    }
-
     /// Constructs an `Rc<[T]>` from an iterator known to be of a certain size.
     ///
     /// Behavior is undefined should the size be wrong.
@@ -2008,17 +1999,12 @@ impl<T> From<Vec<T>> for Rc<[T]> {
     /// assert_eq!(vec![1, 2, 3], *shared);
     /// ```
     #[inline]
-    fn from(v: Vec<T>) -> Rc<[T]> {
-        match Rc::try_from_vec_in_place(v) {
-            Ok(rc) => rc,
-            Err(mut v) => {
-                unsafe {
-                    let rc = Rc::copy_from_slice(&v);
-                    // Allow the Vec to free its memory, but not destroy its contents
-                    v.set_len(0);
-                    rc
-                }
-            }
+    fn from(mut v: Vec<T>) -> Rc<[T]> {
+        unsafe {
+            let rc = Rc::copy_from_slice(&v);
+            // Allow the Vec to free its memory, but not destroy its contents
+            v.set_len(0);
+            rc
         }
     }
 }
index a5e7bf2a1a9f34ef3adfed7023bbaa6dece57585..1b61ede3476c336c3112867a32253dc86ee219ea 100644 (file)
@@ -458,7 +458,7 @@ pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
         hack::into_vec(self)
     }
 
-    /// Creates a vector by repeating a slice `n` times.
+    /// Creates a vector by copying a slice `n` times.
     ///
     /// # Panics
     ///
index c9ba8921f6ecc939ad182bb7db3c078e187ba5e6..7a8e6f088f3acc5f3c63b1695e4b6d9907d2ec5c 100644 (file)
 /// [`Deref`]: core::ops::Deref "ops::Deref"
 /// [`as_str()`]: String::as_str
 #[derive(PartialOrd, Eq, Ord)]
-#[cfg_attr(not(test), rustc_diagnostic_item = "String")]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(all(not(bootstrap), not(test)), lang = "String")]
 pub struct String {
     vec: Vec<u8>,
 }
index 37e07eb5998b332ffdeb54f4fe675557800e289d..f7dc4d1094ca3f8b1a0d160435ba6aa2653fa828 100644 (file)
@@ -1261,49 +1261,6 @@ unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> {
         }
     }
 
-    /// Create an `Arc<[T]>` by reusing the underlying memory
-    /// of a `Vec<T>`. This will return the vector if the existing allocation
-    /// is not large enough.
-    #[cfg(not(no_global_oom_handling))]
-    fn try_from_vec_in_place(mut v: Vec<T>) -> Result<Arc<[T]>, Vec<T>> {
-        let layout_elements = Layout::array::<T>(v.len()).unwrap();
-        let layout_allocation = Layout::array::<T>(v.capacity()).unwrap();
-        let layout_arcinner = arcinner_layout_for_value_layout(layout_elements);
-        let mut ptr = NonNull::new(v.as_mut_ptr()).expect("`Vec<T>` stores `NonNull<T>`");
-        if layout_arcinner.size() > layout_allocation.size()
-            || layout_arcinner.align() > layout_allocation.align()
-        {
-            // Can't fit - calling `grow` would involve `realloc`
-            // (which copies the elements), followed by copying again.
-            return Err(v);
-        }
-        if layout_arcinner.size() < layout_allocation.size()
-            || layout_arcinner.align() < layout_allocation.align()
-        {
-            // We need to shrink the allocation so that it fits
-            // https://doc.rust-lang.org/nightly/std/alloc/trait.Allocator.html#memory-fitting
-            // SAFETY:
-            // - Vec allocates by requesting `Layout::array::<T>(capacity)`, so this capacity matches
-            // - `layout_arcinner` is smaller
-            // If this fails, the ownership has not been transferred
-            if let Ok(p) = unsafe { Global.shrink(ptr.cast(), layout_allocation, layout_arcinner) }
-            {
-                ptr = p.cast();
-            } else {
-                return Err(v);
-            }
-        }
-        // Make sure the vec's memory isn't deallocated now
-        let v = mem::ManuallyDrop::new(v);
-        let ptr: *mut ArcInner<[T]> = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), v.len()) as _;
-        unsafe {
-            ptr::copy(ptr.cast::<T>(), &mut (*ptr).data as *mut [T] as *mut T, v.len());
-            ptr::write(&mut (*ptr).strong, atomic::AtomicUsize::new(1));
-            ptr::write(&mut (*ptr).weak, atomic::AtomicUsize::new(1));
-            Ok(Self::from_ptr(ptr))
-        }
-    }
-
     /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size.
     ///
     /// Behavior is undefined should the size be wrong.
@@ -1630,10 +1587,11 @@ pub fn get_mut(this: &mut Self) -> Option<&mut T> {
     ///
     /// # Safety
     ///
-    /// Any other `Arc` or [`Weak`] pointers to the same allocation must not be dereferenced
-    /// for the duration of the returned borrow.
-    /// This is trivially the case if no such pointers exist,
-    /// for example immediately after `Arc::new`.
+    /// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then
+    /// they must be must not be dereferenced or have active borrows for the duration
+    /// of the returned borrow, and their inner type must be exactly the same as the
+    /// inner type of this Rc (including lifetimes). This is trivially the case if no
+    /// such pointers exist, for example immediately after `Arc::new`.
     ///
     /// # Examples
     ///
@@ -1648,6 +1606,38 @@ pub fn get_mut(this: &mut Self) -> Option<&mut T> {
     /// }
     /// assert_eq!(*x, "foo");
     /// ```
+    /// Other `Arc` pointers to the same allocation must be to the same type.
+    /// ```no_run
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let x: Arc<str> = Arc::from("Hello, world!");
+    /// let mut y: Arc<[u8]> = x.clone().into();
+    /// unsafe {
+    ///     // this is Undefined Behavior, because x's inner type is str, not [u8]
+    ///     Arc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
+    /// }
+    /// println!("{}", &*x); // Invalid UTF-8 in a str
+    /// ```
+    /// Other `Arc` pointers to the same allocation must be to the exact same type, including lifetimes.
+    /// ```no_run
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let x: Arc<&str> = Arc::new("Hello, world!");
+    /// {
+    ///     let s = String::from("Oh, no!");
+    ///     let mut y: Arc<&str> = x.clone().into();
+    ///     unsafe {
+    ///         // this is Undefined Behavior, because x's inner type
+    ///         // is &'long str, not &'short str
+    ///         *Arc::get_mut_unchecked(&mut y) = &s;
+    ///     }
+    /// }
+    /// println!("{}", &*x); // Use-after-free
+    /// ```
     #[inline]
     #[unstable(feature = "get_mut_unchecked", issue = "63292")]
     pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
@@ -2615,17 +2605,12 @@ impl<T> From<Vec<T>> for Arc<[T]> {
     /// assert_eq!(&[1, 2, 3], &shared[..]);
     /// ```
     #[inline]
-    fn from(v: Vec<T>) -> Arc<[T]> {
-        match Arc::try_from_vec_in_place(v) {
-            Ok(rc) => rc,
-            Err(mut v) => {
-                unsafe {
-                    let rc = Arc::copy_from_slice(&v);
-                    // Allow the Vec to free its memory, but not destroy its contents
-                    v.set_len(0);
-                    rc
-                }
-            }
+    fn from(mut v: Vec<T>) -> Arc<[T]> {
+        unsafe {
+            let rc = Arc::copy_from_slice(&v);
+            // Allow the Vec to free its memory, but not destroy its contents
+            v.set_len(0);
+            rc
         }
     }
 }
index eb379e4d6a10f9edfba773e77377f3cd4169a289..ce40b5c9b0a0d3a5948635c131dc1b353adbbcfb 100644 (file)
@@ -210,18 +210,3 @@ fn hmm<'a>(val: &'a mut Weak<&'a str>) -> Weak<&'a str> {
     // `val` dropped here while still borrowed
     // borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::sync::Weak`
 }
-
-#[test]
-fn arc_from_vec_opt() {
-    let mut v = Vec::with_capacity(64);
-    v.push(0usize);
-    let addr = v.as_ptr().cast::<u8>();
-    let arc: Arc<[_]> = v.into();
-    unsafe {
-        assert_eq!(
-            arc.as_ptr().cast::<u8>().offset_from(addr),
-            (std::mem::size_of::<usize>() * 2) as isize,
-            "Vector allocation not reused"
-        );
-    }
-}
index 1d5f3c52006487bb9517b4fafec882965868c117..efb39a609665b33ad2e6b9b43a75533a98f1feb5 100644 (file)
@@ -206,18 +206,3 @@ fn hmm<'a>(val: &'a mut Weak<&'a str>) -> Weak<&'a str> {
     // `val` dropped here while still borrowed
     // borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::rc::Weak`
 }
-
-#[test]
-fn rc_from_vec_opt() {
-    let mut v = Vec::with_capacity(64);
-    v.push(0usize);
-    let addr = v.as_ptr().cast::<u8>();
-    let rc: Rc<[_]> = v.into();
-    unsafe {
-        assert_eq!(
-            rc.as_ptr().cast::<u8>().offset_from(addr),
-            (std::mem::size_of::<usize>() * 2) as isize,
-            "Vector allocation not reused"
-        );
-    }
-}
index 019d73c0b16bbb03b43281aad5d0a56983cf9e9a..c1b9e7af9d857f43bf77cd141ee404ebc46dc902 100644 (file)
@@ -1727,3 +1727,11 @@ fn test_from_zero_sized_vec() {
     let queue = VecDeque::from(v);
     assert_eq!(queue.len(), 100);
 }
+
+#[test]
+fn test_resize_keeps_reserved_space_from_item() {
+    let v = Vec::<i32>::with_capacity(1234);
+    let mut d = VecDeque::new();
+    d.resize(1, v);
+    assert_eq!(d[0].capacity(), 1234);
+}
index 6756eecd0e0f8ca6bc446b899595a56de3ef6b1a..1d80b8bf9ec761ef815188c91b12eec841118b5b 100644 (file)
@@ -208,9 +208,11 @@ unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
     ///
     /// If this returns a non-null pointer, then ownership of the memory block
     /// referenced by `ptr` has been transferred to this allocator.
-    /// The memory may or may not have been deallocated, and should be
-    /// considered unusable. The new memory block is allocated with `layout`,
-    /// but with the `size` updated to `new_size`. This new layout should be
+    /// Any access to the old `ptr` is Undefined Behavior, even if the
+    /// allocation remained in-place. The newly returned pointer is the only valid pointer
+    /// for accessing this memory now.
+    /// The new memory block is allocated with `layout`,
+    /// but with the `size` updated to `new_size`. This new layout must be
     /// used when deallocating the new memory block with `dealloc`. The range
     /// `0..min(layout.size(), new_size)` of the new memory block is
     /// guaranteed to have the same values as the original block.
index a4bf6a853a65022bc0f9863e2d351838c69ee8e9..a6082455fac8d1d6f29b1fa029502dab87914060 100644 (file)
@@ -169,8 +169,9 @@ fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
     /// this, the allocator may extend the allocation referenced by `ptr` to fit the new layout.
     ///
     /// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
-    /// transferred to this allocator. The memory may or may not have been freed, and should be
-    /// considered unusable.
+    /// transferred to this allocator. Any access to the old `ptr` is Undefined Behavior, even if the
+    /// allocation was grown in-place. The newly returned pointer is the only valid pointer
+    /// for accessing this memory now.
     ///
     /// If this method returns `Err`, then ownership of the memory block has not been transferred to
     /// this allocator, and the contents of the memory block are unaltered.
@@ -295,8 +296,9 @@ unsafe fn grow_zeroed(
     /// this, the allocator may shrink the allocation referenced by `ptr` to fit the new layout.
     ///
     /// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
-    /// transferred to this allocator. The memory may or may not have been freed, and should be
-    /// considered unusable.
+    /// transferred to this allocator. Any access to the old `ptr` is Undefined Behavior, even if the
+    /// allocation was shrunk in-place. The newly returned pointer is the only valid pointer
+    /// for accessing this memory now.
     ///
     /// If this method returns `Err`, then ownership of the memory block has not been transferred to
     /// this allocator, and the contents of the memory block are unaltered.
index 7844be5f783a9d46d933cd1bbfc147f32253090f..b355d94ce4976697ff0226398b040c248f97ee38 100644 (file)
@@ -4,6 +4,10 @@
 
 /// A value which is initialized on the first access.
 ///
+/// For a thread-safe version of this struct, see [`std::sync::LazyLock`].
+///
+/// [`std::sync::LazyLock`]: ../../std/sync/struct.LazyLock.html
+///
 /// # Examples
 ///
 /// ```
index 3c39394dd8c8e7007200f4c063e523d72ca87368..8c01643c7ac177a4d0e5027536b605a74e699278 100644 (file)
@@ -4,8 +4,14 @@
 
 /// A cell which can be written to only once.
 ///
-/// Unlike `RefCell`, a `OnceCell` only provides shared `&T` references to its value.
-/// Unlike `Cell`, a `OnceCell` doesn't require copying or replacing the value to access it.
+/// Unlike [`RefCell`], a `OnceCell` only provides shared `&T` references to its value.
+/// Unlike [`Cell`], a `OnceCell` doesn't require copying or replacing the value to access it.
+///
+/// For a thread-safe version of this struct, see [`std::sync::OnceLock`].
+///
+/// [`RefCell`]: crate::cell::RefCell
+/// [`Cell`]: crate::cell::Cell
+/// [`std::sync::OnceLock`]: ../../std/sync/struct.OnceLock.html
 ///
 /// # Examples
 ///
index 2adc968bd469276929609a7a50ceba0e544a1103..48b6177434bcbea9d6b7f20f24f70b4809b025e5 100644 (file)
@@ -510,7 +510,7 @@ impl<'a> Arguments<'a> {
     /// assert_eq!(format_args!("{}", 1).as_str(), None);
     /// ```
     #[stable(feature = "fmt_as_str", since = "1.52.0")]
-    #[rustc_const_unstable(feature = "const_arguments_as_str", issue = "none")]
+    #[rustc_const_unstable(feature = "const_arguments_as_str", issue = "103900")]
     #[must_use]
     #[inline]
     pub const fn as_str(&self) -> Option<&'static str> {
index 819ccf5a3e9e70ed7a63165fcffbb70cb67acc3b..7ed7d767f2fb5b42955ac6c80cccaba8e9003885 100644 (file)
@@ -1851,6 +1851,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
     ///
     /// This intrinsic does not have a stable counterpart.
+    #[rustc_const_unstable(feature = "const_exact_div", issue = "none")]
     pub fn exact_div<T: Copy>(x: T, y: T) -> T;
 
     /// Performs an unchecked division, resulting in undefined behavior
index ef0f397825b15ebb0c96d17fea966d2201321aae..bb35d50b4bfda2a7c39313d8faa753f8758e713d 100644 (file)
@@ -401,6 +401,8 @@ fn $fold<AAA, FFF>(mut self, init: AAA, mut fold: FFF) -> AAA
 pub use self::sources::{once_with, OnceWith};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::sources::{repeat, Repeat};
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+pub use self::sources::{repeat_n, RepeatN};
 #[stable(feature = "iterator_repeat_with", since = "1.28.0")]
 pub use self::sources::{repeat_with, RepeatWith};
 #[stable(feature = "iter_successors", since = "1.34.0")]
index d34772cd304ffdfef14df26d8dd2ef0eedc253f9..3ec426a3ad9a155cba3489d1ea4a533f124b8be9 100644 (file)
@@ -4,6 +4,7 @@
 mod once;
 mod once_with;
 mod repeat;
+mod repeat_n;
 mod repeat_with;
 mod successors;
 
@@ -16,6 +17,9 @@
 #[stable(feature = "iter_once", since = "1.2.0")]
 pub use self::once::{once, Once};
 
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+pub use self::repeat_n::{repeat_n, RepeatN};
+
 #[stable(feature = "iterator_repeat_with", since = "1.28.0")]
 pub use self::repeat_with::{repeat_with, RepeatWith};
 
diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs
new file mode 100644 (file)
index 0000000..dc69bf4
--- /dev/null
@@ -0,0 +1,195 @@
+use crate::iter::{FusedIterator, TrustedLen};
+use crate::mem::ManuallyDrop;
+
+/// Creates a new iterator that repeats a single element a given number of times.
+///
+/// The `repeat_n()` function repeats a single value exactly `n` times.
+///
+/// This is very similar to using [`repeat()`] with [`Iterator::take()`],
+/// but there are two differences:
+/// - `repeat_n()` can return the original value, rather than always cloning.
+/// - `repeat_n()` produces an [`ExactSizeIterator`].
+///
+/// [`repeat()`]: crate::iter::repeat
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// #![feature(iter_repeat_n)]
+/// use std::iter;
+///
+/// // four of the the number four:
+/// let mut four_fours = iter::repeat_n(4, 4);
+///
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+///
+/// // no more fours
+/// assert_eq!(None, four_fours.next());
+/// ```
+///
+/// For non-`Copy` types,
+///
+/// ```
+/// #![feature(iter_repeat_n)]
+/// use std::iter;
+///
+/// let v: Vec<i32> = Vec::with_capacity(123);
+/// let mut it = iter::repeat_n(v, 5);
+///
+/// for i in 0..4 {
+///     // It starts by cloning things
+///     let cloned = it.next().unwrap();
+///     assert_eq!(cloned.len(), 0);
+///     assert_eq!(cloned.capacity(), 0);
+/// }
+///
+/// // ... but the last item is the original one
+/// let last = it.next().unwrap();
+/// assert_eq!(last.len(), 0);
+/// assert_eq!(last.capacity(), 123);
+///
+/// // ... and now we're done
+/// assert_eq!(None, it.next());
+/// ```
+#[inline]
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+#[doc(hidden)] // waiting on ACP#120 to decide whether to expose publicly
+pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
+    let mut element = ManuallyDrop::new(element);
+
+    if count == 0 {
+        // SAFETY: we definitely haven't dropped it yet, since we only just got
+        // passed it in, and because the count is zero the instance we're about
+        // to create won't drop it, so to avoid leaking we need to now.
+        unsafe { ManuallyDrop::drop(&mut element) };
+    }
+
+    RepeatN { element, count }
+}
+
+/// An iterator that repeats an element an exact number of times.
+///
+/// This `struct` is created by the [`repeat_n()`] function.
+/// See its documentation for more.
+#[derive(Clone, Debug)]
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+#[doc(hidden)] // waiting on ACP#120 to decide whether to expose publicly
+pub struct RepeatN<A> {
+    count: usize,
+    // Invariant: has been dropped iff count == 0.
+    element: ManuallyDrop<A>,
+}
+
+impl<A> RepeatN<A> {
+    /// If we haven't already dropped the element, return it in an option.
+    ///
+    /// Clears the count so it won't be dropped again later.
+    #[inline]
+    fn take_element(&mut self) -> Option<A> {
+        if self.count > 0 {
+            self.count = 0;
+            // SAFETY: We just set count to zero so it won't be dropped again,
+            // and it used to be non-zero so it hasn't already been dropped.
+            unsafe { Some(ManuallyDrop::take(&mut self.element)) }
+        } else {
+            None
+        }
+    }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A> Drop for RepeatN<A> {
+    fn drop(&mut self) {
+        self.take_element();
+    }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A: Clone> Iterator for RepeatN<A> {
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        if self.count == 0 {
+            return None;
+        }
+
+        self.count -= 1;
+        Some(if self.count == 0 {
+            // SAFETY: the check above ensured that the count used to be non-zero,
+            // so element hasn't been dropped yet, and we just lowered the count to
+            // zero so it won't be dropped later, and thus it's okay to take it here.
+            unsafe { ManuallyDrop::take(&mut self.element) }
+        } else {
+            A::clone(&mut self.element)
+        })
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = self.len();
+        (len, Some(len))
+    }
+
+    #[inline]
+    fn advance_by(&mut self, skip: usize) -> Result<(), usize> {
+        let len = self.count;
+
+        if skip >= len {
+            self.take_element();
+        }
+
+        if skip > len {
+            Err(len)
+        } else {
+            self.count = len - skip;
+            Ok(())
+        }
+    }
+
+    #[inline]
+    fn last(mut self) -> Option<A> {
+        self.take_element()
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.len()
+    }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A: Clone> ExactSizeIterator for RepeatN<A> {
+    fn len(&self) -> usize {
+        self.count
+    }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A: Clone> DoubleEndedIterator for RepeatN<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        self.next()
+    }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+        self.advance_by(n)
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<A> {
+        self.nth(n)
+    }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A: Clone> FusedIterator for RepeatN<A> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}
index 2d12805270f93bed274ee92d93cc32b48cf19fb5..848eccd7f2908ef05ac3a55930797e5c429465e1 100644 (file)
 #![feature(const_cmp)]
 #![feature(const_discriminant)]
 #![feature(const_eval_select)]
+#![feature(const_exact_div)]
 #![feature(const_float_bits_conv)]
 #![feature(const_float_classify)]
 #![feature(const_fmt_arguments_new)]
 #![feature(const_option)]
 #![feature(const_option_ext)]
 #![feature(const_pin)]
+#![feature(const_pointer_is_aligned)]
 #![feature(const_ptr_sub_ptr)]
 #![feature(const_replace)]
+#![feature(const_result_drop)]
 #![feature(const_ptr_as_ref)]
 #![feature(const_ptr_is_null)]
 #![feature(const_ptr_read)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(ptr_alignment_type)]
 #![feature(ptr_metadata)]
+#![feature(set_ptr_value)]
 #![feature(slice_ptr_get)]
 #![feature(slice_split_at_unchecked)]
 #![feature(str_internals)]
index 3eff6033f8da9e16d29006232c4c8e20a0f470e4..42c342801976957a9696b25b92511653d313b918 100644 (file)
@@ -809,6 +809,15 @@ pub trait Destruct {}
 #[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
 pub trait Tuple {}
 
+/// A marker for things
+#[unstable(feature = "pointer_sized_trait", issue = "none")]
+#[cfg_attr(not(bootstrap), lang = "pointer_sized")]
+#[rustc_on_unimplemented(
+    message = "`{Self}` needs to be a pointer-sized type",
+    label = "`{Self}` needs to be a pointer-sized type"
+)]
+pub trait PointerSized {}
+
 /// Implementations of `Copy` for primitive types.
 ///
 /// Implementations that cannot be described in Rust
index e64eb1cf7aed8d5d47b9c327befbf0c9bbb1d817..e1ab7ac5ff045e056a2ba2c26a295867e7137042 100644 (file)
@@ -761,10 +761,11 @@ pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
         #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")]
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
-        pub const unsafe fn unchecked_shl(self, rhs: Self) -> Self {
+        pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
             // SAFETY: the caller must uphold the safety contract for
             // `unchecked_shl`.
-            unsafe { intrinsics::unchecked_shl(self, rhs) }
+            // Any legal shift amount is losslessly representable in the self type.
+            unsafe { intrinsics::unchecked_shl(self, rhs.try_into().ok().unwrap_unchecked()) }
         }
 
         /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
@@ -808,10 +809,11 @@ pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
         #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")]
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
-        pub const unsafe fn unchecked_shr(self, rhs: Self) -> Self {
+        pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
             // SAFETY: the caller must uphold the safety contract for
             // `unchecked_shr`.
-            unsafe { intrinsics::unchecked_shr(self, rhs) }
+            // Any legal shift amount is losslessly representable in the self type.
+            unsafe { intrinsics::unchecked_shr(self, rhs.try_into().ok().unwrap_unchecked()) }
         }
 
         /// Checked absolute value. Computes `self.abs()`, returning `None` if
@@ -1358,11 +1360,12 @@ pub const fn wrapping_neg(self) -> Self {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
+        #[rustc_allow_const_fn_unstable(const_inherent_unchecked_arith)]
         pub const fn wrapping_shl(self, rhs: u32) -> Self {
             // SAFETY: the masking by the bitsize of the type ensures that we do not shift
             // out of bounds
             unsafe {
-                intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
+                self.unchecked_shl(rhs & ($BITS - 1))
             }
         }
 
@@ -1387,11 +1390,12 @@ pub const fn wrapping_shl(self, rhs: u32) -> Self {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
+        #[rustc_allow_const_fn_unstable(const_inherent_unchecked_arith)]
         pub const fn wrapping_shr(self, rhs: u32) -> Self {
             // SAFETY: the masking by the bitsize of the type ensures that we do not shift
             // out of bounds
             unsafe {
-                intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+                self.unchecked_shr(rhs & ($BITS - 1))
             }
         }
 
index 311c5fa5b683419ffce434ee57c879bae8375964..b2328b001de904368ad0adb8ef7ee8a98a080d67 100644 (file)
@@ -3,6 +3,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::ascii;
+use crate::convert::TryInto;
 use crate::error::Error;
 use crate::intrinsics;
 use crate::mem;
index 741d7ec6f592d159e1e4ac6cf60cda9c39da4716..af74faa90b11031c954536972b8ab5e9170a0e25 100644 (file)
@@ -908,10 +908,11 @@ pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
         #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")]
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
-        pub const unsafe fn unchecked_shl(self, rhs: Self) -> Self {
+        pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
             // SAFETY: the caller must uphold the safety contract for
             // `unchecked_shl`.
-            unsafe { intrinsics::unchecked_shl(self, rhs) }
+            // Any legal shift amount is losslessly representable in the self type.
+            unsafe { intrinsics::unchecked_shl(self, rhs.try_into().ok().unwrap_unchecked()) }
         }
 
         /// Checked shift right. Computes `self >> rhs`, returning `None`
@@ -955,10 +956,11 @@ pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
         #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")]
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
-        pub const unsafe fn unchecked_shr(self, rhs: Self) -> Self {
+        pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
             // SAFETY: the caller must uphold the safety contract for
             // `unchecked_shr`.
-            unsafe { intrinsics::unchecked_shr(self, rhs) }
+            // Any legal shift amount is losslessly representable in the self type.
+            unsafe { intrinsics::unchecked_shr(self, rhs.try_into().ok().unwrap_unchecked()) }
         }
 
         /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
@@ -1374,11 +1376,12 @@ pub const fn wrapping_neg(self) -> Self {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
+        #[rustc_allow_const_fn_unstable(const_inherent_unchecked_arith)]
         pub const fn wrapping_shl(self, rhs: u32) -> Self {
             // SAFETY: the masking by the bitsize of the type ensures that we do not shift
             // out of bounds
             unsafe {
-                intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
+                self.unchecked_shl(rhs & ($BITS - 1))
             }
         }
 
@@ -1406,11 +1409,12 @@ pub const fn wrapping_shl(self, rhs: u32) -> Self {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
+        #[rustc_allow_const_fn_unstable(const_inherent_unchecked_arith)]
         pub const fn wrapping_shr(self, rhs: u32) -> Self {
             // SAFETY: the masking by the bitsize of the type ensures that we do not shift
             // out of bounds
             unsafe {
-                intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+                self.unchecked_shr(rhs & ($BITS - 1))
             }
         }
 
index e28ddf3c75ea8dfe28d0d475bae1cbc4f57fb5ec..8a3eee0dc529f59988bdaa1fdaa8f9f8c5ddb843 100644 (file)
@@ -79,19 +79,14 @@ pub const fn cast<U>(self) -> *const U {
     /// }
     /// ```
     #[unstable(feature = "set_ptr_value", issue = "75091")]
+    #[rustc_const_unstable(feature = "set_ptr_value", issue = "75091")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
-    pub fn with_metadata_of<U>(self, mut val: *const U) -> *const U
+    pub const fn with_metadata_of<U>(self, meta: *const U) -> *const U
     where
         U: ?Sized,
     {
-        let target = &mut val as *mut *const U as *mut *const u8;
-        // SAFETY: In case of a thin pointer, this operations is identical
-        // to a simple assignment. In case of a fat pointer, with the current
-        // fat pointer layout implementation, the first field of such a
-        // pointer is always the data pointer, which is likewise assigned.
-        unsafe { *target = self as *const u8 };
-        val
+        from_raw_parts::<U>(self as *const (), metadata(meta))
     }
 
     /// Changes constness without changing the type.
@@ -478,8 +473,7 @@ pub const fn to_raw_parts(self) -> (*const (), <T as super::Pointee>::Metadata)
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn byte_offset(self, count: isize) -> Self {
         // SAFETY: the caller must uphold the safety contract for `offset`.
-        let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
-        from_raw_parts::<T>(this, metadata(self))
+        unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -559,7 +553,7 @@ pub const fn wrapping_offset(self, count: isize) -> *const T
     #[unstable(feature = "pointer_byte_offsets", issue = "96283")]
     #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
     pub const fn wrapping_byte_offset(self, count: isize) -> Self {
-        from_raw_parts::<T>(self.cast::<u8>().wrapping_offset(count).cast::<()>(), metadata(self))
+        self.cast::<u8>().wrapping_offset(count).with_metadata_of(self)
     }
 
     /// Masks out bits of the pointer according to a mask.
@@ -597,8 +591,7 @@ pub const fn wrapping_byte_offset(self, count: isize) -> Self {
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline(always)]
     pub fn mask(self, mask: usize) -> *const T {
-        let this = intrinsics::ptr_mask(self.cast::<()>(), mask);
-        from_raw_parts::<T>(this, metadata(self))
+        intrinsics::ptr_mask(self.cast::<()>(), mask).with_metadata_of(self)
     }
 
     /// Calculates the distance between two pointers. The returned value is in
@@ -939,8 +932,7 @@ pub const fn guaranteed_ne(self, other: *const T) -> Option<bool>
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn byte_add(self, count: usize) -> Self {
         // SAFETY: the caller must uphold the safety contract for `add`.
-        let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
-        from_raw_parts::<T>(this, metadata(self))
+        unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
     }
 
     /// Calculates the offset from a pointer (convenience for
@@ -1026,8 +1018,7 @@ pub const fn guaranteed_ne(self, other: *const T) -> Option<bool>
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn byte_sub(self, count: usize) -> Self {
         // SAFETY: the caller must uphold the safety contract for `sub`.
-        let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
-        from_raw_parts::<T>(this, metadata(self))
+        unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1107,7 +1098,7 @@ pub const fn wrapping_add(self, count: usize) -> Self
     #[unstable(feature = "pointer_byte_offsets", issue = "96283")]
     #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
     pub const fn wrapping_byte_add(self, count: usize) -> Self {
-        from_raw_parts::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
+        self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1187,7 +1178,7 @@ pub const fn wrapping_sub(self, count: usize) -> Self
     #[unstable(feature = "pointer_byte_offsets", issue = "96283")]
     #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
     pub const fn wrapping_byte_sub(self, count: usize) -> Self {
-        from_raw_parts::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
+        self.cast::<u8>().wrapping_sub(count).with_metadata_of(self)
     }
 
     /// Reads the value from `self` without moving it. This leaves the
@@ -1329,6 +1320,8 @@ pub unsafe fn read_volatile(self) -> T
     /// }
     /// # }
     /// ```
+    #[must_use]
+    #[inline]
     #[stable(feature = "align_offset", since = "1.36.0")]
     #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
     pub const fn align_offset(self, align: usize) -> usize
@@ -1339,32 +1332,149 @@ pub const fn align_offset(self, align: usize) -> usize
             panic!("align_offset: align is not a power-of-two");
         }
 
-        fn rt_impl<T>(p: *const T, align: usize) -> usize {
-            // SAFETY: `align` has been checked to be a power of 2 above
-            unsafe { align_offset(p, align) }
-        }
+        #[cfg(bootstrap)]
+        {
+            fn rt_impl<T>(p: *const T, align: usize) -> usize {
+                // SAFETY: `align` has been checked to be a power of 2 above
+                unsafe { align_offset(p, align) }
+            }
+
+            const fn ctfe_impl<T>(_: *const T, _: usize) -> usize {
+                usize::MAX
+            }
 
-        const fn ctfe_impl<T>(_: *const T, _: usize) -> usize {
-            usize::MAX
+            // SAFETY:
+            // It is permissible for `align_offset` to always return `usize::MAX`,
+            // algorithm correctness can not depend on `align_offset` returning non-max values.
+            //
+            // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
+            unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
         }
 
-        // SAFETY:
-        // It is permissible for `align_offset` to always return `usize::MAX`,
-        // algorithm correctness can not depend on `align_offset` returning non-max values.
-        //
-        // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
-        unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
+        #[cfg(not(bootstrap))]
+        {
+            // SAFETY: `align` has been checked to be a power of 2 above
+            unsafe { align_offset(self, align) }
+        }
     }
 
     /// Returns whether the pointer is properly aligned for `T`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    /// ```
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_byte_offsets)]
+    ///
+    /// // On some platforms, the alignment of i32 is less than 4.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    ///
+    /// let data = AlignedI32(42);
+    /// let ptr = &data as *const AlignedI32;
+    ///
+    /// assert!(ptr.is_aligned());
+    /// assert!(!ptr.wrapping_byte_add(1).is_aligned());
+    /// ```
+    ///
+    /// # At compiletime
+    /// **Note: Alignment at compiletime is experimental and subject to change. See the
+    /// [tracking issue] for details.**
+    ///
+    /// At compiletime, the compiler may not know where a value will end up in memory.
+    /// Calling this function on a pointer created from a reference at compiletime will only
+    /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
+    /// is never aligned if cast to a type with a stricter alignment than the reference's
+    /// underlying allocation.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// // On some platforms, the alignment of primitives is less than their size.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    /// #[repr(align(8))]
+    /// struct AlignedI64(i64);
+    ///
+    /// const _: () = {
+    ///     let data = AlignedI32(42);
+    ///     let ptr = &data as *const AlignedI32;
+    ///     assert!(ptr.is_aligned());
+    ///
+    ///     // At runtime either `ptr1` or `ptr2` would be aligned, but at compiletime neither is aligned.
+    ///     let ptr1 = ptr.cast::<AlignedI64>();
+    ///     let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
+    ///     assert!(!ptr1.is_aligned());
+    ///     assert!(!ptr2.is_aligned());
+    /// };
+    /// ```
+    ///
+    /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
+    /// pointer is aligned, even if the compiletime pointer wasn't aligned.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// // On some platforms, the alignment of primitives is less than their size.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    /// #[repr(align(8))]
+    /// struct AlignedI64(i64);
+    ///
+    /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
+    /// const COMPTIME_PTR: *const AlignedI32 = &AlignedI32(42);
+    /// const _: () = assert!(!COMPTIME_PTR.cast::<AlignedI64>().is_aligned());
+    /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).cast::<AlignedI64>().is_aligned());
+    ///
+    /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
+    /// let runtime_ptr = COMPTIME_PTR;
+    /// assert_ne!(
+    ///     runtime_ptr.cast::<AlignedI64>().is_aligned(),
+    ///     runtime_ptr.wrapping_add(1).cast::<AlignedI64>().is_aligned(),
+    /// );
+    /// ```
+    ///
+    /// If a pointer is created from a fixed address, this function behaves the same during
+    /// runtime and compiletime.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// // On some platforms, the alignment of primitives is less than their size.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    /// #[repr(align(8))]
+    /// struct AlignedI64(i64);
+    ///
+    /// const _: () = {
+    ///     let ptr = 40 as *const AlignedI32;
+    ///     assert!(ptr.is_aligned());
+    ///
+    ///     // For pointers with a known address, runtime and compiletime behavior are identical.
+    ///     let ptr1 = ptr.cast::<AlignedI64>();
+    ///     let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
+    ///     assert!(ptr1.is_aligned());
+    ///     assert!(!ptr2.is_aligned());
+    /// };
+    /// ```
+    ///
+    /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
     #[unstable(feature = "pointer_is_aligned", issue = "96284")]
-    pub fn is_aligned(self) -> bool
+    #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
+    pub const fn is_aligned(self) -> bool
     where
         T: Sized,
     {
-        self.is_aligned_to(core::mem::align_of::<T>())
+        self.is_aligned_to(mem::align_of::<T>())
     }
 
     /// Returns whether the pointer is aligned to `align`.
@@ -1375,16 +1485,121 @@ pub fn is_aligned(self) -> bool
     /// # Panics
     ///
     /// The function panics if `align` is not a power-of-two (this includes 0).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    /// ```
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_byte_offsets)]
+    ///
+    /// // On some platforms, the alignment of i32 is less than 4.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    ///
+    /// let data = AlignedI32(42);
+    /// let ptr = &data as *const AlignedI32;
+    ///
+    /// assert!(ptr.is_aligned_to(1));
+    /// assert!(ptr.is_aligned_to(2));
+    /// assert!(ptr.is_aligned_to(4));
+    ///
+    /// assert!(ptr.wrapping_byte_add(2).is_aligned_to(2));
+    /// assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4));
+    ///
+    /// assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
+    /// ```
+    ///
+    /// # At compiletime
+    /// **Note: Alignment at compiletime is experimental and subject to change. See the
+    /// [tracking issue] for details.**
+    ///
+    /// At compiletime, the compiler may not know where a value will end up in memory.
+    /// Calling this function on a pointer created from a reference at compiletime will only
+    /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
+    /// cannot be stricter aligned than the reference's underlying allocation.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// // On some platforms, the alignment of i32 is less than 4.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    ///
+    /// const _: () = {
+    ///     let data = AlignedI32(42);
+    ///     let ptr = &data as *const AlignedI32;
+    ///
+    ///     assert!(ptr.is_aligned_to(1));
+    ///     assert!(ptr.is_aligned_to(2));
+    ///     assert!(ptr.is_aligned_to(4));
+    ///
+    ///     // At compiletime, we know for sure that the pointer isn't aligned to 8.
+    ///     assert!(!ptr.is_aligned_to(8));
+    ///     assert!(!ptr.wrapping_add(1).is_aligned_to(8));
+    /// };
+    /// ```
+    ///
+    /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
+    /// pointer is aligned, even if the compiletime pointer wasn't aligned.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// // On some platforms, the alignment of i32 is less than 4.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    ///
+    /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
+    /// const COMPTIME_PTR: *const AlignedI32 = &AlignedI32(42);
+    /// const _: () = assert!(!COMPTIME_PTR.is_aligned_to(8));
+    /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).is_aligned_to(8));
+    ///
+    /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
+    /// let runtime_ptr = COMPTIME_PTR;
+    /// assert_ne!(
+    ///     runtime_ptr.is_aligned_to(8),
+    ///     runtime_ptr.wrapping_add(1).is_aligned_to(8),
+    /// );
+    /// ```
+    ///
+    /// If a pointer is created from a fixed address, this function behaves the same during
+    /// runtime and compiletime.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// const _: () = {
+    ///     let ptr = 40 as *const u8;
+    ///     assert!(ptr.is_aligned_to(1));
+    ///     assert!(ptr.is_aligned_to(2));
+    ///     assert!(ptr.is_aligned_to(4));
+    ///     assert!(ptr.is_aligned_to(8));
+    ///     assert!(!ptr.is_aligned_to(16));
+    /// };
+    /// ```
+    ///
+    /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
     #[unstable(feature = "pointer_is_aligned", issue = "96284")]
-    pub fn is_aligned_to(self, align: usize) -> bool {
+    #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
+    pub const fn is_aligned_to(self, align: usize) -> bool {
         if !align.is_power_of_two() {
             panic!("is_aligned_to: align is not a power-of-two");
         }
 
-        // Cast is needed for `T: !Sized`
-        self.cast::<u8>().addr() & align - 1 == 0
+        // We can't use the address of `self` in a `const fn`, so we use `align_offset` instead.
+        // The cast to `()` is used to
+        //   1. deal with fat pointers; and
+        //   2. ensure that `align_offset` doesn't actually try to compute an offset.
+        self.cast::<()>().align_offset(align) == 0
     }
 }
 
index 9d4bae3eaa5f7c11b4b12ff67aad5f49756f80d8..73923753a3020062ad6811df4849eb013a5dd970 100644 (file)
@@ -1574,10 +1574,14 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
 
 /// Align pointer `p`.
 ///
-/// Calculate offset (in terms of elements of `stride` stride) that has to be applied
+/// Calculate offset (in terms of elements of `size_of::<T>()` stride) that has to be applied
 /// to pointer `p` so that pointer `p` would get aligned to `a`.
 ///
-/// Note: This implementation has been carefully tailored to not panic. It is UB for this to panic.
+/// # Safety
+/// `a` must be a power of two.
+///
+/// # Notes
+/// This implementation has been carefully tailored to not panic. It is UB for this to panic.
 /// The only real change that can be made here is change of `INV_TABLE_MOD_16` and associated
 /// constants.
 ///
@@ -1587,12 +1591,12 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
 ///
 /// Any questions go to @nagisa.
 #[lang = "align_offset"]
-pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
+pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
     // FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <=
     // 1, where the method versions of these operations are not inlined.
     use intrinsics::{
-        cttz_nonzero, exact_div, unchecked_rem, unchecked_shl, unchecked_shr, unchecked_sub,
-        wrapping_add, wrapping_mul, wrapping_sub,
+        cttz_nonzero, exact_div, mul_with_overflow, unchecked_rem, unchecked_shl, unchecked_shr,
+        unchecked_sub, wrapping_add, wrapping_mul, wrapping_sub,
     };
 
     /// Calculate multiplicative modular inverse of `x` modulo `m`.
@@ -1604,7 +1608,7 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
     ///
     /// Implementation of this function shall not panic. Ever.
     #[inline]
-    unsafe fn mod_inv(x: usize, m: usize) -> usize {
+    const unsafe fn mod_inv(x: usize, m: usize) -> usize {
         /// Multiplicative modular inverse table modulo 2⁴ = 16.
         ///
         /// Note, that this table does not contain values where inverse does not exist (i.e., for
@@ -1612,40 +1616,48 @@ unsafe fn mod_inv(x: usize, m: usize) -> usize {
         const INV_TABLE_MOD_16: [u8; 8] = [1, 11, 13, 7, 9, 3, 5, 15];
         /// Modulo for which the `INV_TABLE_MOD_16` is intended.
         const INV_TABLE_MOD: usize = 16;
-        /// INV_TABLE_MOD²
-        const INV_TABLE_MOD_SQUARED: usize = INV_TABLE_MOD * INV_TABLE_MOD;
 
-        let table_inverse = INV_TABLE_MOD_16[(x & (INV_TABLE_MOD - 1)) >> 1] as usize;
         // SAFETY: `m` is required to be a power-of-two, hence non-zero.
         let m_minus_one = unsafe { unchecked_sub(m, 1) };
-        if m <= INV_TABLE_MOD {
-            table_inverse & m_minus_one
-        } else {
-            // We iterate "up" using the following formula:
-            //
-            // $$ xy ≡ 1 (mod 2ⁿ) → xy (2 - xy) ≡ 1 (mod 2²ⁿ) $$
+        let mut inverse = INV_TABLE_MOD_16[(x & (INV_TABLE_MOD - 1)) >> 1] as usize;
+        let mut mod_gate = INV_TABLE_MOD;
+        // We iterate "up" using the following formula:
+        //
+        // $$ xy ≡ 1 (mod 2ⁿ) → xy (2 - xy) ≡ 1 (mod 2²ⁿ) $$
+        //
+        // This application needs to be applied at least until `2²ⁿ ≥ m`, at which point we can
+        // finally reduce the computation to our desired `m` by taking `inverse mod m`.
+        //
+        // This computation is `O(log log m)`, which is to say, that on 64-bit machines this loop
+        // will always finish in at most 4 iterations.
+        loop {
+            // y = y * (2 - xy) mod n
             //
-            // until 2²ⁿ ≥ m. Then we can reduce to our desired `m` by taking the result `mod m`.
-            let mut inverse = table_inverse;
-            let mut going_mod = INV_TABLE_MOD_SQUARED;
-            loop {
-                // y = y * (2 - xy) mod n
-                //
-                // Note, that we use wrapping operations here intentionally – the original formula
-                // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod
-                // usize::MAX` instead, because we take the result `mod n` at the end
-                // anyway.
-                inverse = wrapping_mul(inverse, wrapping_sub(2usize, wrapping_mul(x, inverse)));
-                if going_mod >= m {
-                    return inverse & m_minus_one;
-                }
-                going_mod = wrapping_mul(going_mod, going_mod);
+            // Note, that we use wrapping operations here intentionally – the original formula
+            // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod
+            // usize::MAX` instead, because we take the result `mod n` at the end
+            // anyway.
+            if mod_gate >= m {
+                break;
             }
+            inverse = wrapping_mul(inverse, wrapping_sub(2usize, wrapping_mul(x, inverse)));
+            let (new_gate, overflow) = mul_with_overflow(mod_gate, mod_gate);
+            if overflow {
+                break;
+            }
+            mod_gate = new_gate;
         }
+        inverse & m_minus_one
     }
 
-    let addr = p.addr();
     let stride = mem::size_of::<T>();
+
+    // SAFETY: This is just an inlined `p.addr()` (which is not
+    // a `const fn` so we cannot call it).
+    // During const eval, we hook this function to ensure that the pointer never
+    // has provenance, making this sound.
+    let addr: usize = unsafe { mem::transmute(p) };
+
     // SAFETY: `a` is a power-of-two, therefore non-zero.
     let a_minus_one = unsafe { unchecked_sub(a, 1) };
 
index ba21126dbd2ca9a0197433c4608dacd4016c07f7..8472b05ddbd40a595f6b1d3bdb8d2b2ba98a5438 100644 (file)
@@ -78,23 +78,14 @@ pub const fn cast<U>(self) -> *mut U {
     /// }
     /// ```
     #[unstable(feature = "set_ptr_value", issue = "75091")]
+    #[rustc_const_unstable(feature = "set_ptr_value", issue = "75091")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
-    pub fn with_metadata_of<U>(self, val: *const U) -> *mut U
+    pub const fn with_metadata_of<U>(self, meta: *const U) -> *mut U
     where
         U: ?Sized,
     {
-        // Prepare in the type system that we will replace the pointer value with a mutable
-        // pointer, taking the mutable provenance from the `self` pointer.
-        let mut val = val as *mut U;
-        // Pointer to the pointer value within the value.
-        let target = &mut val as *mut *mut U as *mut *mut u8;
-        // SAFETY: In case of a thin pointer, this operations is identical
-        // to a simple assignment. In case of a fat pointer, with the current
-        // fat pointer layout implementation, the first field of such a
-        // pointer is always the data pointer, which is likewise assigned.
-        unsafe { *target = self as *mut u8 };
-        val
+        from_raw_parts_mut::<U>(self as *mut (), metadata(meta))
     }
 
     /// Changes constness without changing the type.
@@ -496,8 +487,7 @@ pub const fn to_raw_parts(self) -> (*mut (), <T as super::Pointee>::Metadata) {
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn byte_offset(self, count: isize) -> Self {
         // SAFETY: the caller must uphold the safety contract for `offset`.
-        let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
-        from_raw_parts_mut::<T>(this, metadata(self))
+        unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -576,10 +566,7 @@ pub const fn wrapping_offset(self, count: isize) -> *mut T
     #[unstable(feature = "pointer_byte_offsets", issue = "96283")]
     #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
     pub const fn wrapping_byte_offset(self, count: isize) -> Self {
-        from_raw_parts_mut::<T>(
-            self.cast::<u8>().wrapping_offset(count).cast::<()>(),
-            metadata(self),
-        )
+        self.cast::<u8>().wrapping_offset(count).with_metadata_of(self)
     }
 
     /// Masks out bits of the pointer according to a mask.
@@ -620,8 +607,7 @@ pub const fn wrapping_byte_offset(self, count: isize) -> Self {
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline(always)]
     pub fn mask(self, mask: usize) -> *mut T {
-        let this = intrinsics::ptr_mask(self.cast::<()>(), mask) as *mut ();
-        from_raw_parts_mut::<T>(this, metadata(self))
+        intrinsics::ptr_mask(self.cast::<()>(), mask).cast_mut().with_metadata_of(self)
     }
 
     /// Returns `None` if the pointer is null, or else returns a unique reference to
@@ -1048,8 +1034,7 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn byte_add(self, count: usize) -> Self {
         // SAFETY: the caller must uphold the safety contract for `add`.
-        let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
-        from_raw_parts_mut::<T>(this, metadata(self))
+        unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
     }
 
     /// Calculates the offset from a pointer (convenience for
@@ -1135,8 +1120,7 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn byte_sub(self, count: usize) -> Self {
         // SAFETY: the caller must uphold the safety contract for `sub`.
-        let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
-        from_raw_parts_mut::<T>(this, metadata(self))
+        unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1216,7 +1200,7 @@ pub const fn wrapping_add(self, count: usize) -> Self
     #[unstable(feature = "pointer_byte_offsets", issue = "96283")]
     #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
     pub const fn wrapping_byte_add(self, count: usize) -> Self {
-        from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
+        self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1296,7 +1280,7 @@ pub const fn wrapping_sub(self, count: usize) -> Self
     #[unstable(feature = "pointer_byte_offsets", issue = "96283")]
     #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
     pub const fn wrapping_byte_sub(self, count: usize) -> Self {
-        from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
+        self.cast::<u8>().wrapping_sub(count).with_metadata_of(self)
     }
 
     /// Reads the value from `self` without moving it. This leaves the
@@ -1604,6 +1588,8 @@ pub unsafe fn replace(self, src: T) -> T
     /// }
     /// # }
     /// ```
+    #[must_use]
+    #[inline]
     #[stable(feature = "align_offset", since = "1.36.0")]
     #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
     pub const fn align_offset(self, align: usize) -> usize
@@ -1614,32 +1600,151 @@ pub const fn align_offset(self, align: usize) -> usize
             panic!("align_offset: align is not a power-of-two");
         }
 
-        fn rt_impl<T>(p: *mut T, align: usize) -> usize {
-            // SAFETY: `align` has been checked to be a power of 2 above
-            unsafe { align_offset(p, align) }
+        #[cfg(bootstrap)]
+        {
+            fn rt_impl<T>(p: *mut T, align: usize) -> usize {
+                // SAFETY: `align` has been checked to be a power of 2 above
+                unsafe { align_offset(p, align) }
+            }
+
+            const fn ctfe_impl<T>(_: *mut T, _: usize) -> usize {
+                usize::MAX
+            }
+
+            // SAFETY:
+            // It is permissible for `align_offset` to always return `usize::MAX`,
+            // algorithm correctness can not depend on `align_offset` returning non-max values.
+            //
+            // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
+            unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
         }
 
-        const fn ctfe_impl<T>(_: *mut T, _: usize) -> usize {
-            usize::MAX
+        #[cfg(not(bootstrap))]
+        {
+            // SAFETY: `align` has been checked to be a power of 2 above
+            unsafe { align_offset(self, align) }
         }
-
-        // SAFETY:
-        // It is permissible for `align_offset` to always return `usize::MAX`,
-        // algorithm correctness can not depend on `align_offset` returning non-max values.
-        //
-        // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
-        unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
     }
 
     /// Returns whether the pointer is properly aligned for `T`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    /// ```
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_byte_offsets)]
+    ///
+    /// // On some platforms, the alignment of i32 is less than 4.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    ///
+    /// let mut data = AlignedI32(42);
+    /// let ptr = &mut data as *mut AlignedI32;
+    ///
+    /// assert!(ptr.is_aligned());
+    /// assert!(!ptr.wrapping_byte_add(1).is_aligned());
+    /// ```
+    ///
+    /// # At compiletime
+    /// **Note: Alignment at compiletime is experimental and subject to change. See the
+    /// [tracking issue] for details.**
+    ///
+    /// At compiletime, the compiler may not know where a value will end up in memory.
+    /// Calling this function on a pointer created from a reference at compiletime will only
+    /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
+    /// is never aligned if cast to a type with a stricter alignment than the reference's
+    /// underlying allocation.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    /// #![feature(const_mut_refs)]
+    ///
+    /// // On some platforms, the alignment of primitives is less than their size.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    /// #[repr(align(8))]
+    /// struct AlignedI64(i64);
+    ///
+    /// const _: () = {
+    ///     let mut data = AlignedI32(42);
+    ///     let ptr = &mut data as *mut AlignedI32;
+    ///     assert!(ptr.is_aligned());
+    ///
+    ///     // At runtime either `ptr1` or `ptr2` would be aligned, but at compiletime neither is aligned.
+    ///     let ptr1 = ptr.cast::<AlignedI64>();
+    ///     let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
+    ///     assert!(!ptr1.is_aligned());
+    ///     assert!(!ptr2.is_aligned());
+    /// };
+    /// ```
+    ///
+    /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
+    /// pointer is aligned, even if the compiletime pointer wasn't aligned.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// // On some platforms, the alignment of primitives is less than their size.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    /// #[repr(align(8))]
+    /// struct AlignedI64(i64);
+    ///
+    /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
+    /// // Also, note that mutable references are not allowed in the final value of constants.
+    /// const COMPTIME_PTR: *mut AlignedI32 = (&AlignedI32(42) as *const AlignedI32).cast_mut();
+    /// const _: () = assert!(!COMPTIME_PTR.cast::<AlignedI64>().is_aligned());
+    /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).cast::<AlignedI64>().is_aligned());
+    ///
+    /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
+    /// let runtime_ptr = COMPTIME_PTR;
+    /// assert_ne!(
+    ///     runtime_ptr.cast::<AlignedI64>().is_aligned(),
+    ///     runtime_ptr.wrapping_add(1).cast::<AlignedI64>().is_aligned(),
+    /// );
+    /// ```
+    ///
+    /// If a pointer is created from a fixed address, this function behaves the same during
+    /// runtime and compiletime.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// // On some platforms, the alignment of primitives is less than their size.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    /// #[repr(align(8))]
+    /// struct AlignedI64(i64);
+    ///
+    /// const _: () = {
+    ///     let ptr = 40 as *mut AlignedI32;
+    ///     assert!(ptr.is_aligned());
+    ///
+    ///     // For pointers with a known address, runtime and compiletime behavior are identical.
+    ///     let ptr1 = ptr.cast::<AlignedI64>();
+    ///     let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
+    ///     assert!(ptr1.is_aligned());
+    ///     assert!(!ptr2.is_aligned());
+    /// };
+    /// ```
+    ///
+    /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
     #[unstable(feature = "pointer_is_aligned", issue = "96284")]
-    pub fn is_aligned(self) -> bool
+    #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
+    pub const fn is_aligned(self) -> bool
     where
         T: Sized,
     {
-        self.is_aligned_to(core::mem::align_of::<T>())
+        self.is_aligned_to(mem::align_of::<T>())
     }
 
     /// Returns whether the pointer is aligned to `align`.
@@ -1650,16 +1755,123 @@ pub fn is_aligned(self) -> bool
     /// # Panics
     ///
     /// The function panics if `align` is not a power-of-two (this includes 0).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    /// ```
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_byte_offsets)]
+    ///
+    /// // On some platforms, the alignment of i32 is less than 4.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    ///
+    /// let mut data = AlignedI32(42);
+    /// let ptr = &mut data as *mut AlignedI32;
+    ///
+    /// assert!(ptr.is_aligned_to(1));
+    /// assert!(ptr.is_aligned_to(2));
+    /// assert!(ptr.is_aligned_to(4));
+    ///
+    /// assert!(ptr.wrapping_byte_add(2).is_aligned_to(2));
+    /// assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4));
+    ///
+    /// assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
+    /// ```
+    ///
+    /// # At compiletime
+    /// **Note: Alignment at compiletime is experimental and subject to change. See the
+    /// [tracking issue] for details.**
+    ///
+    /// At compiletime, the compiler may not know where a value will end up in memory.
+    /// Calling this function on a pointer created from a reference at compiletime will only
+    /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
+    /// cannot be stricter aligned than the reference's underlying allocation.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    /// #![feature(const_mut_refs)]
+    ///
+    /// // On some platforms, the alignment of i32 is less than 4.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    ///
+    /// const _: () = {
+    ///     let mut data = AlignedI32(42);
+    ///     let ptr = &mut data as *mut AlignedI32;
+    ///
+    ///     assert!(ptr.is_aligned_to(1));
+    ///     assert!(ptr.is_aligned_to(2));
+    ///     assert!(ptr.is_aligned_to(4));
+    ///
+    ///     // At compiletime, we know for sure that the pointer isn't aligned to 8.
+    ///     assert!(!ptr.is_aligned_to(8));
+    ///     assert!(!ptr.wrapping_add(1).is_aligned_to(8));
+    /// };
+    /// ```
+    ///
+    /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
+    /// pointer is aligned, even if the compiletime pointer wasn't aligned.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// // On some platforms, the alignment of i32 is less than 4.
+    /// #[repr(align(4))]
+    /// struct AlignedI32(i32);
+    ///
+    /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
+    /// // Also, note that mutable references are not allowed in the final value of constants.
+    /// const COMPTIME_PTR: *mut AlignedI32 = (&AlignedI32(42) as *const AlignedI32).cast_mut();
+    /// const _: () = assert!(!COMPTIME_PTR.is_aligned_to(8));
+    /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).is_aligned_to(8));
+    ///
+    /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
+    /// let runtime_ptr = COMPTIME_PTR;
+    /// assert_ne!(
+    ///     runtime_ptr.is_aligned_to(8),
+    ///     runtime_ptr.wrapping_add(1).is_aligned_to(8),
+    /// );
+    /// ```
+    ///
+    /// If a pointer is created from a fixed address, this function behaves the same during
+    /// runtime and compiletime.
+    ///
+    #[cfg_attr(bootstrap, doc = "```ignore")]
+    #[cfg_attr(not(bootstrap), doc = "```")]
+    /// #![feature(pointer_is_aligned)]
+    /// #![feature(const_pointer_is_aligned)]
+    ///
+    /// const _: () = {
+    ///     let ptr = 40 as *mut u8;
+    ///     assert!(ptr.is_aligned_to(1));
+    ///     assert!(ptr.is_aligned_to(2));
+    ///     assert!(ptr.is_aligned_to(4));
+    ///     assert!(ptr.is_aligned_to(8));
+    ///     assert!(!ptr.is_aligned_to(16));
+    /// };
+    /// ```
+    ///
+    /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
     #[unstable(feature = "pointer_is_aligned", issue = "96284")]
-    pub fn is_aligned_to(self, align: usize) -> bool {
+    #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
+    pub const fn is_aligned_to(self, align: usize) -> bool {
         if !align.is_power_of_two() {
             panic!("is_aligned_to: align is not a power-of-two");
         }
 
-        // Cast is needed for `T: !Sized`
-        self.cast::<u8>().addr() & align - 1 == 0
+        // We can't use the address of `self` in a `const fn`, so we use `align_offset` instead.
+        // The cast to `()` is used to
+        //   1. deal with fat pointers; and
+        //   2. ensure that `align_offset` doesn't actually try to compute an offset.
+        self.cast::<()>().align_offset(align) == 0
     }
 }
 
index 0f58bc643d9655a8aaa299f61efcecf462a5d29e..ad90e00b8a095a42aa6a0fed4a28d4ae0f98c0e9 100644 (file)
@@ -3752,9 +3752,9 @@ pub fn is_sorted(&self) -> bool
     /// [`is_sorted`]: slice::is_sorted
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
     #[must_use]
-    pub fn is_sorted_by<F>(&self, mut compare: F) -> bool
+    pub fn is_sorted_by<'a, F>(&'a self, mut compare: F) -> bool
     where
-        F: FnMut(&T, &T) -> Option<Ordering>,
+        F: FnMut(&'a T, &'a T) -> Option<Ordering>,
     {
         self.iter().is_sorted_by(|a, b| compare(*a, *b))
     }
@@ -3778,9 +3778,9 @@ pub fn is_sorted_by<F>(&self, mut compare: F) -> bool
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
     #[must_use]
-    pub fn is_sorted_by_key<F, K>(&self, f: F) -> bool
+    pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
     where
-        F: FnMut(&T) -> K,
+        F: FnMut(&'a T) -> K,
         K: PartialOrd,
     {
         self.iter().is_sorted_by_key(f)
index d0114ade6e4634828b42619d5472a5178446ba2b..a15f3a5148f0a6cebd77d04fe8b55ce676ba7f50 100644 (file)
@@ -106,3 +106,52 @@ fn test_empty() {
     let mut it = empty::<i32>();
     assert_eq!(it.next(), None);
 }
+
+#[test]
+fn test_repeat_n_drop() {
+    #[derive(Clone, Debug)]
+    struct DropCounter<'a>(&'a Cell<usize>);
+    impl Drop for DropCounter<'_> {
+        fn drop(&mut self) {
+            self.0.set(self.0.get() + 1);
+        }
+    }
+
+    // `repeat_n(x, 0)` drops `x` immediately
+    let count = Cell::new(0);
+    let item = DropCounter(&count);
+    let mut it = repeat_n(item, 0);
+    assert_eq!(count.get(), 1);
+    assert!(it.next().is_none());
+    assert_eq!(count.get(), 1);
+    drop(it);
+    assert_eq!(count.get(), 1);
+
+    // Dropping the iterator needs to drop the item if it's non-empty
+    let count = Cell::new(0);
+    let item = DropCounter(&count);
+    let it = repeat_n(item, 3);
+    assert_eq!(count.get(), 0);
+    drop(it);
+    assert_eq!(count.get(), 1);
+
+    // Dropping the iterator doesn't drop the item if it was exhausted
+    let count = Cell::new(0);
+    let item = DropCounter(&count);
+    let mut it = repeat_n(item, 3);
+    assert_eq!(count.get(), 0);
+    let x0 = it.next().unwrap();
+    assert_eq!(count.get(), 0);
+    let x1 = it.next().unwrap();
+    assert_eq!(count.get(), 0);
+    let x2 = it.next().unwrap();
+    assert_eq!(count.get(), 0);
+    assert!(it.next().is_none());
+    assert_eq!(count.get(), 0);
+    assert!(it.next().is_none());
+    assert_eq!(count.get(), 0);
+    drop(it);
+    assert_eq!(count.get(), 0);
+    drop((x0, x1, x2));
+    assert_eq!(count.get(), 3);
+}
index 61d31b3448734349b7c5b06ba5bf68de895d18b3..4c0c0da652f95444c9b42eba60f29cb0dd9a7090 100644 (file)
@@ -4,6 +4,7 @@
 #![feature(array_windows)]
 #![feature(bigint_helper_methods)]
 #![feature(cell_update)]
+#![feature(const_align_offset)]
 #![feature(const_assume)]
 #![feature(const_align_of_val_raw)]
 #![feature(const_black_box)]
@@ -18,6 +19,7 @@
 #![feature(const_nonnull_new)]
 #![feature(const_num_from_num)]
 #![feature(const_pointer_byte_offsets)]
+#![feature(const_pointer_is_aligned)]
 #![feature(const_ptr_as_ref)]
 #![feature(const_ptr_read)]
 #![feature(const_ptr_write)]
@@ -73,6 +75,7 @@
 #![feature(iter_is_partitioned)]
 #![feature(iter_next_chunk)]
 #![feature(iter_order_by)]
+#![feature(iter_repeat_n)]
 #![feature(iterator_try_collect)]
 #![feature(iterator_try_reduce)]
 #![feature(const_mut_refs)]
@@ -81,6 +84,7 @@
 #![feature(never_type)]
 #![feature(unwrap_infallible)]
 #![feature(pointer_byte_offsets)]
+#![feature(pointer_is_aligned)]
 #![feature(portable_simd)]
 #![feature(ptr_metadata)]
 #![feature(once_cell)]
index 97a369810056dceefcdef14ad542fe4a0e15fd93..390148550a4b398d891d2db7110a6dc19b24e9b4 100644 (file)
@@ -358,6 +358,23 @@ fn align_offset_zst() {
     }
 }
 
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_zst_const() {
+    const {
+        // For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at
+        // all, because no amount of elements will align the pointer.
+        let mut p = 1;
+        while p < 1024 {
+            assert!(ptr::invalid::<()>(p).align_offset(p) == 0);
+            if p != 1 {
+                assert!(ptr::invalid::<()>(p + 1).align_offset(p) == !0);
+            }
+            p = (p + 1).next_power_of_two();
+        }
+    }
+}
+
 #[test]
 fn align_offset_stride_one() {
     // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
@@ -379,6 +396,26 @@ fn align_offset_stride_one() {
     }
 }
 
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_stride_one_const() {
+    const {
+        // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
+        // number of bytes.
+        let mut align = 1;
+        while align < 1024 {
+            let mut ptr = 1;
+            while ptr < 2 * align {
+                let expected = ptr % align;
+                let offset = if expected == 0 { 0 } else { align - expected };
+                assert!(ptr::invalid::<u8>(ptr).align_offset(align) == offset);
+                ptr += 1;
+            }
+            align = (align + 1).next_power_of_two();
+        }
+    }
+}
+
 #[test]
 fn align_offset_various_strides() {
     unsafe fn test_stride<T>(ptr: *const T, align: usize) -> bool {
@@ -455,6 +492,260 @@ unsafe fn test_stride<T>(ptr: *const T, align: usize) -> bool {
     assert!(!x);
 }
 
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_various_strides_const() {
+    const unsafe fn test_stride<T>(ptr: *const T, numptr: usize, align: usize) {
+        let mut expected = usize::MAX;
+        // Naive but definitely correct way to find the *first* aligned element of stride::<T>.
+        let mut el = 0;
+        while el < align {
+            if (numptr + el * ::std::mem::size_of::<T>()) % align == 0 {
+                expected = el;
+                break;
+            }
+            el += 1;
+        }
+        let got = ptr.align_offset(align);
+        assert!(got == expected);
+    }
+
+    const {
+        // For pointers of stride != 1, we verify the algorithm against the naivest possible
+        // implementation
+        let mut align = 1;
+        let limit = 32;
+        while align < limit {
+            let mut ptr = 1;
+            while ptr < 4 * align {
+                unsafe {
+                    #[repr(packed)]
+                    struct A3(u16, u8);
+                    test_stride::<A3>(ptr::invalid::<A3>(ptr), ptr, align);
+
+                    struct A4(u32);
+                    test_stride::<A4>(ptr::invalid::<A4>(ptr), ptr, align);
+
+                    #[repr(packed)]
+                    struct A5(u32, u8);
+                    test_stride::<A5>(ptr::invalid::<A5>(ptr), ptr, align);
+
+                    #[repr(packed)]
+                    struct A6(u32, u16);
+                    test_stride::<A6>(ptr::invalid::<A6>(ptr), ptr, align);
+
+                    #[repr(packed)]
+                    struct A7(u32, u16, u8);
+                    test_stride::<A7>(ptr::invalid::<A7>(ptr), ptr, align);
+
+                    #[repr(packed)]
+                    struct A8(u32, u32);
+                    test_stride::<A8>(ptr::invalid::<A8>(ptr), ptr, align);
+
+                    #[repr(packed)]
+                    struct A9(u32, u32, u8);
+                    test_stride::<A9>(ptr::invalid::<A9>(ptr), ptr, align);
+
+                    #[repr(packed)]
+                    struct A10(u32, u32, u16);
+                    test_stride::<A10>(ptr::invalid::<A10>(ptr), ptr, align);
+
+                    test_stride::<u32>(ptr::invalid::<u32>(ptr), ptr, align);
+                    test_stride::<u128>(ptr::invalid::<u128>(ptr), ptr, align);
+                }
+                ptr += 1;
+            }
+            align = (align + 1).next_power_of_two();
+        }
+    }
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_with_provenance_const() {
+    const {
+        // On some platforms (e.g. msp430-none-elf), the alignment of `i32` is less than 4.
+        #[repr(align(4))]
+        struct AlignedI32(i32);
+
+        let data = AlignedI32(42);
+
+        // `stride % align == 0` (usual case)
+
+        let ptr: *const i32 = &data.0;
+        assert!(ptr.align_offset(1) == 0);
+        assert!(ptr.align_offset(2) == 0);
+        assert!(ptr.align_offset(4) == 0);
+        assert!(ptr.align_offset(8) == usize::MAX);
+        assert!(ptr.wrapping_byte_add(1).align_offset(1) == 0);
+        assert!(ptr.wrapping_byte_add(1).align_offset(2) == usize::MAX);
+        assert!(ptr.wrapping_byte_add(2).align_offset(1) == 0);
+        assert!(ptr.wrapping_byte_add(2).align_offset(2) == 0);
+        assert!(ptr.wrapping_byte_add(2).align_offset(4) == usize::MAX);
+        assert!(ptr.wrapping_byte_add(3).align_offset(1) == 0);
+        assert!(ptr.wrapping_byte_add(3).align_offset(2) == usize::MAX);
+
+        assert!(ptr.wrapping_add(42).align_offset(4) == 0);
+        assert!(ptr.wrapping_add(42).align_offset(8) == usize::MAX);
+
+        let ptr1: *const i8 = ptr.cast();
+        assert!(ptr1.align_offset(1) == 0);
+        assert!(ptr1.align_offset(2) == 0);
+        assert!(ptr1.align_offset(4) == 0);
+        assert!(ptr1.align_offset(8) == usize::MAX);
+        assert!(ptr1.wrapping_byte_add(1).align_offset(1) == 0);
+        assert!(ptr1.wrapping_byte_add(1).align_offset(2) == 1);
+        assert!(ptr1.wrapping_byte_add(1).align_offset(4) == 3);
+        assert!(ptr1.wrapping_byte_add(1).align_offset(8) == usize::MAX);
+        assert!(ptr1.wrapping_byte_add(2).align_offset(1) == 0);
+        assert!(ptr1.wrapping_byte_add(2).align_offset(2) == 0);
+        assert!(ptr1.wrapping_byte_add(2).align_offset(4) == 2);
+        assert!(ptr1.wrapping_byte_add(2).align_offset(8) == usize::MAX);
+        assert!(ptr1.wrapping_byte_add(3).align_offset(1) == 0);
+        assert!(ptr1.wrapping_byte_add(3).align_offset(2) == 1);
+        assert!(ptr1.wrapping_byte_add(3).align_offset(4) == 1);
+        assert!(ptr1.wrapping_byte_add(3).align_offset(8) == usize::MAX);
+
+        let ptr2: *const i16 = ptr.cast();
+        assert!(ptr2.align_offset(1) == 0);
+        assert!(ptr2.align_offset(2) == 0);
+        assert!(ptr2.align_offset(4) == 0);
+        assert!(ptr2.align_offset(8) == usize::MAX);
+        assert!(ptr2.wrapping_byte_add(1).align_offset(1) == 0);
+        assert!(ptr2.wrapping_byte_add(1).align_offset(2) == usize::MAX);
+        assert!(ptr2.wrapping_byte_add(2).align_offset(1) == 0);
+        assert!(ptr2.wrapping_byte_add(2).align_offset(2) == 0);
+        assert!(ptr2.wrapping_byte_add(2).align_offset(4) == 1);
+        assert!(ptr2.wrapping_byte_add(2).align_offset(8) == usize::MAX);
+        assert!(ptr2.wrapping_byte_add(3).align_offset(1) == 0);
+        assert!(ptr2.wrapping_byte_add(3).align_offset(2) == usize::MAX);
+
+        let ptr3: *const i64 = ptr.cast();
+        assert!(ptr3.align_offset(1) == 0);
+        assert!(ptr3.align_offset(2) == 0);
+        assert!(ptr3.align_offset(4) == 0);
+        assert!(ptr3.align_offset(8) == usize::MAX);
+        assert!(ptr3.wrapping_byte_add(1).align_offset(1) == 0);
+        assert!(ptr3.wrapping_byte_add(1).align_offset(2) == usize::MAX);
+
+        // `stride % align != 0` (edge case)
+
+        let ptr4: *const [u8; 3] = ptr.cast();
+        assert!(ptr4.align_offset(1) == 0);
+        assert!(ptr4.align_offset(2) == 0);
+        assert!(ptr4.align_offset(4) == 0);
+        assert!(ptr4.align_offset(8) == usize::MAX);
+        assert!(ptr4.wrapping_byte_add(1).align_offset(1) == 0);
+        assert!(ptr4.wrapping_byte_add(1).align_offset(2) == 1);
+        assert!(ptr4.wrapping_byte_add(1).align_offset(4) == 1);
+        assert!(ptr4.wrapping_byte_add(1).align_offset(8) == usize::MAX);
+        assert!(ptr4.wrapping_byte_add(2).align_offset(1) == 0);
+        assert!(ptr4.wrapping_byte_add(2).align_offset(2) == 0);
+        assert!(ptr4.wrapping_byte_add(2).align_offset(4) == 2);
+        assert!(ptr4.wrapping_byte_add(2).align_offset(8) == usize::MAX);
+        assert!(ptr4.wrapping_byte_add(3).align_offset(1) == 0);
+        assert!(ptr4.wrapping_byte_add(3).align_offset(2) == 1);
+        assert!(ptr4.wrapping_byte_add(3).align_offset(4) == 3);
+        assert!(ptr4.wrapping_byte_add(3).align_offset(8) == usize::MAX);
+
+        let ptr5: *const [u8; 5] = ptr.cast();
+        assert!(ptr5.align_offset(1) == 0);
+        assert!(ptr5.align_offset(2) == 0);
+        assert!(ptr5.align_offset(4) == 0);
+        assert!(ptr5.align_offset(8) == usize::MAX);
+        assert!(ptr5.wrapping_byte_add(1).align_offset(1) == 0);
+        assert!(ptr5.wrapping_byte_add(1).align_offset(2) == 1);
+        assert!(ptr5.wrapping_byte_add(1).align_offset(4) == 3);
+        assert!(ptr5.wrapping_byte_add(1).align_offset(8) == usize::MAX);
+        assert!(ptr5.wrapping_byte_add(2).align_offset(1) == 0);
+        assert!(ptr5.wrapping_byte_add(2).align_offset(2) == 0);
+        assert!(ptr5.wrapping_byte_add(2).align_offset(4) == 2);
+        assert!(ptr5.wrapping_byte_add(2).align_offset(8) == usize::MAX);
+        assert!(ptr5.wrapping_byte_add(3).align_offset(1) == 0);
+        assert!(ptr5.wrapping_byte_add(3).align_offset(2) == 1);
+        assert!(ptr5.wrapping_byte_add(3).align_offset(4) == 1);
+        assert!(ptr5.wrapping_byte_add(3).align_offset(8) == usize::MAX);
+    }
+}
+
+#[test]
+fn align_offset_issue_103361() {
+    #[cfg(target_pointer_width = "64")]
+    const SIZE: usize = 1 << 47;
+    #[cfg(target_pointer_width = "32")]
+    const SIZE: usize = 1 << 30;
+    #[cfg(target_pointer_width = "16")]
+    const SIZE: usize = 1 << 13;
+    struct HugeSize([u8; SIZE - 1]);
+    let _ = (SIZE as *const HugeSize).align_offset(SIZE);
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_issue_103361_const() {
+    #[cfg(target_pointer_width = "64")]
+    const SIZE: usize = 1 << 47;
+    #[cfg(target_pointer_width = "32")]
+    const SIZE: usize = 1 << 30;
+    #[cfg(target_pointer_width = "16")]
+    const SIZE: usize = 1 << 13;
+    struct HugeSize([u8; SIZE - 1]);
+
+    const {
+        assert!(ptr::invalid::<HugeSize>(SIZE - 1).align_offset(SIZE) == SIZE - 1);
+        assert!(ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE) == 0);
+        assert!(ptr::invalid::<HugeSize>(SIZE + 1).align_offset(SIZE) == 1);
+    }
+}
+
+#[test]
+fn is_aligned() {
+    let data = 42;
+    let ptr: *const i32 = &data;
+    assert!(ptr.is_aligned());
+    assert!(ptr.is_aligned_to(1));
+    assert!(ptr.is_aligned_to(2));
+    assert!(ptr.is_aligned_to(4));
+    assert!(ptr.wrapping_byte_add(2).is_aligned_to(1));
+    assert!(ptr.wrapping_byte_add(2).is_aligned_to(2));
+    assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4));
+
+    // At runtime either `ptr` or `ptr+1` is aligned to 8.
+    assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn is_aligned_const() {
+    const {
+        let data = 42;
+        let ptr: *const i32 = &data;
+        assert!(ptr.is_aligned());
+        assert!(ptr.is_aligned_to(1));
+        assert!(ptr.is_aligned_to(2));
+        assert!(ptr.is_aligned_to(4));
+        assert!(ptr.wrapping_byte_add(2).is_aligned_to(1));
+        assert!(ptr.wrapping_byte_add(2).is_aligned_to(2));
+        assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4));
+
+        // At comptime neither `ptr` nor `ptr+1` is aligned to 8.
+        assert!(!ptr.is_aligned_to(8));
+        assert!(!ptr.wrapping_add(1).is_aligned_to(8));
+    }
+}
+
+#[test]
+#[cfg(bootstrap)]
+fn is_aligned_const() {
+    const {
+        let data = 42;
+        let ptr: *const i32 = &data;
+        // The bootstrap compiler always returns false for is_aligned.
+        assert!(!ptr.is_aligned());
+        assert!(!ptr.is_aligned_to(1));
+    }
+}
+
 #[test]
 fn offset_from() {
     let mut a = [0; 5];
index 1eb4f378904a9894efcddba25f6138e5aac883c9..7e7180a38e2f23d6c76b3886a503ebb20832bec6 100644 (file)
@@ -42,7 +42,8 @@
         // L4Re is unix family but does not yet support unwinding.
         #[path = "dummy.rs"]
         mod real_imp;
-    } else if #[cfg(target_env = "msvc")] {
+    } else if #[cfg(all(target_env = "msvc", not(target_arch = "arm")))] {
+        // LLVM does not support unwinding on 32 bit ARM msvc (thumbv7a-pc-windows-msvc)
         #[path = "seh.rs"]
         mod real_imp;
     } else if #[cfg(any(
index 4127c4056f24ed8125bfe974439616a5394b1c53..4e30076246314edb50cdf017b1f1aa00878a3d12 100644 (file)
@@ -880,7 +880,9 @@ pub fn tanh(self) -> f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asinh(self) -> f32 {
-        (self.abs() + ((self * self) + 1.0).sqrt()).ln().copysign(self)
+        let ax = self.abs();
+        let ix = 1.0 / ax;
+        (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
     }
 
     /// Inverse hyperbolic cosine function.
@@ -900,7 +902,11 @@ pub fn asinh(self) -> f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acosh(self) -> f32 {
-        if self < 1.0 { Self::NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() }
+        if self < 1.0 {
+            Self::NAN
+        } else {
+            (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
+        }
     }
 
     /// Inverse hyperbolic tangent function.
index 4ec16c84aa916607c51a6293d221a0e28f205815..6ee295de6163f3807fee36515ad138a61c10dc98 100644 (file)
@@ -587,6 +587,11 @@ fn test_asinh() {
     assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
     // regression test for the catastrophic cancellation fixed in 72486
     assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f32, 60.0f32.sinh().asinh());
+    // mul needed for approximate comparison to be meaningful
+    assert_approx_eq!(1.0f32, 1e-15f32.sinh().asinh() * 1e15f32);
 }
 
 #[test]
@@ -602,6 +607,9 @@ fn test_acosh() {
     assert!(nan.acosh().is_nan());
     assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
     assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh());
 }
 
 #[test]
index cc64258da60d1a63fdc44ef0f72f41d07e2ab976..ec67fdad4f726f50ac11d503701fef61ab8664b5 100644 (file)
@@ -882,7 +882,9 @@ pub fn tanh(self) -> f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asinh(self) -> f64 {
-        (self.abs() + ((self * self) + 1.0).sqrt()).ln().copysign(self)
+        let ax = self.abs();
+        let ix = 1.0 / ax;
+        (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
     }
 
     /// Inverse hyperbolic cosine function.
@@ -902,7 +904,11 @@ pub fn asinh(self) -> f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acosh(self) -> f64 {
-        if self < 1.0 { Self::NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() }
+        if self < 1.0 {
+            Self::NAN
+        } else {
+            (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
+        }
     }
 
     /// Inverse hyperbolic tangent function.
index 12baa68f49b76abcff7f1fb0c778870a608b04bf..5b039d445ce14db91eabb7e6c570d6dc29cf0be5 100644 (file)
@@ -575,6 +575,11 @@ fn test_asinh() {
     assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
     // regression test for the catastrophic cancellation fixed in 72486
     assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f64, 60.0f64.sinh().asinh());
+    // mul needed for approximate comparison to be meaningful
+    assert_approx_eq!(1.0f64, 1e-15f64.sinh().asinh() * 1e15f64);
 }
 
 #[test]
@@ -590,6 +595,9 @@ fn test_acosh() {
     assert!(nan.acosh().is_nan());
     assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
     assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f64, 60.0f64.cosh().acosh());
 }
 
 #[test]
index 535cc1c42fcfda8d859603e0fd89aeddb69f6094..c8d3289ca4a06986bd81ff1ea97ced5996745bd7 100644 (file)
@@ -6,7 +6,9 @@
 
 /// A value which is initialized on the first access.
 ///
-/// This type is a thread-safe `Lazy`, and can be used in statics.
+/// This type is a thread-safe [`LazyCell`], and can be used in statics.
+///
+/// [`LazyCell`]: crate::cell::LazyCell
 ///
 /// # Examples
 ///
index 37413ec62a717aae1c3009696db643df59d09403..16d1fd2a576b97703ae8483cd01953997d5b6e0d 100644 (file)
@@ -7,7 +7,9 @@
 
 /// A synchronization primitive which can be written to only once.
 ///
-/// This type is a thread-safe `OnceCell`.
+/// This type is a thread-safe [`OnceCell`], and can be used in statics.
+///
+/// [`OnceCell`]: crate::cell::OnceCell
 ///
 /// # Examples
 ///
@@ -33,7 +35,7 @@
 #[unstable(feature = "once_cell", issue = "74465")]
 pub struct OnceLock<T> {
     once: Once,
-    // Whether or not the value is initialized is tracked by `state_and_queue`.
+    // Whether or not the value is initialized is tracked by `once.is_completed()`.
     value: UnsafeCell<MaybeUninit<T>>,
     /// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl.
     ///
index cca9c67670161161522d930666161cac896e7596..d5abd9b581c65b67adf203f4e8a5c345e5897de8 100644 (file)
@@ -149,7 +149,11 @@ fn from(t: libc::timespec) -> Timespec {
     }
 }
 
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
+#[cfg(any(
+    all(target_os = "macos", any(not(target_arch = "aarch64"))),
+    target_os = "ios",
+    target_os = "watchos"
+))]
 mod inner {
     use crate::sync::atomic::{AtomicU64, Ordering};
     use crate::sys::cvt;
@@ -265,7 +269,11 @@ fn info_from_bits(bits: u64) -> mach_timebase_info {
     }
 }
 
-#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "watchos")))]
+#[cfg(not(any(
+    all(target_os = "macos", any(not(target_arch = "aarch64"))),
+    target_os = "ios",
+    target_os = "watchos"
+)))]
 mod inner {
     use crate::fmt;
     use crate::mem::MaybeUninit;
@@ -281,7 +289,11 @@ pub struct Instant {
 
     impl Instant {
         pub fn now() -> Instant {
-            Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) }
+            #[cfg(target_os = "macos")]
+            const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW;
+            #[cfg(not(target_os = "macos"))]
+            const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC;
+            Instant { t: Timespec::now(clock_id) }
         }
 
         pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
@@ -312,13 +324,8 @@ pub fn now() -> SystemTime {
         }
     }
 
-    #[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon")))]
-    pub type clock_t = libc::c_int;
-    #[cfg(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon"))]
-    pub type clock_t = libc::c_ulong;
-
     impl Timespec {
-        pub fn now(clock: clock_t) -> Timespec {
+        pub fn now(clock: libc::clockid_t) -> Timespec {
             // Try to use 64-bit time in preparation for Y2038.
             #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32"))]
             {
index ade00750c959cc2b1b096dc32d4092809b77a955..3780980382879cf0e5199cd3c052721798a7a42b 100644 (file)
@@ -1,5 +1,6 @@
 use crate::os::windows::prelude::*;
 
+use crate::borrow::Cow;
 use crate::ffi::OsString;
 use crate::fmt;
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
@@ -719,7 +720,7 @@ fn new(buffer: &'a DirBuff) -> Self {
     }
 }
 impl<'a> Iterator for DirBuffIter<'a> {
-    type Item = (&'a [u16], bool);
+    type Item = (Cow<'a, [u16]>, bool);
     fn next(&mut self) -> Option<Self::Item> {
         use crate::mem::size_of;
         let buffer = &self.buffer?[self.cursor..];
@@ -734,15 +735,19 @@ fn next(&mut self) -> Option<Self::Item> {
         //   `FileNameLength` bytes)
         let (name, is_directory, next_entry) = unsafe {
             let info = buffer.as_ptr().cast::<c::FILE_ID_BOTH_DIR_INFO>();
-            // Guaranteed to be aligned in documentation for
+            // While this is guaranteed to be aligned in documentation for
             // https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_both_dir_info
-            assert!(info.is_aligned());
-            let next_entry = (*info).NextEntryOffset as usize;
-            let name = crate::slice::from_raw_parts(
+            // it does not seem that reality is so kind, and assuming this
+            // caused crashes in some cases (https://github.com/rust-lang/rust/issues/104530)
+            // presumably, this can be blamed on buggy filesystem drivers, but who knows.
+            let next_entry = ptr::addr_of!((*info).NextEntryOffset).read_unaligned() as usize;
+            let length = ptr::addr_of!((*info).FileNameLength).read_unaligned() as usize;
+            let attrs = ptr::addr_of!((*info).FileAttributes).read_unaligned();
+            let name = from_maybe_unaligned(
                 ptr::addr_of!((*info).FileName).cast::<u16>(),
-                (*info).FileNameLength as usize / size_of::<u16>(),
+                length / size_of::<u16>(),
             );
-            let is_directory = ((*info).FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) != 0;
+            let is_directory = (attrs & c::FILE_ATTRIBUTE_DIRECTORY) != 0;
 
             (name, is_directory, next_entry)
         };
@@ -755,13 +760,21 @@ fn next(&mut self) -> Option<Self::Item> {
 
         // Skip `.` and `..` pseudo entries.
         const DOT: u16 = b'.' as u16;
-        match name {
+        match &name[..] {
             [DOT] | [DOT, DOT] => self.next(),
             _ => Some((name, is_directory)),
         }
     }
 }
 
+unsafe fn from_maybe_unaligned<'a>(p: *const u16, len: usize) -> Cow<'a, [u16]> {
+    if p.is_aligned() {
+        Cow::Borrowed(crate::slice::from_raw_parts(p, len))
+    } else {
+        Cow::Owned((0..len).map(|i| p.add(i).read_unaligned()).collect())
+    }
+}
+
 /// Open a link relative to the parent directory, ensure no symlinks are followed.
 fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<File> {
     // This is implemented using the lower level `NtCreateFile` function as
@@ -1117,13 +1130,13 @@ fn copy_handle(f: &File) -> mem::ManuallyDrop<File> {
             if is_directory {
                 let child_dir = open_link_no_reparse(
                     &dir,
-                    name,
+                    &name,
                     c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY,
                 )?;
                 dirlist.push(child_dir);
             } else {
                 for i in 1..=MAX_RETRIES {
-                    let result = open_link_no_reparse(&dir, name, c::SYNCHRONIZE | c::DELETE);
+                    let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
                     match result {
                         Ok(f) => delete(&f)?,
                         // Already deleted, so skip.
index 05023df1bb24b19e1cc1820b6345baa85f1ffdfc..34bdb8bd4612e600d1ea3bb617bbb555172c4f35 100644 (file)
 //!
 //! ## Stack size
 //!
-//! The default stack size for spawned threads is 2 MiB, though this particular stack size is
-//! subject to change in the future. There are two ways to manually specify the stack size for
-//! spawned threads:
+//! The default stack size is platform-dependent and subject to change. Currently it is 2MB on all
+//! Tier-1 platforms. There are two ways to manually specify the stack size for spawned threads:
 //!
 //! * Build the thread with [`Builder`] and pass the desired stack size to [`Builder::stack_size`].
 //! * Set the `RUST_MIN_STACK` environment variable to an integer representing the desired stack
index 6229556c85fee926f0535f3d3867c9b99b808bf3..2e64ae59aff24422cf1862c2e18b863b8201efe1 100644 (file)
@@ -88,6 +88,14 @@ fn instant_math_is_associative() {
     // Changing the order of instant math shouldn't change the results,
     // especially when the expression reduces to X + identity.
     assert_eq!((now + offset) - now, (now - now) + offset);
+
+    // On any platform, `Instant` should have the same resolution as `Duration` (e.g. 1 nanosecond)
+    // or better. Otherwise, math will be non-associative (see #91417).
+    let now = Instant::now();
+    let provided_offset = Duration::from_nanos(1);
+    let later = now + provided_offset;
+    let measured_offset = later - now;
+    assert_eq!(measured_offset, provided_offset);
 }
 
 #[test]
index 15500f7fd3543e099338831d43a260af1cdd5e11..a218910f0ec4d0d40e09b7cd05a0b2f0f1121f51 100644 (file)
@@ -275,7 +275,7 @@ pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
 } // cfg_if!
 
 cfg_if::cfg_if! {
-if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] {
+if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] {
     // We declare these as opaque types. This is fine since you just need to
     // pass them to _GCC_specific_handler and forget about them.
     pub enum EXCEPTION_RECORD {}
index e1a108cea9574a6a772ce946215cef328a8facf1..a59dc4f87a68ebbf009f5bab47ff2aa1d5f04e52 100644 (file)
@@ -383,9 +383,9 @@ dependencies = [
 
 [[package]]
 name = "ntapi"
-version = "0.3.7"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
+checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc"
 dependencies = [
  "winapi",
 ]
@@ -607,9 +607,9 @@ dependencies = [
 
 [[package]]
 name = "sysinfo"
-version = "0.24.2"
+version = "0.26.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2809487b962344ca55d9aea565f9ffbcb6929780802217acc82561f6746770"
+checksum = "c375d5fd899e32847b8566e10598d6e9f1d9b55ec6de3cdf9e7da4bdc51371bc"
 dependencies = [
  "cfg-if",
  "core-foundation-sys",
index f74738437ea3a2e7ac0bd91b536b9ed8236e6c42..813c8075605993ec5cfa2ee537833c1ebc3918d6 100644 (file)
@@ -54,7 +54,7 @@ xz2 = "0.1"
 walkdir = "2"
 
 # Dependencies needed by the build-metrics feature
-sysinfo = { version = "0.24.1", optional = true }
+sysinfo = { version = "0.26.0", optional = true }
 
 [target.'cfg(windows)'.dependencies.winapi]
 version = "0.3"
index 54906a4918bc12b3d67d90853b38f97a511abe9d..0deed3f990d033ab3a4be39ae379bb68f28badfa 100644 (file)
@@ -1121,13 +1121,18 @@ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
     fn run(self, builder: &Builder<'_>) -> Interned<PathBuf> {
         let compiler = self.compiler;
         let host_dir = builder.out.join(&compiler.host.triple);
-        let sysroot = if compiler.stage == 0 {
-            host_dir.join("stage0-sysroot")
-        } else if builder.download_rustc() {
-            host_dir.join("ci-rustc-sysroot")
-        } else {
-            host_dir.join(format!("stage{}", compiler.stage))
+
+        let sysroot_dir = |stage| {
+            if stage == 0 {
+                host_dir.join("stage0-sysroot")
+            } else if builder.download_rustc() && compiler.stage != builder.top_stage {
+                host_dir.join("ci-rustc-sysroot")
+            } else {
+                host_dir.join(format!("stage{}", stage))
+            }
         };
+        let sysroot = sysroot_dir(compiler.stage);
+
         let _ = fs::remove_dir_all(&sysroot);
         t!(fs::create_dir_all(&sysroot));
 
@@ -1138,9 +1143,15 @@ fn run(self, builder: &Builder<'_>) -> Interned<PathBuf> {
                 "Cross-compiling is not yet supported with `download-rustc`",
             );
 
-            // #102002, cleanup stage1 and stage0-sysroot folders when using download-rustc so people don't use old versions of the toolchain by accident.
-            let _ = fs::remove_dir_all(host_dir.join("stage1"));
-            let _ = fs::remove_dir_all(host_dir.join("stage0-sysroot"));
+            // #102002, cleanup old toolchain folders when using download-rustc so people don't use them by accident.
+            for stage in 0..=2 {
+                if stage != compiler.stage {
+                    let dir = sysroot_dir(stage);
+                    if !dir.ends_with("ci-rustc-sysroot") {
+                        let _ = fs::remove_dir_all(dir);
+                    }
+                }
+            }
 
             // Copy the compiler into the correct sysroot.
             let ci_rustc_dir =
index c61025b556aa5702941f43215aebc73144aaa59e..babf09d2b93349605ed3c8b2965635e7932a352b 100644 (file)
@@ -1511,19 +1511,25 @@ pub(crate) fn llvm_link_shared(&self) -> bool {
 
     /// Return whether we will use a downloaded, pre-compiled version of rustc, or just build from source.
     pub(crate) fn download_rustc(&self) -> bool {
-        static DOWNLOAD_RUSTC: OnceCell<bool> = OnceCell::new();
+        self.download_rustc_commit().is_some()
+    }
+
+    pub(crate) fn download_rustc_commit(&self) -> Option<&'static str> {
+        static DOWNLOAD_RUSTC: OnceCell<Option<String>> = OnceCell::new();
         if self.dry_run() && DOWNLOAD_RUSTC.get().is_none() {
             // avoid trying to actually download the commit
-            return false;
+            return None;
         }
 
-        *DOWNLOAD_RUSTC.get_or_init(|| match &self.download_rustc_commit {
-            None => false,
-            Some(commit) => {
-                self.download_ci_rustc(commit);
-                true
-            }
-        })
+        DOWNLOAD_RUSTC
+            .get_or_init(|| match &self.download_rustc_commit {
+                None => None,
+                Some(commit) => {
+                    self.download_ci_rustc(commit);
+                    Some(commit.clone())
+                }
+            })
+            .as_deref()
     }
 
     pub(crate) fn initial_rustfmt(&self) -> Option<PathBuf> {
index 451febddc88ceee13b32ae9b7aed99a487d4ad08..c823dc7968465e84a0553676654ebbbfcd153d50 100644 (file)
@@ -97,7 +97,7 @@ pub(crate) fn persist(&self, build: &Build) {
             cpu_threads_count: system.cpus().len(),
             cpu_model: system.cpus()[0].brand().into(),
 
-            memory_total_bytes: system.total_memory() * 1024,
+            memory_total_bytes: system.total_memory(),
         };
         let steps = std::mem::take(&mut state.finished_steps);
 
index fd362b8367cc00c4ebd920079dcb7956655315a6..38873cee93bd982475849358869314fca0a41eac 100644 (file)
@@ -1011,6 +1011,8 @@ fn run(self, builder: &Builder<'_>) {
                 //        instead of hard-coding this test
                 if entry.file_name() == "link_to_definition" {
                     cargo.env("RUSTDOCFLAGS", "-Zunstable-options --generate-link-to-definition");
+                } else if entry.file_name() == "scrape_examples" {
+                    cargo.arg("-Zrustdoc-scrape-examples=examples");
                 }
                 builder.run(&mut cargo);
             }
@@ -1401,6 +1403,7 @@ fn run(self, builder: &Builder<'_>) {
 
         cmd.arg("--src-base").arg(builder.src.join("src/test").join(suite));
         cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));
+        cmd.arg("--sysroot-base").arg(builder.sysroot(compiler));
         cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
         cmd.arg("--suite").arg(suite);
         cmd.arg("--mode").arg(mode);
@@ -1670,6 +1673,10 @@ fn run(self, builder: &Builder<'_>) {
 
         cmd.arg("--channel").arg(&builder.config.channel);
 
+        if let Some(commit) = builder.config.download_rustc_commit() {
+            cmd.env("FAKE_DOWNLOAD_RUSTC_PREFIX", format!("/rustc/{commit}"));
+        }
+
         builder.ci_env.force_coloring_in_ci(&mut cmd);
 
         builder.info(&format!(
index ed0d9e9902b995528b86b686a9d445ac07bf4a27..3f8dcd03d2db1e396fd994bd43521c76473f02bd 100644 (file)
@@ -1 +1 @@
-0.13.1
\ No newline at end of file
+0.13.2
\ No newline at end of file
index 0da69202e679fc41cdbc81861be29a42107a7922..1e7b4fe15b68cad5c59d74e96df437a4d4cf57d9 100644 (file)
@@ -9,7 +9,6 @@ path = "lib.rs"
 [dependencies]
 arrayvec = { version = "0.7", default-features = false }
 askama = { version = "0.11", default-features = false, features = ["config"] }
-atty = "0.2"
 itertools = "0.10.1"
 minifier = "0.2.2"
 once_cell = "1.10.0"
index 789dd398be50d7298da6dd2bdbfae5e9df742142..e0cdb86d9d1dc152e47f97f85e5ea4456ed0f2ea 100644 (file)
@@ -418,7 +418,7 @@ fn println_condition(condition: Condition) {
             ) {
                 Ok(p) => p,
                 Err(e) => {
-                    diag.struct_err(&e.to_string()).emit();
+                    diag.struct_err(e).emit();
                     return Err(1);
                 }
             };
@@ -561,7 +561,7 @@ fn println_condition(condition: Condition) {
             ) {
                 Ok(p) => p,
                 Err(e) => {
-                    diag.struct_err(&e.to_string()).emit();
+                    diag.struct_err(e).emit();
                     return Err(1);
                 }
             };
index 8731efb5e87469df5771f938ef9dc1521d9d7902..647eb69d9a6f6e8d0a6923c0f0026679c86d2330 100644 (file)
@@ -2915,7 +2915,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
         );
 
         if line_ranges.len() > 1 {
-            write!(w, r#"<span class="prev">&pr;</span> <span class="next">&sc;</span>"#);
+            write!(w, r#"<button class="prev">&pr;</button> <button class="next">&sc;</button>"#);
         }
 
         // Look for the example file in the source map if it exists, otherwise return a dummy span
index ac11a860a4f0b88af87cc192f97674afe7c3afa0..c95f117a205886dc06c5c32937884b07d3fd9d2a 100644 (file)
@@ -19,8 +19,8 @@
     collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference,
     item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls,
     render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre,
-    render_impl, render_rightside, render_stability_since_raw, AssocItemLink, Context,
-    ImplRenderingParameters,
+    render_impl, render_rightside, render_stability_since_raw,
+    render_stability_since_raw_with_extra, AssocItemLink, Context, ImplRenderingParameters,
 };
 use crate::clean;
 use crate::config::ModuleSorting;
@@ -1267,30 +1267,30 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
             document_non_exhaustive_header(it)
         );
         document_non_exhaustive(w, it);
+        write!(w, "<div class=\"variants\">");
         for variant in e.variants() {
             let id = cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.unwrap()));
             write!(
                 w,
-                "<h3 id=\"{id}\" class=\"variant small-section-header\">\
-                    <a href=\"#{id}\" class=\"anchor field\"></a>\
-                    <code>{name}",
+                "<section id=\"{id}\" class=\"variant\">\
+                    <a href=\"#{id}\" class=\"anchor\"></a>",
                 id = id,
-                name = variant.name.unwrap()
             );
-            if let clean::VariantItem(clean::Variant::Tuple(ref s)) = *variant.kind {
-                w.write_str("(");
-                print_tuple_struct_fields(w, cx, s);
-                w.write_str(")");
-            }
-            w.write_str("</code>");
-            render_stability_since_raw(
+            render_stability_since_raw_with_extra(
                 w,
                 variant.stable_since(tcx),
                 variant.const_stability(tcx),
                 it.stable_since(tcx),
                 it.const_stable_since(tcx),
+                " rightside",
             );
-            w.write_str("</h3>");
+            write!(w, "<h3 class=\"code-header\">{name}", name = variant.name.unwrap());
+            if let clean::VariantItem(clean::Variant::Tuple(ref s)) = *variant.kind {
+                w.write_str("(");
+                print_tuple_struct_fields(w, cx, s);
+                w.write_str(")");
+            }
+            w.write_str("</h3></section>");
 
             use crate::clean::Variant;
 
@@ -1324,7 +1324,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
                             write!(
                                 w,
                                 "<div class=\"sub-variant-field\">\
-                                 <span id=\"{id}\" class=\"variant small-section-header\">\
+                                 <span id=\"{id}\" class=\"small-section-header\">\
                                      <a href=\"#{id}\" class=\"anchor field\"></a>\
                                      <code>{f}:&nbsp;{t}</code>\
                                  </span>",
@@ -1343,6 +1343,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
 
             document(w, cx, variant, Some(it), HeadingOffset::H4);
         }
+        write!(w, "</div>");
     }
     let def_id = it.item_id.expect_def_id();
     render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
index 50135d6019006633eb804053085c1b8bf95a2b51..54e296959b0ec97fb569a2210d1e0054cece775f 100644 (file)
@@ -287,8 +287,11 @@ pub(crate) fn print_src(
             }
         }
         SourceContext::Embedded { offset, needs_expansion } => {
-            extra =
-                if needs_expansion { Some(r#"<span class="expand">&varr;</span>"#) } else { None };
+            extra = if needs_expansion {
+                Some(r#"<button class="expand">&varr;</button>"#)
+            } else {
+                None
+            };
             for line_number in 1..=lines {
                 let line = line_number + offset;
                 writeln!(line_numbers, "<span>{line}</span>")
index 5ec2fe47e0156bc0e44157089fe73295261d071a..accd609306978c66191ab93e52b1fb9c53272ecd 100644 (file)
@@ -384,8 +384,7 @@ img {
 
 .sidebar {
        font-size: 0.875rem;
-       width: 200px;
-       min-width: 200px;
+       flex: 0 0 200px;
        overflow-y: scroll;
        position: sticky;
        height: 100vh;
@@ -394,12 +393,7 @@ img {
 }
 
 .rustdoc.source .sidebar {
-       width: 50px;
-       min-width: 0px;
-       max-width: 300px;
-       flex-grow: 0;
-       flex-shrink: 0;
-       flex-basis: auto;
+       flex-basis: 50px;
        border-right: 1px solid;
        overflow-x: hidden;
        /* The sidebar is by default hidden  */
@@ -420,7 +414,7 @@ img {
 
 .source-sidebar-expanded .source .sidebar {
        overflow-y: auto;
-       width: 300px;
+       flex-basis: 300px;
 }
 
 .source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) {
@@ -706,8 +700,6 @@ a {
 }
 
 .small-section-header {
-       display: flex;
-       justify-content: space-between;
        position: relative;
 }
 
@@ -715,7 +707,7 @@ a {
        display: initial;
 }
 
-.impl:hover > .anchor, .trait-impl:hover > .anchor {
+.impl:hover > .anchor, .trait-impl:hover > .anchor, .variant:hover > .anchor {
        display: inline-block;
        position: absolute;
 }
@@ -1234,12 +1226,6 @@ a.test-arrow:hover {
        font-size: 1.25rem;
 }
 
-h3.variant {
-       font-weight: 600;
-       font-size: 1.125rem;
-       margin-bottom: 10px;
-}
-
 .sub-variant h4 {
        font-size: 1rem;
        font-weight: 400;
@@ -1392,6 +1378,12 @@ h3.variant {
        background-color: var(--button-background-color);
        border: 1px solid var(--border-color);
        border-radius: 2px;
+       color: var(--settings-button-color);
+}
+
+#settings-menu > a:hover, #settings-menu > a:focus,
+#help-button > a:hover, #help-button > a:focus {
+       border-color: var(--settings-button-border-focus);
 }
 
 #copy-path {
@@ -1439,6 +1431,9 @@ kbd {
        border: solid 1px var(--border-color);
        border-radius: 3px;
        cursor: default;
+       color: var(--kbd--color);
+       background-color: var(--kbd-background);
+       box-shadow: inset 0 -1px 0 var(--kbd-box-shadow-color);
 }
 
 ul.all-items > li {
@@ -1701,6 +1696,7 @@ in storage.js
                z-index: 11;
                /* Reduce height slightly to account for mobile topbar. */
                height: calc(100vh - 45px);
+               width: 200px;
        }
 
        /* The source view uses a different design for the sidebar toggle, and doesn't have a topbar,
@@ -1908,6 +1904,7 @@ in storage.js
        }
 }
 
+.variant,
 .implementors-toggle > summary,
 .impl,
 #implementors-list > .docblock,
@@ -1919,6 +1916,7 @@ in storage.js
        margin-bottom: 0.75em;
 }
 
+.variants > .docblock,
 .impl-items > .rustdoc-toggle[open]:not(:last-child),
 .methods > .rustdoc-toggle[open]:not(:last-child),
 .implementors-toggle[open]:not(:last-child) {
@@ -1970,6 +1968,12 @@ in storage.js
        top: 0.25em;
        z-index: 1;
        cursor: pointer;
+       padding: 0;
+       background: none;
+       border: none;
+       /* iOS button gradient: https://stackoverflow.com/q/5438567 */
+       -webkit-appearance: none;
+       opacity: 1;
 }
 .scraped-example .code-wrapper .prev {
        right: 2.25em;
index 0e4dacb28f7cd0911b1855998bd4f49df402363f..952d3e833fbfd0f420a57b9f05cff74b364fbccd 100644 (file)
@@ -7,6 +7,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
        --main-background-color: #0f1419;
        --main-color: #c5c5c5;
        --settings-input-color: #ffb454;
+       --settings-button-color: #fff;
+       --settings-button-border-focus: #e0e0e0;
        --sidebar-background-color: #14191f;
        --sidebar-background-color-hover: rgba(70, 70, 70, 0.33);
        --code-block-background-color: #191f26;
@@ -67,6 +69,9 @@ Original by Dempfi (https://github.com/dempfi/ayu)
        --target-border-color: rgba(255, 180, 76, 0.85);
        --tooltip-background-color: #314559;
        --tooltip-color: #c5c5c5;
+       --kbd-color: #c5c5c5;
+       --kbd-background: #314559;
+       --kbd-box-shadow-color: #5c6773;
        --rust-logo-filter: drop-shadow(1px 0 0px #fff)
                drop-shadow(0 1px 0 #fff)
                drop-shadow(-1px 0 0 #fff)
@@ -193,25 +198,10 @@ pre.rust .kw {}
 pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, pre.rust .attribute {}
 pre.rust .kw-2, pre.rust .prelude-ty {}
 
-kbd {
-       color: #c5c5c5;
-       background-color: #314559;
-       box-shadow: inset 0 -1px 0 #5c6773;
-}
-
-#settings-menu > a, #help-button > a {
-       color: #fff;
-}
-
 #settings-menu > a img {
        filter: invert(100);
 }
 
-#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
-       border-color: #e0e0e0;
-}
-
 .search-results .result-name span.alias {
        color: #c5c5c5;
 }
index 8e00591179f1f201e0dff4cf530f990151e4f440..6327083f6aea7f75afec6bc9fd301254cd6af1ae 100644 (file)
@@ -2,6 +2,8 @@
        --main-background-color: #353535;
        --main-color: #ddd;
        --settings-input-color: #2196f3;
+       --settings-button-color: #000;
+       --settings-button-border-focus: #ffb900;
        --sidebar-background-color: #505050;
        --sidebar-background-color-hover: #676767;
        --code-block-background-color: #2A2A2A;
@@ -62,6 +64,9 @@
        --target-border-color: #bb7410;
        --tooltip-background-color: #000;
        --tooltip-color: #fff;
+       --kbd-color: #000;
+       --kbd-background: #fafbfc;
+       --kbd-box-shadow-color: #c6cbd1;
        --rust-logo-filter: drop-shadow(1px 0 0px #fff)
                drop-shadow(0 1px 0 #fff)
                drop-shadow(-1px 0 0 #fff)
@@ -98,21 +103,6 @@ details.rustdoc-toggle > summary::before {
        color: #888;
 }
 
-kbd {
-       color: #000;
-       background-color: #fafbfc;
-       box-shadow: inset 0 -1px 0 #c6cbd1;
-}
-
-#settings-menu > a, #help-button > a {
-       color: #000;
-}
-
-#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
-       border-color: #ffb900;
-}
-
 .search-results .result-name span.alias {
        color: #fff;
 }
index e23e3682b166ec3c459d95b56550bdb13698410c..0ea709e3e8d5bff5f65572a68b06917a1a89357d 100644 (file)
@@ -2,6 +2,8 @@
        --main-background-color: white;
        --main-color: black;
        --settings-input-color: #2196f3;
+       --settings-button-color: #000;
+       --settings-button-border-focus: #717171;
        --sidebar-background-color: #F5F5F5;
        --sidebar-background-color-hover: #E0E0E0;
        --code-block-background-color: #F5F5F5;
@@ -62,6 +64,9 @@
        --target-border-color: #ad7c37;
        --tooltip-background-color: #fdffd3;
        --tooltip-color: #fff;
+       --kbd-color: #000;
+       --kbd-background: #fafbfc;
+       --kbd-box-shadow-color: #c6cbd1;
        --rust-logo-filter: initial;
        /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
        --crate-search-div-filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg)
@@ -91,21 +96,6 @@ body.source .example-wrap pre.rust a {
        color: #888;
 }
 
-kbd {
-       color: #000;
-       background-color: #fafbfc;
-       box-shadow: inset 0 -1px 0 #c6cbd1;
-}
-
-#settings-menu > a, #help-button > a {
-       color: #000;
-}
-
-#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
-       border-color: #717171;
-}
-
 .search-results .result-name span.alias {
        color: #000;
 }
index da08c33e27f05f0d9fa3cdf068e28d23774c025c..2a109ffbc608d3184a18a6ac1a51c3220e769147 100644 (file)
@@ -792,7 +792,7 @@ function loadCss(cssUrl) {
             // This means when the window is resized, we need to redo the layout.
             const base = window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE;
             const force_visible = base.NOTABLE_FORCE_VISIBLE;
-            hideNotable();
+            hideNotable(false);
             if (force_visible) {
                 showNotable(base);
                 base.NOTABLE_FORCE_VISIBLE = true;
@@ -843,7 +843,7 @@ function loadCss(cssUrl) {
             // Make this function idempotent.
             return;
         }
-        hideNotable();
+        hideNotable(false);
         const ty = e.getAttribute("data-ty");
         const wrapper = document.createElement("div");
         wrapper.innerHTML = "<div class=\"docblock\">" + window.NOTABLE_TRAITS[ty] + "</div>";
@@ -880,7 +880,7 @@ function loadCss(cssUrl) {
                 return;
             }
             if (!e.NOTABLE_FORCE_VISIBLE && !elemIsInParent(event.relatedTarget, e)) {
-                hideNotable();
+                hideNotable(true);
             }
         };
     }
@@ -900,14 +900,16 @@ function loadCss(cssUrl) {
             // To work around this, make sure the click finishes being dispatched before
             // hiding the popover. Since `hideNotable()` is idempotent, this makes Safari behave
             // consistently with the other two.
-            setTimeout(hideNotable, 0);
+            setTimeout(() => hideNotable(false), 0);
         }
     }
 
-    function hideNotable() {
+    function hideNotable(focus) {
         if (window.CURRENT_NOTABLE_ELEMENT) {
             if (window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE) {
-                window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.focus();
+                if (focus) {
+                    window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.focus();
+                }
                 window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false;
             }
             const body = document.getElementsByTagName("body")[0];
@@ -920,7 +922,7 @@ function loadCss(cssUrl) {
         e.onclick = function() {
             this.NOTABLE_FORCE_VISIBLE = this.NOTABLE_FORCE_VISIBLE ? false : true;
             if (window.CURRENT_NOTABLE_ELEMENT && !this.NOTABLE_FORCE_VISIBLE) {
-                hideNotable();
+                hideNotable(true);
             } else {
                 showNotable(this);
                 window.CURRENT_NOTABLE_ELEMENT.setAttribute("tabindex", "0");
@@ -943,7 +945,7 @@ function loadCss(cssUrl) {
             }
             if (!this.NOTABLE_FORCE_VISIBLE &&
                 !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT)) {
-                hideNotable();
+                hideNotable(true);
             }
         };
     });
@@ -1054,7 +1056,7 @@ function loadCss(cssUrl) {
         onEachLazy(document.querySelectorAll(".search-form .popover"), elem => {
             elem.style.display = "none";
         });
-        hideNotable();
+        hideNotable(false);
     };
 
     /**
index b4d4150cddbb8829658d75c19b5fb33d75beb3dd..1f87f95563ad550d789ec580f3d4eff64fcb71ce 100644 (file)
@@ -58,7 +58,7 @@ pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf {
 }
 
 pub(crate) fn static_filename(filename: &str, contents: &[u8]) -> PathBuf {
-    let filename = filename.rsplit("/").next().unwrap();
+    let filename = filename.rsplit('/').next().unwrap();
     suffix_path(filename, &static_suffix(contents))
 }
 
index 4efcfc510a255c67420218592c9ee0832e48c6f0..df13e597f1fdce383482e2f8ef37baef21dacc73 100644 (file)
@@ -40,7 +40,7 @@
     {%- endif -%}
     <script defer src="{{static_root_path|safe}}{{files.main_js}}"></script> {#- -#}
     {%- if layout.scrape_examples_extension -%}
-    <script defer src="{{page.root_path|safe}}{{files.scrape_examples_js}}"></script> {#- -#}
+    <script defer src="{{static_root_path|safe}}{{files.scrape_examples_js}}"></script> {#- -#}
     {%- endif -%}
     <noscript> {#- -#}
         <link rel="stylesheet" {# -#}
index 1982c066b6ff28f2dab608625ea6d3d7d852407d..1a84ec650474d28b916f4c62cfab234515490f81 100644 (file)
@@ -8,6 +8,7 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(drain_filter)]
+#![feature(is_terminal)]
 #![feature(let_chains)]
 #![feature(test)]
 #![feature(never_type)]
@@ -69,7 +70,7 @@
 
 use std::default::Default;
 use std::env::{self, VarError};
-use std::io;
+use std::io::{self, IsTerminal};
 use std::process;
 
 use rustc_driver::abort_on_err;
@@ -179,7 +180,7 @@ fn init_logging() {
     let color_logs = match std::env::var("RUSTDOC_LOG_COLOR").as_deref() {
         Ok("always") => true,
         Ok("never") => false,
-        Ok("auto") | Err(VarError::NotPresent) => atty::is(atty::Stream::Stdout),
+        Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
         Ok(value) => early_error(
             ErrorOutputType::default(),
             &format!("invalid log color value '{}': expected one of always, never, or auto", value),
diff --git a/src/test/assembly/is_aligned.rs b/src/test/assembly/is_aligned.rs
new file mode 100644 (file)
index 0000000..04b5de8
--- /dev/null
@@ -0,0 +1,58 @@
+// assembly-output: emit-asm
+// min-llvm-version: 14.0
+// only-x86_64
+// revisions: opt-speed opt-size
+// [opt-speed] compile-flags: -Copt-level=1
+// [opt-size] compile-flags: -Copt-level=s
+#![crate_type="rlib"]
+
+#![feature(core_intrinsics)]
+#![feature(pointer_is_aligned)]
+
+// CHECK-LABEL: is_aligned_to_unchecked
+// CHECK: decq
+// CHECK-NEXT: testq
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub unsafe fn is_aligned_to_unchecked(ptr: *const u8, align: usize) -> bool {
+    unsafe {
+        std::intrinsics::assume(align.is_power_of_two())
+    }
+    ptr.is_aligned_to(align)
+}
+
+// CHECK-LABEL: is_aligned_1
+// CHECK: movb $1
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_1(ptr: *const u8) -> bool {
+    ptr.is_aligned()
+}
+
+// CHECK-LABEL: is_aligned_2
+// CHECK: testb $1
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_2(ptr: *const u16) -> bool {
+    ptr.is_aligned()
+}
+
+// CHECK-LABEL: is_aligned_4
+// CHECK: testb $3
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_4(ptr: *const u32) -> bool {
+    ptr.is_aligned()
+}
+
+// CHECK-LABEL: is_aligned_8
+// CHECK: testb $7
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_8(ptr: *const u64) -> bool {
+    ptr.is_aligned()
+}
diff --git a/src/test/codegen/iter-repeat-n-trivial-drop.rs b/src/test/codegen/iter-repeat-n-trivial-drop.rs
new file mode 100644 (file)
index 0000000..20e1d9b
--- /dev/null
@@ -0,0 +1,56 @@
+// compile-flags: -O
+// only-x86_64
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+#![feature(iter_repeat_n)]
+
+#[derive(Clone)]
+pub struct NotCopy(u16);
+
+impl Drop for NotCopy {
+    fn drop(&mut self) {}
+}
+
+// For a type where `Drop::drop` doesn't do anything observable and a clone is the
+// same as a move, make sure that the extra case for the last item disappears.
+
+#[no_mangle]
+// CHECK-LABEL: @iter_repeat_n_next
+pub fn iter_repeat_n_next(it: &mut std::iter::RepeatN<NotCopy>) -> Option<NotCopy> {
+    // CHECK-NEXT: start:
+    // CHECK-NOT: br
+    // CHECK: %[[COUNT:.+]] = load i64
+    // CHECK-NEXT: %[[COUNT_ZERO:.+]] = icmp eq i64 %[[COUNT]], 0
+    // CHECK-NEXT: br i1 %[[COUNT_ZERO]], label %[[EMPTY:.+]], label %[[NOT_EMPTY:.+]]
+
+    // CHECK: [[NOT_EMPTY]]:
+    // CHECK-NEXT: %[[DEC:.+]] = add i64 %[[COUNT]], -1
+    // CHECK-NEXT: store i64 %[[DEC]]
+    // CHECK-NOT: br
+    // CHECK: %[[VAL:.+]] = load i16
+    // CHECK-NEXT: br label %[[EMPTY]]
+
+    // CHECK: [[EMPTY]]:
+    // CHECK-NOT: br
+    // CHECK: phi i16 [ undef, %start ], [ %[[VAL]], %[[NOT_EMPTY]] ]
+    // CHECK-NOT: br
+    // CHECK: ret
+
+    it.next()
+}
+
+// And as a result, using the iterator can optimize without special cases for
+// the last iteration, like `memset`ing all the items in one call.
+
+#[no_mangle]
+// CHECK-LABEL: @vec_extend_via_iter_repeat_n
+pub fn vec_extend_via_iter_repeat_n() -> Vec<u8> {
+    // CHECK: %[[ADDR:.+]] = tail call dereferenceable_or_null(1234) ptr @__rust_alloc(i64 1234, i64 1)
+    // CHECK: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(1234) %[[ADDR]], i8 42, i64 1234,
+
+    let n = 1234_usize;
+    let mut v = Vec::with_capacity(n);
+    v.extend(std::iter::repeat_n(42_u8, n));
+    v
+}
diff --git a/src/test/codegen/unchecked_shifts.rs b/src/test/codegen/unchecked_shifts.rs
new file mode 100644 (file)
index 0000000..60d0cb0
--- /dev/null
@@ -0,0 +1,66 @@
+// compile-flags: -O
+// min-llvm-version: 15.0 (LLVM 13 in CI does this differently from submodule LLVM)
+// ignore-debug (because unchecked is checked in debug)
+
+#![crate_type = "lib"]
+#![feature(unchecked_math)]
+
+// CHECK-LABEL: @unchecked_shl_unsigned_same
+#[no_mangle]
+pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 {
+    // CHECK-NOT: and i32
+    // CHECK: shl i32 %a, %b
+    // CHECK-NOT: and i32
+    a.unchecked_shl(b)
+}
+
+// CHECK-LABEL: @unchecked_shl_unsigned_smaller
+#[no_mangle]
+pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 {
+    // This uses -DAG to avoid failing on irrelevant reorderings,
+    // like emitting the truncation earlier.
+
+    // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 65536
+    // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
+    // CHECK-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16
+    // CHECK-DAG: shl i16 %a, %[[TRUNC]]
+    a.unchecked_shl(b)
+}
+
+// CHECK-LABEL: @unchecked_shl_unsigned_bigger
+#[no_mangle]
+pub unsafe fn unchecked_shl_unsigned_bigger(a: u64, b: u32) -> u64 {
+    // CHECK: %[[EXT:.+]] = zext i32 %b to i64
+    // CHECK: shl i64 %a, %[[EXT]]
+    a.unchecked_shl(b)
+}
+
+// CHECK-LABEL: @unchecked_shr_signed_same
+#[no_mangle]
+pub unsafe fn unchecked_shr_signed_same(a: i32, b: u32) -> i32 {
+    // CHECK-NOT: and i32
+    // CHECK: ashr i32 %a, %b
+    // CHECK-NOT: and i32
+    a.unchecked_shr(b)
+}
+
+// CHECK-LABEL: @unchecked_shr_signed_smaller
+#[no_mangle]
+pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 {
+    // This uses -DAG to avoid failing on irrelevant reorderings,
+    // like emitting the truncation earlier.
+
+    // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 32768
+    // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
+    // CHECK-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16
+    // CHECK-DAG: ashr i16 %a, %[[TRUNC]]
+    a.unchecked_shr(b)
+}
+
+// CHECK-LABEL: @unchecked_shr_signed_bigger
+#[no_mangle]
+pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 {
+    // CHECK: %[[EXT:.+]] = zext i32 %b to i64
+    // CHECK: ashr i64 %a, %[[EXT]]
+    a.unchecked_shr(b)
+}
index 60fb06d409c490b86d2ec556382a20016fde0cdd..2227de3b377659530471d21b43a191869fc60566 100644 (file)
@@ -76,9 +76,9 @@
 // Const generic parameter
 // cdb-command:x a!function_names::const_generic_fn*
 // cdb-check:[...] a!function_names::const_generic_fn_bool<false> (void)
-// cdb-check:[...] a!function_names::const_generic_fn_non_int<CONST$6348c650c7b26618> (void)
 // cdb-check:[...] a!function_names::const_generic_fn_unsigned_int<14> (void)
 // cdb-check:[...] a!function_names::const_generic_fn_signed_int<-7> (void)
+// cdb-check:[...] a!function_names::const_generic_fn_non_int<CONST$6348c650c7b26618> (void)
 
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
diff --git a/src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir b/src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir
new file mode 100644 (file)
index 0000000..5b18508
--- /dev/null
@@ -0,0 +1,74 @@
+// MIR for `foo` after PreCodegen
+
+fn foo(_1: Option<String>) -> i32 {
+    debug s => _1;                       // in scope 0 at $DIR/string.rs:+0:12: +0:13
+    let mut _0: i32;                     // return place in scope 0 at $DIR/string.rs:+0:34: +0:37
+    let mut _2: &std::string::String;    // in scope 0 at $DIR/string.rs:+2:14: +2:17
+    let mut _3: &str;                    // in scope 0 at $DIR/string.rs:+2:14: +2:17
+    let mut _4: bool;                    // in scope 0 at $DIR/string.rs:+2:14: +2:17
+    let mut _5: isize;                   // in scope 0 at $DIR/string.rs:+2:9: +2:18
+    let _6: std::option::Option<std::string::String>; // in scope 0 at $DIR/string.rs:+3:9: +3:10
+    let mut _7: bool;                    // in scope 0 at $DIR/string.rs:+5:1: +5:2
+    scope 1 {
+        debug s => _6;                   // in scope 1 at $DIR/string.rs:+3:9: +3:10
+    }
+
+    bb0: {
+        _7 = const false;                // scope 0 at $DIR/string.rs:+1:11: +1:12
+        _7 = const true;                 // scope 0 at $DIR/string.rs:+1:11: +1:12
+        _5 = discriminant(_1);           // scope 0 at $DIR/string.rs:+1:11: +1:12
+        switchInt(move _5) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/string.rs:+1:5: +1:12
+    }
+
+    bb1: {
+        StorageLive(_6);                 // scope 0 at $DIR/string.rs:+3:9: +3:10
+        _7 = const false;                // scope 0 at $DIR/string.rs:+3:9: +3:10
+        _6 = move _1;                    // scope 0 at $DIR/string.rs:+3:9: +3:10
+        _0 = const 4321_i32;             // scope 1 at $DIR/string.rs:+3:14: +3:18
+        drop(_6) -> bb6;                 // scope 0 at $DIR/string.rs:+3:17: +3:18
+    }
+
+    bb2: {
+        _2 = &((_1 as Some).0: std::string::String); // scope 0 at $DIR/string.rs:+2:14: +2:17
+        _3 = <String as Deref>::deref(move _2) -> bb3; // scope 0 at $DIR/string.rs:+2:14: +2:17
+                                         // mir::Constant
+                                         // + span: $DIR/string.rs:9:14: 9:17
+                                         // + literal: Const { ty: for<'a> fn(&'a String) -> &'a <String as Deref>::Target {<String as Deref>::deref}, val: Value(<ZST>) }
+    }
+
+    bb3: {
+        _4 = <str as PartialEq>::eq(_3, const "a") -> bb4; // scope 0 at $DIR/string.rs:+2:14: +2:17
+                                         // mir::Constant
+                                         // + span: $DIR/string.rs:9:14: 9:17
+                                         // + literal: Const { ty: for<'a, 'b> fn(&'a str, &'b str) -> bool {<str as PartialEq>::eq}, val: Value(<ZST>) }
+                                         // mir::Constant
+                                         // + span: $DIR/string.rs:9:14: 9:17
+                                         // + literal: Const { ty: &str, val: Value(Slice(..)) }
+    }
+
+    bb4: {
+        switchInt(move _4) -> [false: bb1, otherwise: bb5]; // scope 0 at $DIR/string.rs:+2:14: +2:17
+    }
+
+    bb5: {
+        _0 = const 1234_i32;             // scope 0 at $DIR/string.rs:+2:22: +2:26
+        goto -> bb9;                     // scope 0 at $DIR/string.rs:+2:22: +2:26
+    }
+
+    bb6: {
+        StorageDead(_6);                 // scope 0 at $DIR/string.rs:+3:17: +3:18
+        goto -> bb9;                     // scope 0 at $DIR/string.rs:+3:17: +3:18
+    }
+
+    bb7: {
+        return;                          // scope 0 at $DIR/string.rs:+5:2: +5:2
+    }
+
+    bb8: {
+        drop(_1) -> bb7;                 // scope 0 at $DIR/string.rs:+5:1: +5:2
+    }
+
+    bb9: {
+        switchInt(_7) -> [false: bb7, otherwise: bb8]; // scope 0 at $DIR/string.rs:+5:1: +5:2
+    }
+}
diff --git a/src/test/mir-opt/deref-patterns/string.rs b/src/test/mir-opt/deref-patterns/string.rs
new file mode 100644 (file)
index 0000000..3a99c44
--- /dev/null
@@ -0,0 +1,12 @@
+// compile-flags: -Z mir-opt-level=0 -C panic=abort
+
+#![feature(string_deref_patterns)]
+#![crate_type = "lib"]
+
+// EMIT_MIR string.foo.PreCodegen.after.mir
+pub fn foo(s: Option<String>) -> i32 {
+    match s {
+        Some("a") => 1234,
+        s => 4321,
+    }
+}
diff --git a/src/test/rustdoc-gui/enum-variants.goml b/src/test/rustdoc-gui/enum-variants.goml
new file mode 100644 (file)
index 0000000..230abb2
--- /dev/null
@@ -0,0 +1,5 @@
+// Verifies that there is non-zero margin on variants and their docblocks.
+goto: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
+
+assert-css: (".variants > .variant", {"margin": "0px 0px 12px"})
+assert-css: (".variants > .docblock", {"margin": "0px 0px 32px 24px"})
index 392f17bfd47c12a52ce2a6bed3baebcb63967096..799ba851c92f9a1aaa7892c758e87bba78d5b182 100644 (file)
@@ -13,6 +13,44 @@ assert-css: ("#help", {"display": "block"})
 compare-elements-property: (".sub", "#help", ["offsetWidth"])
 compare-elements-position: (".sub", "#help", ("x"))
 
+// Checking the color of the elements of the help menu.
+show-text: true
+define-function: (
+    "check-colors",
+    (theme, color, background, box_shadow),
+    [
+        // Setting the theme.
+        ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+        // We reload the page so the local storage settings are being used.
+        ("reload"),
+        ("assert-css", ("#help kbd", {
+            "color": |color|,
+            "background-color": |background|,
+            "box-shadow": |box_shadow| + " 0px -1px 0px 0px inset",
+            "cursor": "default",
+        }, ALL)),
+    ],
+)
+
+call-function: ("check-colors", {
+    "theme": "ayu",
+    "color": "rgb(197, 197, 197)",
+    "background": "rgb(49, 69, 89)",
+    "box_shadow": "rgb(92, 103, 115)",
+})
+call-function: ("check-colors", {
+    "theme": "dark",
+    "color": "rgb(221, 221, 221)",
+    "background": "rgb(250, 251, 252)",
+    "box_shadow": "rgb(198, 203, 209)",
+})
+call-function: ("check-colors", {
+    "theme": "light",
+    "color": "rgb(0, 0, 0)",
+    "background": "rgb(250, 251, 252)",
+    "box_shadow": "rgb(198, 203, 209)",
+})
+
 // This test ensures that opening the help popover without switching pages works.
 goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
 size: (1000, 1000) // Only supported on desktop.
index 4c3943d8858307c729e5493042344d87c6be68f2..aab3b11433e93d2d15ab96fade3614403da6c27c 100644 (file)
@@ -219,3 +219,33 @@ press-key: "Tab"
 press-key: "Tab"
 press-key: "Tab"
 assert-count: ("//*[@class='notable popover']", 0)
+assert: "#method\.create_an_iterator_from_read .notable-traits:focus"
+
+// Now we check that the focus isn't given back to the wrong item when opening
+// another popover.
+store-window-property: (scroll, "scrollY")
+click: "#method\.create_an_iterator_from_read .fnname"
+// We ensure that the scroll position changed.
+assert-window-property-false: {"scrollY": |scroll|}
+// Store the new position.
+store-window-property: (scroll, "scrollY")
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+wait-for: "//*[@class='notable popover']"
+click: "#settings-menu a"
+click: ".search-input"
+// We ensure we didn't come back to the previous focused item.
+assert-window-property-false: {"scrollY": |scroll|}
+
+// Same but with Escape handling.
+store-window-property: (scroll, "scrollY")
+click: "#method\.create_an_iterator_from_read .fnname"
+// We ensure that the scroll position changed.
+assert-window-property-false: {"scrollY": |scroll|}
+// Store the new position.
+store-window-property: (scroll, "scrollY")
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+wait-for: "//*[@class='notable popover']"
+click: "#settings-menu a"
+press-key: "Escape"
+// We ensure we didn't come back to the previous focused item.
+assert-window-property-false: {"scrollY": |scroll|}
diff --git a/src/test/rustdoc-gui/scrape-examples-button-focus.goml b/src/test/rustdoc-gui/scrape-examples-button-focus.goml
new file mode 100644 (file)
index 0000000..2a263a8
--- /dev/null
@@ -0,0 +1,14 @@
+goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html"
+store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
+assert-property-false: (".scraped-example-list > .scraped-example pre", {
+       "scrollHeight": |smallOffsetHeight|
+})
+focus: ".scraped-example-list > .scraped-example .expand"
+press-key: "Enter"
+assert-property-false: (".scraped-example-list > .scraped-example pre", {
+       "offsetHeight": |smallOffsetHeight|
+})
+store-property: (fullOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
+assert-property: (".scraped-example-list > .scraped-example pre", {
+       "scrollHeight": |fullOffsetHeight|
+})
index 4155dab64eb98d376ff5eb9ba5ba8a3d60922ffe..abf8af77715c9eec5da0306c825e479abcf5db59 100644 (file)
@@ -29,170 +29,95 @@ assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
 // Now we check the display of the sidebar items.
 show-text: true
 
-// First we start with the light theme.
-local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
-reload:
-// Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
-assert-css: (
-    "#source-sidebar details[open] > .files a.selected",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"},
-)
-// Without hover or focus.
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
-// With focus.
-focus: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
-// Without hover.
-assert-css: (
-    "#source-sidebar details[open] > .files a:not(.selected)",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .files a:not(.selected)"
-wait-for-css: (
-    "#source-sidebar details[open] > .files a:not(.selected)",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
-assert-css: (
-    "#source-sidebar details[open] > .files a:not(.selected)",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
-// Without hover.
-assert-css: (
-    "#source-sidebar details[open] > .folders > details > summary",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .folders > details > summary"
-wait-for-css: (
-    "#source-sidebar details[open] > .folders > details > summary",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
-assert-css: (
-    "#source-sidebar details[open] > .folders > details > summary",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
+define-function: (
+    "check-colors",
+    (
+        theme, color, color_hover, background, background_hover, background_toggle,
+        background_toggle_hover,
+    ),
+    [
+        ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+        ("reload"),
+        ("wait-for-css", ("#sidebar-toggle", {"visibility": "visible"})),
+        ("assert-css", (
+            "#source-sidebar details[open] > .files a.selected",
+            {"color": |color_hover|, "background-color": |background|},
+        )),
+        // Without hover or focus.
+        ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle|})),
+        // With focus.
+        ("focus", "#sidebar-toggle > button"),
+        ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle_hover|})),
+        ("focus", ".search-input"),
+        // With hover.
+        ("move-cursor-to", "#sidebar-toggle > button"),
+        ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle_hover|})),
+        // Without hover.
+        ("assert-css", (
+            "#source-sidebar details[open] > .files a:not(.selected)",
+            {"color": |color|, "background-color": |background_toggle|},
+        )),
+        // With focus.
+        ("focus", "#source-sidebar details[open] > .files a:not(.selected)"),
+        ("wait-for-css", (
+            "#source-sidebar details[open] > .files a:not(.selected)",
+            {"color": |color_hover|, "background-color": |background_hover|},
+        )),
+        ("focus", ".search-input"),
+        // With hover.
+        ("move-cursor-to", "#source-sidebar details[open] > .files a:not(.selected)"),
+        ("assert-css", (
+            "#source-sidebar details[open] > .files a:not(.selected)",
+            {"color": |color_hover|, "background-color": |background_hover|},
+        )),
+        // Without hover.
+        ("assert-css", (
+            "#source-sidebar details[open] > .folders > details > summary",
+            {"color": |color|, "background-color": |background_toggle|},
+        )),
+        // With focus.
+        ("focus", "#source-sidebar details[open] > .folders > details > summary"),
+        ("wait-for-css", (
+            "#source-sidebar details[open] > .folders > details > summary",
+            {"color": |color_hover|, "background-color": |background_hover|},
+        )),
+        ("focus", ".search-input"),
+        // With hover.
+        ("move-cursor-to", "#source-sidebar details[open] > .folders > details > summary"),
+        ("assert-css", (
+            "#source-sidebar details[open] > .folders > details > summary",
+            {"color": |color_hover|, "background-color": |background_hover|},
+        )),
+    ],
 )
 
-// Now with the dark theme.
-local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
-reload:
-// Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
-assert-css: (
-    "#source-sidebar details[open] > .files > a.selected",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"},
-)
-// Without hover or focus.
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
-// With focus.
-focus: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
-// Without hover.
-assert-css: (
-    "#source-sidebar details[open] > .files > a:not(.selected)",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .files a:not(.selected)"
-wait-for-css: (
-    "#source-sidebar details[open] > .files a:not(.selected)",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
-assert-css: (
-    "#source-sidebar details[open] > .files a:not(.selected)",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-// Without hover.
-assert-css: (
-    "#source-sidebar details[open] > .folders > details > summary",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .folders > details > summary"
-wait-for-css: (
-    "#source-sidebar details[open] > .folders > details > summary",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
-assert-css: (
-    "#source-sidebar details[open] > .folders > details > summary",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-
-// And finally with the ayu theme.
-local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"}
-reload:
-// Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
-assert-css: (
-    "#source-sidebar details[open] > .files a.selected",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-// Without hover or focus.
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
-// With focus.
-focus: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
-// Without hover.
-assert-css: (
-    "#source-sidebar details[open] > .files a:not(.selected)",
-    {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .files a:not(.selected)"
-wait-for-css: (
-    "#source-sidebar details[open] > .files a:not(.selected)",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
-assert-css: (
-    "#source-sidebar details[open] > .files a:not(.selected)",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-// Without hover.
-assert-css: (
-    "#source-sidebar details[open] > .folders > details > summary",
-    {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .folders > details > summary"
-wait-for-css: (
-    "#source-sidebar details[open] > .folders > details > summary",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
-assert-css: (
-    "#source-sidebar details[open] > .folders > details > summary",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
+call-function: ("check-colors", {
+    "theme": "light",
+    "color": "rgb(0, 0, 0)",
+    "color_hover": "rgb(0, 0, 0)",
+    "background": "rgb(255, 255, 255)",
+    "background_hover": "rgb(224, 224, 224)",
+    "background_toggle": "rgba(0, 0, 0, 0)",
+    "background_toggle_hover": "rgb(224, 224, 224)",
+})
+call-function: ("check-colors", {
+    "theme": "dark",
+    "color": "rgb(221, 221, 221)",
+    "color_hover": "rgb(221, 221, 221)",
+    "background": "rgb(51, 51, 51)",
+    "background_hover": "rgb(68, 68, 68)",
+    "background_toggle": "rgba(0, 0, 0, 0)",
+    "background_toggle_hover": "rgb(103, 103, 103)",
+})
+call-function: ("check-colors", {
+    "theme": "ayu",
+    "color": "rgb(197, 197, 197)",
+    "color_hover": "rgb(255, 180, 76)",
+    "background": "rgb(20, 25, 31)",
+    "background_hover": "rgb(20, 25, 31)",
+    "background_toggle": "rgba(0, 0, 0, 0)",
+    "background_toggle_hover": "rgba(70, 70, 70, 0.33)",
+})
 
 // Now checking on mobile devices.
 size: (500, 700)
index e9a987d52bbdbd881d85e5c0bf822f9b12595bb9..36e4d555b8ed21ec68abfac989e875f36f3c8dee 100644 (file)
@@ -28,7 +28,7 @@ assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']"
 // Only "another_folder" should be "open" in "lib2".
 assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']"
 // All other trees should be collapsed.
-assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 6)
+assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 7)
 
 // We now switch to mobile mode.
 size: (600, 600)
diff --git a/src/test/rustdoc-gui/src/scrape_examples/Cargo.lock b/src/test/rustdoc-gui/src/scrape_examples/Cargo.lock
new file mode 100644 (file)
index 0000000..7cd6d08
--- /dev/null
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "scrape_examples"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/scrape_examples/Cargo.toml b/src/test/rustdoc-gui/src/scrape_examples/Cargo.toml
new file mode 100644 (file)
index 0000000..aea9b65
--- /dev/null
@@ -0,0 +1,8 @@
+[package]
+name = "scrape_examples"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check.rs
new file mode 100644 (file)
index 0000000..3e69c60
--- /dev/null
@@ -0,0 +1,25 @@
+fn main() {
+    for i in 0..9 {
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+    }
+    scrape_examples::test();
+    for i in 0..9 {
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+        println!("hello world!");
+    }
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/src/lib.rs b/src/test/rustdoc-gui/src/scrape_examples/src/lib.rs
new file mode 100644 (file)
index 0000000..6412de2
--- /dev/null
@@ -0,0 +1,7 @@
+/// # Examples
+///
+/// ```
+/// test();
+/// test();
+/// ```
+pub fn test() {}
index fc63ed343bda27cefb52a6258acb6b23c557af8e..db0d102b741846292198e1d04994b908ac2827cc 100644 (file)
@@ -8,22 +8,22 @@
 
 // @has issue_88600/enum.FooEnum.html
 pub enum FooEnum {
-    // @has - '//*[@id="variant.HiddenTupleItem"]//code' 'HiddenTupleItem(_)'
+    // @has - '//*[@id="variant.HiddenTupleItem"]//h3' 'HiddenTupleItem(_)'
     // @count - '//*[@id="variant.HiddenTupleItem.field.0"]' 0
     HiddenTupleItem(#[doc(hidden)] H),
-    // @has - '//*[@id="variant.MultipleHidden"]//code' 'MultipleHidden(_, _)'
+    // @has - '//*[@id="variant.MultipleHidden"]//h3' 'MultipleHidden(_, _)'
     // @count - '//*[@id="variant.MultipleHidden.field.0"]' 0
     // @count - '//*[@id="variant.MultipleHidden.field.1"]' 0
     MultipleHidden(#[doc(hidden)] H, #[doc(hidden)] H),
-    // @has - '//*[@id="variant.MixedHiddenFirst"]//code' 'MixedHiddenFirst(_, S)'
+    // @has - '//*[@id="variant.MixedHiddenFirst"]//h3' 'MixedHiddenFirst(_, S)'
     // @count - '//*[@id="variant.MixedHiddenFirst.field.0"]' 0
     // @has - '//*[@id="variant.MixedHiddenFirst.field.1"]' '1: S'
     MixedHiddenFirst(#[doc(hidden)] H, /** dox */ S),
-    // @has - '//*[@id="variant.MixedHiddenLast"]//code' 'MixedHiddenLast(S, _)'
+    // @has - '//*[@id="variant.MixedHiddenLast"]//h3' 'MixedHiddenLast(S, _)'
     // @has - '//*[@id="variant.MixedHiddenLast.field.0"]' '0: S'
     // @count - '//*[@id="variant.MixedHiddenLast.field.1"]' 0
     MixedHiddenLast(/** dox */ S, #[doc(hidden)] H),
-    // @has - '//*[@id="variant.HiddenStruct"]//code' 'HiddenStruct'
+    // @has - '//*[@id="variant.HiddenStruct"]//h3' 'HiddenStruct'
     // @count - '//*[@id="variant.HiddenStruct.field.h"]' 0
     // @has - '//*[@id="variant.HiddenStruct.field.s"]' 's: S'
     HiddenStruct {
index 117b798710cf00570fee91785d61787f65d091e8..d6dc179da7f9897b0112a5d23abb3f524bad9dc0 100644 (file)
@@ -25,6 +25,7 @@
 extern crate rustc_parse;
 extern crate rustc_session;
 extern crate rustc_span;
+extern crate thin_vec;
 
 use rustc_ast::mut_visit::{self, visit_clobber, MutVisitor};
 use rustc_ast::ptr::P;
@@ -35,6 +36,7 @@
 use rustc_span::source_map::FilePathMapping;
 use rustc_span::source_map::{FileName, Spanned, DUMMY_SP};
 use rustc_span::symbol::Ident;
+use thin_vec::thin_vec;
 
 fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
     let src_as_string = src.to_string();
@@ -51,7 +53,7 @@ fn expr(kind: ExprKind) -> P<Expr> {
 
 fn make_x() -> P<Expr> {
     let seg = PathSegment::from_ident(Ident::from_str("x"));
-    let path = Path { segments: vec![seg], span: DUMMY_SP, tokens: None };
+    let path = Path { segments: thin_vec![seg], span: DUMMY_SP, tokens: None };
     expr(ExprKind::Path(None, path))
 }
 
@@ -73,11 +75,15 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
             2 => {
                 let seg = PathSegment::from_ident(Ident::from_str("x"));
                 iter_exprs(depth - 1, &mut |e| {
-                    g(ExprKind::MethodCall(seg.clone(), e, vec![make_x()], DUMMY_SP))
-                });
+                    g(ExprKind::MethodCall(Box::new(MethodCall {
+                        seg: seg.clone(), receiver: e, args: vec![make_x()], span: DUMMY_SP
+                    }))
+                )});
                 iter_exprs(depth - 1, &mut |e| {
-                    g(ExprKind::MethodCall(seg.clone(), make_x(), vec![e], DUMMY_SP))
-                });
+                    g(ExprKind::MethodCall(Box::new(MethodCall {
+                        seg: seg.clone(), receiver: make_x(), args: vec![e], span: DUMMY_SP
+                    }))
+                )});
             }
             3..=8 => {
                 let op = Spanned {
@@ -112,15 +118,15 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
             11 => {
                 let decl = P(FnDecl { inputs: vec![], output: FnRetTy::Default(DUMMY_SP) });
                 iter_exprs(depth - 1, &mut |e| {
-                    g(ExprKind::Closure(
-                        ClosureBinder::NotPresent,
-                        CaptureBy::Value,
-                        Async::No,
-                        Movability::Movable,
-                        decl.clone(),
-                        e,
-                        DUMMY_SP,
-                    ))
+                    g(ExprKind::Closure(Box::new(Closure {
+                        binder: ClosureBinder::NotPresent,
+                        capture_clause: CaptureBy::Value,
+                        asyncness: Async::No,
+                        movability: Movability::Movable,
+                        fn_decl: decl.clone(),
+                        body: e,
+                        fn_decl_span: DUMMY_SP,
+                    })))
                 });
             }
             12 => {
diff --git a/src/test/ui/array-slice-vec/slice_is_sorted_by_borrow.rs b/src/test/ui/array-slice-vec/slice_is_sorted_by_borrow.rs
new file mode 100644 (file)
index 0000000..073280d
--- /dev/null
@@ -0,0 +1,20 @@
+// check-pass
+// regression test for https://github.com/rust-lang/rust/issues/53485#issuecomment-885393452
+
+#![feature(is_sorted)]
+
+struct A {
+    name: String,
+}
+
+fn main() {
+    let a = &[
+        A {
+            name: "1".to_string(),
+        },
+        A {
+            name: "2".to_string(),
+        },
+    ];
+    assert!(a.is_sorted_by_key(|a| a.name.as_str()));
+}
diff --git a/src/test/ui/async-await/in-trait/object-safety.rs b/src/test/ui/async-await/in-trait/object-safety.rs
new file mode 100644 (file)
index 0000000..a8bc35f
--- /dev/null
@@ -0,0 +1,13 @@
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait Foo {
+    async fn foo(&self);
+}
+
+fn main() {
+    let x: &dyn Foo = todo!();
+    //~^ ERROR the trait `Foo` cannot be made into an object
+}
diff --git a/src/test/ui/async-await/in-trait/object-safety.stderr b/src/test/ui/async-await/in-trait/object-safety.stderr
new file mode 100644 (file)
index 0000000..0b318f7
--- /dev/null
@@ -0,0 +1,27 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/object-safety.rs:3:12
+   |
+LL | #![feature(async_fn_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety.rs:11:12
+   |
+LL |     let x: &dyn Foo = todo!();
+   |            ^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety.rs:7:14
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     async fn foo(&self);
+   |              ^^^ ...because method `foo` is `async`
+   = help: consider moving `foo` to another trait
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/blind-item-local-shadow.rs b/src/test/ui/blind-item-local-shadow.rs
deleted file mode 100644 (file)
index 942aeb6..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-pass
-
-#![allow(dead_code)]
-#![allow(unused_imports)]
-mod bar {
-    pub fn foo() -> bool { true }
-}
-
-fn main() {
-    let foo = || false;
-    use bar::foo;
-    assert_eq!(foo(), false);
-}
diff --git a/src/test/ui/cast/cast-pointee-projection.rs b/src/test/ui/cast/cast-pointee-projection.rs
new file mode 100644 (file)
index 0000000..f51c5f2
--- /dev/null
@@ -0,0 +1,17 @@
+// check-pass
+
+trait Tag<'a> {
+    type Type: ?Sized;
+}
+
+trait IntoRaw: for<'a> Tag<'a> {
+    fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type;
+}
+
+impl<T: for<'a> Tag<'a>> IntoRaw for T {
+    fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type {
+        this as *mut T::Type
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-100191-2.rs b/src/test/ui/coherence/issue-100191-2.rs
deleted file mode 100644 (file)
index 1c8316f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-//~ ERROR overflow evaluating the requirement `T: Trait<_>`
-
-#![feature(specialization, with_negative_coherence)]
-#![allow(incomplete_features)]
-
-pub trait Trait<T> {}
-
-default impl<T, U> Trait<T> for U {}
-
-impl<T> Trait<<T as Iterator>::Item> for T {}
-
-fn main() {}
diff --git a/src/test/ui/coherence/issue-100191-2.stderr b/src/test/ui/coherence/issue-100191-2.stderr
deleted file mode 100644 (file)
index d50c220..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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 for `T` to implement `Trait<_>`
-  --> $DIR/issue-100191-2.rs:8:20
-   |
-LL | default impl<T, U> Trait<T> for U {}
-   |                    ^^^^^^^^     ^
-   = note: 128 redundant requirements hidden
-   = note: required for `T` to implement `Trait<_>`
-
-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
deleted file mode 100644 (file)
index e8597fd..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#![crate_type = "lib"]
-#![feature(specialization, with_negative_coherence)]
-#![allow(incomplete_features)]
-
-trait X {}
-trait Y: X {}
-trait Z {
-    type Assoc: Y;
-}
-struct A<T>(T);
-
-impl<T> Y for T where T: X {}
-impl<T: X> Z for A<T> {
-    type Assoc = T;
-}
-
-// this impl is invalid, but causes an ICE anyway
-impl<T> From<<A<T> as Z>::Assoc> for T {}
-//~^ ERROR type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-
-fn main() {}
diff --git a/src/test/ui/coherence/issue-100191.stderr b/src/test/ui/coherence/issue-100191.stderr
deleted file mode 100644 (file)
index 1adb0f1..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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/deref-patterns/basic.rs b/src/test/ui/deref-patterns/basic.rs
new file mode 100644 (file)
index 0000000..2497160
--- /dev/null
@@ -0,0 +1,17 @@
+// run-pass
+// check-run-results
+#![feature(string_deref_patterns)]
+
+fn main() {
+    test(Some(String::from("42")));
+    test(Some(String::new()));
+    test(None);
+}
+
+fn test(o: Option<String>) {
+    match o {
+        Some("42") => println!("the answer"),
+        Some(_) => println!("something else?"),
+        None => println!("nil"),
+    }
+}
diff --git a/src/test/ui/deref-patterns/basic.run.stdout b/src/test/ui/deref-patterns/basic.run.stdout
new file mode 100644 (file)
index 0000000..e50df05
--- /dev/null
@@ -0,0 +1,3 @@
+the answer
+something else?
+nil
diff --git a/src/test/ui/deref-patterns/default-infer.rs b/src/test/ui/deref-patterns/default-infer.rs
new file mode 100644 (file)
index 0000000..050b847
--- /dev/null
@@ -0,0 +1,9 @@
+// check-pass
+#![feature(string_deref_patterns)]
+
+fn main() {
+    match <_ as Default>::default() {
+        "" => (),
+        _ => unreachable!(),
+    }
+}
diff --git a/src/test/ui/deref-patterns/gate.rs b/src/test/ui/deref-patterns/gate.rs
new file mode 100644 (file)
index 0000000..ff50e30
--- /dev/null
@@ -0,0 +1,7 @@
+// gate-test-string_deref_patterns
+fn main() {
+    match String::new() {
+        "" | _ => {}
+        //~^ mismatched types
+    }
+}
diff --git a/src/test/ui/deref-patterns/gate.stderr b/src/test/ui/deref-patterns/gate.stderr
new file mode 100644 (file)
index 0000000..993468b
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+  --> $DIR/gate.rs:4:9
+   |
+LL |     match String::new() {
+   |           ------------- this expression has type `String`
+LL |         "" | _ => {}
+   |         ^^ expected struct `String`, found `&str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/deref-patterns/refs.rs b/src/test/ui/deref-patterns/refs.rs
new file mode 100644 (file)
index 0000000..97e260d
--- /dev/null
@@ -0,0 +1,18 @@
+// check-pass
+#![feature(string_deref_patterns)]
+
+fn foo(s: &String) -> i32 {
+    match *s {
+        "a" => 42,
+        _ => -1,
+    }
+}
+
+fn bar(s: Option<&&&&String>) -> i32 {
+    match s {
+        Some(&&&&"&&&&") => 1,
+        _ => -1,
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/align.normal.stderr b/src/test/ui/dyn-star/align.normal.stderr
new file mode 100644 (file)
index 0000000..983d7bf
--- /dev/null
@@ -0,0 +1,11 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/align.rs:4:12
+   |
+LL | #![feature(dyn_star)]
+   |            ^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/dyn-star/align.over_aligned.stderr b/src/test/ui/dyn-star/align.over_aligned.stderr
new file mode 100644 (file)
index 0000000..6b6fc55
--- /dev/null
@@ -0,0 +1,20 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/align.rs:4:12
+   |
+LL | #![feature(dyn_star)]
+   |            ^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: `AlignedUsize` needs to be a pointer-sized type
+  --> $DIR/align.rs:15:13
+   |
+LL |     let x = AlignedUsize(12) as dyn* Debug;
+   |             ^^^^^^^^^^^^^^^^ `AlignedUsize` needs to be a pointer-sized type
+   |
+   = help: the trait `PointerSized` is not implemented for `AlignedUsize`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/dyn-star/align.rs b/src/test/ui/dyn-star/align.rs
new file mode 100644 (file)
index 0000000..fb41a05
--- /dev/null
@@ -0,0 +1,17 @@
+// revisions: normal over_aligned
+//[normal] check-pass
+
+#![feature(dyn_star)]
+//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+
+use std::fmt::Debug;
+
+#[cfg_attr(over_aligned,      repr(C, align(1024)))]
+#[cfg_attr(not(over_aligned), repr(C))]
+#[derive(Debug)]
+struct AlignedUsize(usize);
+
+fn main() {
+    let x = AlignedUsize(12) as dyn* Debug;
+    //[over_aligned]~^ ERROR `AlignedUsize` needs to be a pointer-sized type
+}
diff --git a/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs b/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs
new file mode 100644 (file)
index 0000000..e19e36c
--- /dev/null
@@ -0,0 +1,15 @@
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn dyn_debug(_: (dyn* Debug + '_)) {
+
+}
+
+fn polymorphic<T: Debug + ?Sized>(t: &T) {
+    dyn_debug(t);
+    //~^ ERROR `&T` needs to be a pointer-sized type
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr b/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr
new file mode 100644 (file)
index 0000000..53ccbe4
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0277]: `&T` needs to be a pointer-sized type
+  --> $DIR/check-size-at-cast-polymorphic-bad.rs:11:15
+   |
+LL |     dyn_debug(t);
+   |               ^ `&T` needs to be a pointer-sized type
+   |
+   = help: the trait `PointerSized` is not implemented for `&T`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | fn polymorphic<T: Debug + ?Sized>(t: &T) where &T: PointerSized {
+   |                                          ++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/dyn-star/check-size-at-cast-polymorphic.rs b/src/test/ui/dyn-star/check-size-at-cast-polymorphic.rs
new file mode 100644 (file)
index 0000000..5c0a3d2
--- /dev/null
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn dyn_debug(_: (dyn* Debug + '_)) {
+
+}
+
+fn polymorphic<T: Debug>(t: &T) {
+    dyn_debug(t);
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/check-size-at-cast.rs b/src/test/ui/dyn-star/check-size-at-cast.rs
new file mode 100644 (file)
index 0000000..1f22f79
--- /dev/null
@@ -0,0 +1,10 @@
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn main() {
+    let i = [1, 2, 3, 4] as dyn* Debug;
+    //~^ ERROR `[i32; 4]` needs to be a pointer-sized type
+    dbg!(i);
+}
diff --git a/src/test/ui/dyn-star/check-size-at-cast.stderr b/src/test/ui/dyn-star/check-size-at-cast.stderr
new file mode 100644 (file)
index 0000000..af2a1cc
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0277]: `[i32; 4]` needs to be a pointer-sized type
+  --> $DIR/check-size-at-cast.rs:7:13
+   |
+LL |     let i = [1, 2, 3, 4] as dyn* Debug;
+   |             ^^^^^^^^^^^^ `[i32; 4]` needs to be a pointer-sized type
+   |
+   = help: the trait `PointerSized` is not implemented for `[i32; 4]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs b/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs
new file mode 100644 (file)
index 0000000..b4ff8a2
--- /dev/null
@@ -0,0 +1,26 @@
+// check-pass
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+trait AddOne {
+    fn add1(&mut self) -> usize;
+}
+
+impl AddOne for usize {
+    fn add1(&mut self) -> usize {
+        *self += 1;
+        *self
+    }
+}
+
+fn add_one(i: &mut (dyn* AddOne + '_)) -> usize {
+    i.add1()
+}
+
+fn main() {
+    let mut x = 42usize as dyn* AddOne;
+
+    println!("{}", add_one(&mut x));
+    println!("{}", add_one(&mut x));
+}
diff --git a/src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs b/src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs
new file mode 100644 (file)
index 0000000..1e8cafe
--- /dev/null
@@ -0,0 +1,9 @@
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn main() {
+    let i = 42 as &dyn* Debug;
+    //~^ ERROR non-primitive cast: `i32` as `&dyn* Debug`
+}
diff --git a/src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr b/src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr
new file mode 100644 (file)
index 0000000..f6444a6
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0605]: non-primitive cast: `i32` as `&dyn* Debug`
+  --> $DIR/unsize-into-ref-dyn-star.rs:7:13
+   |
+LL |     let i = 42 as &dyn* Debug;
+   |             ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
index 28a9676f03e39aba19617063b0dbdc1812e7742c..95d7f85f10546240f81ae998a841f818953bfea9 100644 (file)
@@ -1,3 +1,4 @@
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 trait Foo {}
 
 struct Bar<T>(T);
index 87cfaa489c6aad6b7c9b755db60fa8cd19b56274..49a4d984af9eb6143418ea31f0bf55e6f02fc9e7 100644 (file)
@@ -1,15 +1,16 @@
-error[E0275]: overflow evaluating the requirement `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
-  --> $DIR/E0275.rs:5:33
+error[E0275]: overflow evaluating the requirement `Bar<Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>>: Foo`
+  --> $DIR/E0275.rs:6:33
    |
 LL | impl<T> Foo for T where Bar<T>: Foo {}
    |                                 ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`)
-note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
-  --> $DIR/E0275.rs:5:9
+note: required for `Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>` to implement `Foo`
+  --> $DIR/E0275.rs:6:9
    |
 LL | impl<T> Foo for T where Bar<T>: Foo {}
    |         ^^^     ^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/error-codes/E0275/E0275.long-type-hash.txt'
    = note: 127 redundant requirements hidden
    = note: required for `Bar<T>` to implement `Foo`
 
index 9a1554b5e1cbd6e25dd5cfda6a54442e204bbadc..ca0e760ff6d35fcad92ad1fa7baca2ad132009d3 100644 (file)
@@ -5,12 +5,12 @@ LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
    |                                 ^^^^^^^^^^^^ `Foo` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:7:8
+  --> $DIR/object-safety.rs:7:22
    |
 LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     fn baz(&self) -> impl Debug;
-   |        ^^^ ...because method `baz` references an `impl Trait` type in its return type
+   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
    = help: consider moving `baz` to another trait
 
 error[E0038]: the trait `Foo` cannot be made into an object
@@ -20,12 +20,12 @@ LL |     let s = i.baz();
    |             ^^^^^^^ `Foo` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:7:8
+  --> $DIR/object-safety.rs:7:22
    |
 LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     fn baz(&self) -> impl Debug;
-   |        ^^^ ...because method `baz` references an `impl Trait` type in its return type
+   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
    = help: consider moving `baz` to another trait
 
 error[E0038]: the trait `Foo` cannot be made into an object
@@ -35,12 +35,12 @@ LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
    |             ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:7:8
+  --> $DIR/object-safety.rs:7:22
    |
 LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     fn baz(&self) -> impl Debug;
-   |        ^^^ ...because method `baz` references an `impl Trait` type in its return type
+   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
    = help: consider moving `baz` to another trait
    = note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
    = note: required by cast to type `Box<dyn Foo>`
diff --git a/src/test/ui/impl-trait/normalize-tait-in-const.rs b/src/test/ui/impl-trait/normalize-tait-in-const.rs
new file mode 100644 (file)
index 0000000..020bcbb
--- /dev/null
@@ -0,0 +1,39 @@
+// known-bug: #103507
+// failure-status: 101
+// normalize-stderr-test "note: .*\n\n" -> ""
+// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+// rustc-env:RUST_BACKTRACE=0
+
+#![feature(type_alias_impl_trait)]
+#![feature(const_trait_impl)]
+#![feature(const_refs_to_cell)]
+#![feature(inline_const)]
+
+use std::marker::Destruct;
+
+trait T {
+    type Item;
+}
+
+type Alias<'a> = impl T<Item = &'a ()>;
+
+struct S;
+impl<'a> T for &'a S {
+    type Item = &'a ();
+}
+
+const fn filter_positive<'a>() -> &'a Alias<'a> {
+    &&S
+}
+
+const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
+    fun(filter_positive());
+}
+
+const fn foo(_: &Alias<'_>) {}
+
+const BAR: () = {
+    with_positive(foo);
+};
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/normalize-tait-in-const.stderr b/src/test/ui/impl-trait/normalize-tait-in-const.stderr
new file mode 100644 (file)
index 0000000..b9fc872
--- /dev/null
@@ -0,0 +1,8 @@
+error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:198:90: Failed to normalize <for<'a, 'b> fn(&'a Alias<'b>) {foo} as std::ops::FnOnce<(&&S,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead
+
+query stack during panic:
+#0 [eval_to_allocation_raw] const-evaluating + checking `BAR`
+#1 [eval_to_const_value_raw] simplifying constant for the type system `BAR`
+end of query stack
+error: aborting due to previous error
+
index 52f5781349e1650996fae4ffb94bd0ac8df21ff9..951e0f5870d7d084ba3c802c2570f4be32340587 100644 (file)
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `function::<Option<Option<Option<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `function::<Option<Option<Option<Option<Option<...>>>>>>`
   --> $DIR/infinite-instantiation.rs:22:9
    |
 LL |         function(counter - 1, t.to_option());
index 138a235e675e375f588bf4bc3d27bcc606023249..4de22f0c9177d4f90ff06e7dd667c043ac29aeca 100644 (file)
@@ -1,3 +1,4 @@
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 trait Foo {
     fn answer(self);
 }
index 2db60b641eea5086495589a9a70da4006e53ff14..91509ceace8cb3406806a91d1c75c54b504b47af 100644 (file)
@@ -1,5 +1,5 @@
 error[E0392]: parameter `T` is never used
-  --> $DIR/issue-20413.rs:5:15
+  --> $DIR/issue-20413.rs:6:15
    |
 LL | struct NoData<T>;
    |               ^ unused parameter
@@ -7,58 +7,63 @@ LL | struct NoData<T>;
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `T` to be a const parameter, use `const T: usize` instead
 
-error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
-  --> $DIR/issue-20413.rs:8:36
+error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>: Foo`
+  --> $DIR/issue-20413.rs:9:36
    |
 LL | impl<T> Foo for T where NoData<T>: Foo {
    |                                    ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
-  --> $DIR/issue-20413.rs:8:9
+note: required for `NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>` to implement `Foo`
+  --> $DIR/issue-20413.rs:9:9
    |
 LL | impl<T> Foo for T where NoData<T>: Foo {
    |         ^^^     ^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
    = note: 127 redundant requirements hidden
    = note: required for `NoData<T>` to implement `Foo`
 
-error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Baz`
-  --> $DIR/issue-20413.rs:27:42
+error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>: Baz`
+  --> $DIR/issue-20413.rs:28:42
    |
 LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    |                                          ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
-  --> $DIR/issue-20413.rs:27:9
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar`
+  --> $DIR/issue-20413.rs:28:9
    |
 LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    |         ^^^     ^
-note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
-  --> $DIR/issue-20413.rs:34:9
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz`
+  --> $DIR/issue-20413.rs:35:9
    |
 LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
    |         ^^^     ^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
    = note: 126 redundant requirements hidden
    = note: required for `EvenLessData<T>` to implement `Baz`
 
-error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Bar`
-  --> $DIR/issue-20413.rs:34:42
+error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>: Bar`
+  --> $DIR/issue-20413.rs:35:42
    |
 LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
    |                                          ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
-  --> $DIR/issue-20413.rs:34:9
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz`
+  --> $DIR/issue-20413.rs:35:9
    |
 LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
    |         ^^^     ^
-note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
-  --> $DIR/issue-20413.rs:27:9
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar`
+  --> $DIR/issue-20413.rs:28:9
    |
 LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    |         ^^^     ^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
    = note: 126 redundant requirements hidden
    = note: required for `AlmostNoData<T>` to implement `Bar`
 
index 1354ec8e899c09c09f17f68c9c42e4062cd37471..1caa4221f25015fc6d292f88e9c6b4ae76037719 100644 (file)
@@ -9,7 +9,6 @@ note: `A::matches` defined here
    |
 LL |     pub fn matches<F: Fn()>(&self, f: &F) {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-22638/issue-22638.long-type.txt'
 
 error: aborting due to previous error
 
index 93aeb89469d4a3dbe9702dca34d3e66ce03a31a0..5b8299fe839d7bcdb100808ed8c4e7a5049d5458 100644 (file)
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(.....), ...), ...) as Foo>::recurse`
+error: reached the recursion limit while instantiating `<(&(&(..., ...), ...), ...) as Foo>::recurse`
   --> $DIR/issue-37311.rs:17:9
    |
 LL |         (self, self).recurse();
index 2195b89555791c3c17053540a14587c2db125ea5..547643f0d6e203f9644dd410d44deb97d3e7ffac 100644 (file)
@@ -1,4 +1,3 @@
-// compile-flags:-Ztreat-err-as-bug=5
 #[derive(Debug)]
 enum MyError {
     NotFound { key: Vec<u8> },
index c0bde4b2321f11dc05b60203fe499afaf4abb5e6..ef41f078b8037d25e1ab892ac182fad9a3656163 100644 (file)
@@ -1,5 +1,5 @@
 error[E0507]: cannot move out of `*key` which is behind a shared reference
-  --> $DIR/issue-52262.rs:16:35
+  --> $DIR/issue-52262.rs:15:35
    |
 LL |                 String::from_utf8(*key).unwrap()
    |                                   ^^^^ move occurs because `*key` has type `Vec<u8>`, which does not implement the `Copy` trait
index 2968be7c71fb5de77cf070a79b9df263cc493312..4746f918bf8dd53b761d70b0bfcad528f2bddf55 100644 (file)
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &... &mut &mut &mut &mut &mut Empty>`
+error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>`
   --> $DIR/issue-67552.rs:29:9
    |
 LL |         rec(identity(&mut it))
index 5e1fdad60cb8a7d97498cdb4cb3c6a57c72739f3..22332b357231b3b88d51e21b8c405854c721b8de 100644 (file)
@@ -9,7 +9,7 @@ LL |     generic::<Option<T>>();
    = help: a `loop` may express intention better if this is on purpose
    = note: `#[warn(unconditional_recursion)]` on by default
 
-error: reached the recursion limit while instantiating `generic::<Option<Option<Option<O...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `generic::<Option<Option<Option<Option<Option<...>>>>>>`
   --> $DIR/issue-8727.rs:8:5
    |
 LL |     generic::<Option<T>>();
diff --git a/src/test/ui/mir/important-higher-ranked-regions.rs b/src/test/ui/mir/important-higher-ranked-regions.rs
new file mode 100644 (file)
index 0000000..cadfb3b
--- /dev/null
@@ -0,0 +1,26 @@
+// check-pass
+// compile-flags: -Zvalidate-mir
+
+// This test checks that bivariant parameters are handled correctly
+// in the mir.
+#![allow(coherence_leak_check)]
+trait Trait {
+    type Assoc;
+}
+
+struct Foo<T, U>(T)
+where
+    T: Trait<Assoc = U>;
+
+impl Trait for for<'a> fn(&'a ()) {
+    type Assoc = u32;
+}
+impl Trait for fn(&'static ()) {
+    type Assoc = String;
+}
+
+fn foo(x: Foo<for<'a> fn(&'a ()), u32>) -> Foo<fn(&'static ()), String> {
+    x
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-103381.fixed b/src/test/ui/parser/issue-103381.fixed
new file mode 100644 (file)
index 0000000..6a9fb99
--- /dev/null
@@ -0,0 +1,59 @@
+// run-rustfix
+
+#![feature(let_chains)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![allow(irrefutable_let_patterns)]
+
+fn err_some(b: bool, x: Option<u32>) {
+    if b && let Some(x) = x {}
+    //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_none(b: bool, x: Option<u32>) {
+    if b && let None = x {}
+    //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_1() {
+    if true && true { true } else { false };
+    //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_2() {
+    if true && false { true } else { false };
+    //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn should_ok_1() {
+    if true && if let x = 1 { true } else { true } {}
+}
+
+fn should_ok_2() {
+    if true && if let 1 = 1 { true } else { true } {}
+}
+
+fn should_ok_3() {
+    if true && if true { true } else { false } {}
+}
+
+fn shoule_match_ok() {
+    #[cfg(feature = "full")]
+    {
+        let a = 1;
+        let b = 2;
+        if match a {
+            1 if b == 1 => true,
+            _ => false,
+        } && if a > 1 { true } else { false }
+        {
+            true
+        }
+    }
+}
+
+fn should_ok_in_nested() {
+    if true && if true { true } else { false } { true } else { false };
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-103381.rs b/src/test/ui/parser/issue-103381.rs
new file mode 100644 (file)
index 0000000..bf79e10
--- /dev/null
@@ -0,0 +1,59 @@
+// run-rustfix
+
+#![feature(let_chains)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![allow(irrefutable_let_patterns)]
+
+fn err_some(b: bool, x: Option<u32>) {
+    if b && if let Some(x) = x {}
+    //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_none(b: bool, x: Option<u32>) {
+    if b && if let None = x {}
+    //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_1() {
+    if true && if true { true } else { false };
+    //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_2() {
+    if true && if false { true } else { false };
+    //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn should_ok_1() {
+    if true && if let x = 1 { true } else { true } {}
+}
+
+fn should_ok_2() {
+    if true && if let 1 = 1 { true } else { true } {}
+}
+
+fn should_ok_3() {
+    if true && if true { true } else { false } {}
+}
+
+fn shoule_match_ok() {
+    #[cfg(feature = "full")]
+    {
+        let a = 1;
+        let b = 2;
+        if match a {
+            1 if b == 1 => true,
+            _ => false,
+        } && if a > 1 { true } else { false }
+        {
+            true
+        }
+    }
+}
+
+fn should_ok_in_nested() {
+    if true && if true { true } else { false } { true } else { false };
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-103381.stderr b/src/test/ui/parser/issue-103381.stderr
new file mode 100644 (file)
index 0000000..85fcc18
--- /dev/null
@@ -0,0 +1,50 @@
+error: unexpected `if` in the condition expression
+  --> $DIR/issue-103381.rs:9:12
+   |
+LL |     if b && if let Some(x) = x {}
+   |            ^^^^
+   |
+help: remove the `if`
+   |
+LL -     if b && if let Some(x) = x {}
+LL +     if b && let Some(x) = x {}
+   |
+
+error: unexpected `if` in the condition expression
+  --> $DIR/issue-103381.rs:14:12
+   |
+LL |     if b && if let None = x {}
+   |            ^^^^
+   |
+help: remove the `if`
+   |
+LL -     if b && if let None = x {}
+LL +     if b && let None = x {}
+   |
+
+error: unexpected `if` in the condition expression
+  --> $DIR/issue-103381.rs:19:15
+   |
+LL |     if true && if true { true } else { false };
+   |               ^^^^
+   |
+help: remove the `if`
+   |
+LL -     if true && if true { true } else { false };
+LL +     if true && true { true } else { false };
+   |
+
+error: unexpected `if` in the condition expression
+  --> $DIR/issue-103381.rs:24:15
+   |
+LL |     if true && if false { true } else { false };
+   |               ^^^^
+   |
+help: remove the `if`
+   |
+LL -     if true && if false { true } else { false };
+LL +     if true && false { true } else { false };
+   |
+
+error: aborting due to 4 previous errors
+
index e647f0ff4fb8beaa3e3285ea829908df27f3dfec..38353d161c1339e626f95750c3d58ef166c3ff51 100644 (file)
@@ -1,6 +1,7 @@
 // build-fail
 // compile-flags: -Copt-level=0
-//~^^ ERROR overflow evaluating the requirement
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
+//~^^^ ERROR overflow evaluating the requirement
 
 fn main() {
     let mut iter = 0u8..1;
index 59fba5af00e1290dc3eed1040231674b8d430231..a67bfd018a2b5cfd9f96255a5c34eddfda1b56c3 100644 (file)
@@ -1,5 +1,5 @@
 warning: function cannot return without recursing
-  --> $DIR/issue-83150.rs:10:1
+  --> $DIR/issue-83150.rs:11:1
    |
 LL | fn func<T: Iterator<Item = u8>>(iter: &mut T) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -12,9 +12,10 @@ LL |     func(&mut iter.map(|x| x + 1))
 error[E0275]: overflow evaluating the requirement `<std::ops::Range<u8> as Iterator>::Item`
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
-   = note: required for `Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
+   = note: required for `Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:12:24: 12:27]>` to implement `Iterator`
    = note: 64 redundant requirements hidden
-   = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
+   = note: required for `&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>` to implement `Iterator`
+   = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type-hash.txt'
 
 error: aborting due to previous error; 1 warning emitted
 
index d2844d0e6d9f026f04fb6c10a7d35fc6f98721ec..cf08095372b0792aab0eb8bb6ad92d36a3ccd8ed 100644 (file)
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>`
   --> $DIR/recursion.rs:18:11
    |
 LL |     _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
diff --git a/src/test/ui/resolve/blind-item-local-shadow.rs b/src/test/ui/resolve/blind-item-local-shadow.rs
new file mode 100644 (file)
index 0000000..942aeb6
--- /dev/null
@@ -0,0 +1,13 @@
+// run-pass
+
+#![allow(dead_code)]
+#![allow(unused_imports)]
+mod bar {
+    pub fn foo() -> bool { true }
+}
+
+fn main() {
+    let foo = || false;
+    use bar::foo;
+    assert_eq!(foo(), false);
+}
diff --git a/src/test/ui/specialization/issue-43037.current.stderr b/src/test/ui/specialization/issue-43037.current.stderr
new file mode 100644 (file)
index 0000000..26db9d7
--- /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-43037.rs:19:6
+   |
+LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
+   |      ^ type parameter `T` must be used as the type parameter for some local type
+   |
+   = 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/specialization/issue-43037.negative.stderr b/src/test/ui/specialization/issue-43037.negative.stderr
new file mode 100644 (file)
index 0000000..26db9d7
--- /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-43037.rs:19:6
+   |
+LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
+   |      ^ type parameter `T` must be used as the type parameter for some local type
+   |
+   = 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`.
index c49119f9c095b73e07a3361c57e6d72bfeb69dd5..a1e3f998b23701c5a04d86fb76594c0d0d008d89 100644 (file)
@@ -1,4 +1,6 @@
+// revisions: current negative
 #![feature(specialization)]
+#![cfg_attr(negative, feature(with_negative_coherence))]
 #![allow(incomplete_features)]
 
 trait X {}
diff --git a/src/test/ui/specialization/issue-43037.stderr b/src/test/ui/specialization/issue-43037.stderr
deleted file mode 100644 (file)
index 4249cd8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/issue-43037.rs:17:6
-   |
-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/specialization/issue-45814.current.stderr b/src/test/ui/specialization/issue-45814.current.stderr
new file mode 100644 (file)
index 0000000..5013559
--- /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_45814`)
+note: required for `T` to implement `Trait<_>`
+  --> $DIR/issue-45814.rs:9:20
+   |
+LL | default impl<T, U> Trait<T> for U {}
+   |                    ^^^^^^^^     ^
+   = note: 128 redundant requirements hidden
+   = note: required for `T` to implement `Trait<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/specialization/issue-45814.negative.stderr b/src/test/ui/specialization/issue-45814.negative.stderr
new file mode 100644 (file)
index 0000000..5013559
--- /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_45814`)
+note: required for `T` to implement `Trait<_>`
+  --> $DIR/issue-45814.rs:9:20
+   |
+LL | default impl<T, U> Trait<T> for U {}
+   |                    ^^^^^^^^     ^
+   = note: 128 redundant requirements hidden
+   = note: required for `T` to implement `Trait<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
index 8ee5d3e2e58da627b5b3d942493867a70035300d..fce236390c2b0e78ef913361fbb234ac87f6d7b7 100644 (file)
@@ -1,6 +1,7 @@
 //~ ERROR overflow evaluating the requirement `T: Trait<_>`
-
+// revisions: current negative
 #![feature(specialization)]
+#![cfg_attr(negative, feature(with_negative_coherence))]
 #![allow(incomplete_features)]
 
 pub trait Trait<T> {}
diff --git a/src/test/ui/specialization/issue-45814.stderr b/src/test/ui/specialization/issue-45814.stderr
deleted file mode 100644 (file)
index 419345a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0275]: overflow evaluating the requirement `T: Trait<_>`
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
-note: required for `T` to implement `Trait<_>`
-  --> $DIR/issue-45814.rs:8:20
-   |
-LL | default impl<T, U> Trait<T> for U {}
-   |                    ^^^^^^^^     ^
-   = note: 128 redundant requirements hidden
-   = note: required for `T` to implement `Trait<_>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
index 9cadd59c3dc9e60aebdd4dd6db892cb932bca88b..297245f0198b5e0d7a21ca7fc2651f457372fb97 100644 (file)
@@ -2,118 +2,118 @@ ast-stats-1 PRE EXPANSION AST STATS
 ast-stats-1 Name                Accumulated Size         Count     Item Size
 ast-stats-1 ----------------------------------------------------------------
 ast-stats-1 ExprField                 48 ( 0.6%)             1            48
-ast-stats-1 Crate                     56 ( 0.7%)             1            56
-ast-stats-1 Attribute                 64 ( 0.8%)             2            32
+ast-stats-1 Crate                     56 ( 0.8%)             1            56
+ast-stats-1 Attribute                 64 ( 0.9%)             2            32
 ast-stats-1 - Normal                    32 ( 0.4%)             1
 ast-stats-1 - DocComment                32 ( 0.4%)             1
-ast-stats-1 GenericArgs               64 ( 0.8%)             1            64
-ast-stats-1 - AngleBracketed            64 ( 0.8%)             1
-ast-stats-1 Local                     72 ( 0.9%)             1            72
-ast-stats-1 WherePredicate            72 ( 0.9%)             1            72
-ast-stats-1 - BoundPredicate            72 ( 0.9%)             1
-ast-stats-1 Arm                       96 ( 1.1%)             2            48
-ast-stats-1 ForeignItem               96 ( 1.1%)             1            96
-ast-stats-1 - Fn                        96 ( 1.1%)             1
-ast-stats-1 FieldDef                 160 ( 1.9%)             2            80
-ast-stats-1 Stmt                     160 ( 1.9%)             5            32
+ast-stats-1 GenericArgs               64 ( 0.9%)             1            64
+ast-stats-1 - AngleBracketed            64 ( 0.9%)             1
+ast-stats-1 Local                     72 ( 1.0%)             1            72
+ast-stats-1 WherePredicate            72 ( 1.0%)             1            72
+ast-stats-1 - BoundPredicate            72 ( 1.0%)             1
+ast-stats-1 Arm                       96 ( 1.3%)             2            48
+ast-stats-1 ForeignItem               96 ( 1.3%)             1            96
+ast-stats-1 - Fn                        96 ( 1.3%)             1
+ast-stats-1 FieldDef                 160 ( 2.2%)             2            80
+ast-stats-1 Stmt                     160 ( 2.2%)             5            32
 ast-stats-1 - Local                     32 ( 0.4%)             1
 ast-stats-1 - MacCall                   32 ( 0.4%)             1
-ast-stats-1 - Expr                      96 ( 1.1%)             3
-ast-stats-1 Param                    160 ( 1.9%)             4            40
-ast-stats-1 FnDecl                   200 ( 2.4%)             5            40
-ast-stats-1 Variant                  240 ( 2.9%)             2           120
-ast-stats-1 Block                    288 ( 3.4%)             6            48
-ast-stats-1 GenericBound             352 ( 4.2%)             4            88
-ast-stats-1 - Trait                    352 ( 4.2%)             4
-ast-stats-1 AssocItem                416 ( 4.9%)             4           104
-ast-stats-1 - Type                     208 ( 2.5%)             2
-ast-stats-1 - Fn                       208 ( 2.5%)             2
-ast-stats-1 GenericParam             480 ( 5.7%)             5            96
-ast-stats-1 PathSegment              720 ( 8.6%)            30            24
-ast-stats-1 Expr                     832 ( 9.9%)             8           104
-ast-stats-1 - Path                     104 ( 1.2%)             1
-ast-stats-1 - Match                    104 ( 1.2%)             1
-ast-stats-1 - Struct                   104 ( 1.2%)             1
-ast-stats-1 - Lit                      208 ( 2.5%)             2
-ast-stats-1 - Block                    312 ( 3.7%)             3
-ast-stats-1 Pat                      840 (10.0%)             7           120
-ast-stats-1 - Struct                   120 ( 1.4%)             1
-ast-stats-1 - Wild                     120 ( 1.4%)             1
-ast-stats-1 - Ident                    600 ( 7.1%)             5
-ast-stats-1 Ty                     1_344 (16.0%)            14            96
-ast-stats-1 - Rptr                      96 ( 1.1%)             1
-ast-stats-1 - Ptr                       96 ( 1.1%)             1
-ast-stats-1 - ImplicitSelf             192 ( 2.3%)             2
-ast-stats-1 - Path                     960 (11.4%)            10
-ast-stats-1 Item                   1_656 (19.7%)             9           184
-ast-stats-1 - Trait                    184 ( 2.2%)             1
-ast-stats-1 - Enum                     184 ( 2.2%)             1
-ast-stats-1 - ForeignMod               184 ( 2.2%)             1
-ast-stats-1 - Impl                     184 ( 2.2%)             1
-ast-stats-1 - Fn                       368 ( 4.4%)             2
-ast-stats-1 - Use                      552 ( 6.6%)             3
+ast-stats-1 - Expr                      96 ( 1.3%)             3
+ast-stats-1 Param                    160 ( 2.2%)             4            40
+ast-stats-1 FnDecl                   200 ( 2.7%)             5            40
+ast-stats-1 Variant                  240 ( 3.2%)             2           120
+ast-stats-1 GenericBound             288 ( 3.9%)             4            72
+ast-stats-1 - Trait                    288 ( 3.9%)             4
+ast-stats-1 Block                    288 ( 3.9%)             6            48
+ast-stats-1 AssocItem                416 ( 5.6%)             4           104
+ast-stats-1 - Type                     208 ( 2.8%)             2
+ast-stats-1 - Fn                       208 ( 2.8%)             2
+ast-stats-1 GenericParam             480 ( 6.5%)             5            96
+ast-stats-1 Expr                     576 ( 7.8%)             8            72
+ast-stats-1 - Path                      72 ( 1.0%)             1
+ast-stats-1 - Match                     72 ( 1.0%)             1
+ast-stats-1 - Struct                    72 ( 1.0%)             1
+ast-stats-1 - Lit                      144 ( 1.9%)             2
+ast-stats-1 - Block                    216 ( 2.9%)             3
+ast-stats-1 Pat                      616 ( 8.3%)             7            88
+ast-stats-1 - Struct                    88 ( 1.2%)             1
+ast-stats-1 - Wild                      88 ( 1.2%)             1
+ast-stats-1 - Ident                    440 ( 5.9%)             5
+ast-stats-1 PathSegment              720 ( 9.7%)            30            24
+ast-stats-1 Ty                       896 (12.1%)            14            64
+ast-stats-1 - Rptr                      64 ( 0.9%)             1
+ast-stats-1 - Ptr                       64 ( 0.9%)             1
+ast-stats-1 - ImplicitSelf             128 ( 1.7%)             2
+ast-stats-1 - Path                     640 ( 8.6%)            10
+ast-stats-1 Item                   1_656 (22.3%)             9           184
+ast-stats-1 - Trait                    184 ( 2.5%)             1
+ast-stats-1 - Enum                     184 ( 2.5%)             1
+ast-stats-1 - ForeignMod               184 ( 2.5%)             1
+ast-stats-1 - Impl                     184 ( 2.5%)             1
+ast-stats-1 - Fn                       368 ( 5.0%)             2
+ast-stats-1 - Use                      552 ( 7.4%)             3
 ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total                  8_416
+ast-stats-1 Total                  7_424
 ast-stats-1
 ast-stats-2 POST EXPANSION AST STATS
 ast-stats-2 Name                Accumulated Size         Count     Item Size
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 ExprField                 48 ( 0.5%)             1            48
-ast-stats-2 Crate                     56 ( 0.6%)             1            56
-ast-stats-2 GenericArgs               64 ( 0.7%)             1            64
-ast-stats-2 - AngleBracketed            64 ( 0.7%)             1
-ast-stats-2 Local                     72 ( 0.8%)             1            72
-ast-stats-2 WherePredicate            72 ( 0.8%)             1            72
-ast-stats-2 - BoundPredicate            72 ( 0.8%)             1
-ast-stats-2 Arm                       96 ( 1.0%)             2            48
-ast-stats-2 ForeignItem               96 ( 1.0%)             1            96
-ast-stats-2 - Fn                        96 ( 1.0%)             1
-ast-stats-2 InlineAsm                120 ( 1.3%)             1           120
-ast-stats-2 Attribute                128 ( 1.4%)             4            32
-ast-stats-2 - DocComment                32 ( 0.3%)             1
-ast-stats-2 - Normal                    96 ( 1.0%)             3
-ast-stats-2 FieldDef                 160 ( 1.7%)             2            80
-ast-stats-2 Stmt                     160 ( 1.7%)             5            32
-ast-stats-2 - Local                     32 ( 0.3%)             1
-ast-stats-2 - Semi                      32 ( 0.3%)             1
-ast-stats-2 - Expr                      96 ( 1.0%)             3
-ast-stats-2 Param                    160 ( 1.7%)             4            40
-ast-stats-2 FnDecl                   200 ( 2.2%)             5            40
-ast-stats-2 Variant                  240 ( 2.6%)             2           120
-ast-stats-2 Block                    288 ( 3.1%)             6            48
-ast-stats-2 GenericBound             352 ( 3.8%)             4            88
-ast-stats-2 - Trait                    352 ( 3.8%)             4
-ast-stats-2 AssocItem                416 ( 4.5%)             4           104
-ast-stats-2 - Type                     208 ( 2.3%)             2
-ast-stats-2 - Fn                       208 ( 2.3%)             2
-ast-stats-2 GenericParam             480 ( 5.2%)             5            96
-ast-stats-2 PathSegment              792 ( 8.7%)            33            24
-ast-stats-2 Pat                      840 ( 9.2%)             7           120
-ast-stats-2 - Struct                   120 ( 1.3%)             1
-ast-stats-2 - Wild                     120 ( 1.3%)             1
-ast-stats-2 - Ident                    600 ( 6.6%)             5
-ast-stats-2 Expr                     936 (10.2%)             9           104
-ast-stats-2 - Path                     104 ( 1.1%)             1
-ast-stats-2 - Match                    104 ( 1.1%)             1
-ast-stats-2 - Struct                   104 ( 1.1%)             1
-ast-stats-2 - InlineAsm                104 ( 1.1%)             1
-ast-stats-2 - Lit                      208 ( 2.3%)             2
-ast-stats-2 - Block                    312 ( 3.4%)             3
-ast-stats-2 Ty                     1_344 (14.7%)            14            96
-ast-stats-2 - Rptr                      96 ( 1.0%)             1
-ast-stats-2 - Ptr                       96 ( 1.0%)             1
-ast-stats-2 - ImplicitSelf             192 ( 2.1%)             2
-ast-stats-2 - Path                     960 (10.5%)            10
-ast-stats-2 Item                   2_024 (22.1%)            11           184
-ast-stats-2 - Trait                    184 ( 2.0%)             1
-ast-stats-2 - Enum                     184 ( 2.0%)             1
-ast-stats-2 - ExternCrate              184 ( 2.0%)             1
-ast-stats-2 - ForeignMod               184 ( 2.0%)             1
-ast-stats-2 - Impl                     184 ( 2.0%)             1
-ast-stats-2 - Fn                       368 ( 4.0%)             2
-ast-stats-2 - Use                      736 ( 8.0%)             4
+ast-stats-2 ExprField                 48 ( 0.6%)             1            48
+ast-stats-2 Crate                     56 ( 0.7%)             1            56
+ast-stats-2 GenericArgs               64 ( 0.8%)             1            64
+ast-stats-2 - AngleBracketed            64 ( 0.8%)             1
+ast-stats-2 Local                     72 ( 0.9%)             1            72
+ast-stats-2 WherePredicate            72 ( 0.9%)             1            72
+ast-stats-2 - BoundPredicate            72 ( 0.9%)             1
+ast-stats-2 Arm                       96 ( 1.2%)             2            48
+ast-stats-2 ForeignItem               96 ( 1.2%)             1            96
+ast-stats-2 - Fn                        96 ( 1.2%)             1
+ast-stats-2 InlineAsm                120 ( 1.5%)             1           120
+ast-stats-2 Attribute                128 ( 1.6%)             4            32
+ast-stats-2 - DocComment                32 ( 0.4%)             1
+ast-stats-2 - Normal                    96 ( 1.2%)             3
+ast-stats-2 FieldDef                 160 ( 2.0%)             2            80
+ast-stats-2 Stmt                     160 ( 2.0%)             5            32
+ast-stats-2 - Local                     32 ( 0.4%)             1
+ast-stats-2 - Semi                      32 ( 0.4%)             1
+ast-stats-2 - Expr                      96 ( 1.2%)             3
+ast-stats-2 Param                    160 ( 2.0%)             4            40
+ast-stats-2 FnDecl                   200 ( 2.5%)             5            40
+ast-stats-2 Variant                  240 ( 3.0%)             2           120
+ast-stats-2 GenericBound             288 ( 3.5%)             4            72
+ast-stats-2 - Trait                    288 ( 3.5%)             4
+ast-stats-2 Block                    288 ( 3.5%)             6            48
+ast-stats-2 AssocItem                416 ( 5.1%)             4           104
+ast-stats-2 - Type                     208 ( 2.6%)             2
+ast-stats-2 - Fn                       208 ( 2.6%)             2
+ast-stats-2 GenericParam             480 ( 5.9%)             5            96
+ast-stats-2 Pat                      616 ( 7.6%)             7            88
+ast-stats-2 - Struct                    88 ( 1.1%)             1
+ast-stats-2 - Wild                      88 ( 1.1%)             1
+ast-stats-2 - Ident                    440 ( 5.4%)             5
+ast-stats-2 Expr                     648 ( 8.0%)             9            72
+ast-stats-2 - Path                      72 ( 0.9%)             1
+ast-stats-2 - Match                     72 ( 0.9%)             1
+ast-stats-2 - Struct                    72 ( 0.9%)             1
+ast-stats-2 - InlineAsm                 72 ( 0.9%)             1
+ast-stats-2 - Lit                      144 ( 1.8%)             2
+ast-stats-2 - Block                    216 ( 2.7%)             3
+ast-stats-2 PathSegment              792 ( 9.8%)            33            24
+ast-stats-2 Ty                       896 (11.0%)            14            64
+ast-stats-2 - Rptr                      64 ( 0.8%)             1
+ast-stats-2 - Ptr                       64 ( 0.8%)             1
+ast-stats-2 - ImplicitSelf             128 ( 1.6%)             2
+ast-stats-2 - Path                     640 ( 7.9%)            10
+ast-stats-2 Item                   2_024 (24.9%)            11           184
+ast-stats-2 - Trait                    184 ( 2.3%)             1
+ast-stats-2 - Enum                     184 ( 2.3%)             1
+ast-stats-2 - ExternCrate              184 ( 2.3%)             1
+ast-stats-2 - ForeignMod               184 ( 2.3%)             1
+ast-stats-2 - Impl                     184 ( 2.3%)             1
+ast-stats-2 - Fn                       368 ( 4.5%)             2
+ast-stats-2 - Use                      736 ( 9.1%)             4
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total                  9_144
+ast-stats-2 Total                  8_120
 ast-stats-2
 hir-stats HIR STATS
 hir-stats Name                Accumulated Size         Count     Item Size
diff --git a/src/test/ui/structs/multi-line-fru-suggestion.rs b/src/test/ui/structs/multi-line-fru-suggestion.rs
new file mode 100644 (file)
index 0000000..7b2b139
--- /dev/null
@@ -0,0 +1,22 @@
+#[derive(Default)]
+struct Inner {
+    a: u8,
+    b: u8,
+}
+
+#[derive(Default)]
+struct Outer {
+    inner: Inner,
+    defaulted: u8,
+}
+
+fn main(){
+    Outer {
+        //~^ ERROR missing field `defaulted` in initializer of `Outer`
+        inner: Inner {
+            a: 1,
+            b: 2,
+        }
+        ..Default::default()
+    };
+}
diff --git a/src/test/ui/structs/multi-line-fru-suggestion.stderr b/src/test/ui/structs/multi-line-fru-suggestion.stderr
new file mode 100644 (file)
index 0000000..8bbd3ac
--- /dev/null
@@ -0,0 +1,25 @@
+error[E0063]: missing field `defaulted` in initializer of `Outer`
+  --> $DIR/multi-line-fru-suggestion.rs:14:5
+   |
+LL |     Outer {
+   |     ^^^^^ missing `defaulted`
+   |
+note: this expression may have been misinterpreted as a `..` range expression
+  --> $DIR/multi-line-fru-suggestion.rs:16:16
+   |
+LL |           inner: Inner {
+   |  ________________^
+LL | |             a: 1,
+LL | |             b: 2,
+LL | |         }
+   | |_________^ this expression does not end in a comma...
+LL |           ..Default::default()
+   |           ^^^^^^^^^^^^^^^^^^^^ ... so this is interpreted as a `..` range expression, instead of functional record update syntax
+help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
+   |
+LL |         }, 
+   |          +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0063`.
index 49e38b196deb210e7cd3258b9c2601cad92972fc..d93a62185b3f17184522f6a52aa0de0e666d81cd 100644 (file)
@@ -7,9 +7,8 @@ struct A {
 }
 
 fn a() {
-    let q = A { c: 5,..Default::default() };
-    //~^ ERROR mismatched types
-    //~| ERROR missing fields
+    let q = A { c: 5, ..Default::default() };
+    //~^ ERROR missing fields
     //~| HELP separate the last named field with a comma
     let r = A { c: 5, ..Default::default() };
     assert_eq!(q, r);
@@ -21,7 +20,7 @@ struct B {
 }
 
 fn b() {
-    let q = B { b: 1,..Default::default() };
+    let q = B { b: 1, ..Default::default() };
     //~^ ERROR mismatched types
     //~| HELP separate the last named field with a comma
     let r = B { b: 1 };
index 901f310c8bdb21a7434a1d611ce11c7d158b6506..f0fd1c94e9ab5d2c386f6567e32ee28f9d61019f 100644 (file)
@@ -8,8 +8,7 @@ struct A {
 
 fn a() {
     let q = A { c: 5..Default::default() };
-    //~^ ERROR mismatched types
-    //~| ERROR missing fields
+    //~^ ERROR missing fields
     //~| HELP separate the last named field with a comma
     let r = A { c: 5, ..Default::default() };
     assert_eq!(q, r);
index 66e9f021ed68fbfb60a3b5ec7ba20a7a81db77f0..f4fd655e698b08171f3d6375d673c6d098f9ab5d 100644 (file)
@@ -1,37 +1,38 @@
-error[E0308]: mismatched types
-  --> $DIR/struct-record-suggestion.rs:10:20
-   |
-LL |     let q = A { c: 5..Default::default() };
-   |                    ^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found struct `std::ops::Range`
-   |
-   = note: expected type `u64`
-            found struct `std::ops::Range<{integer}>`
-
 error[E0063]: missing fields `b` and `d` in initializer of `A`
   --> $DIR/struct-record-suggestion.rs:10:13
    |
 LL |     let q = A { c: 5..Default::default() };
    |             ^ missing `b` and `d`
    |
+note: this expression may have been misinterpreted as a `..` range expression
+  --> $DIR/struct-record-suggestion.rs:10:20
+   |
+LL |     let q = A { c: 5..Default::default() };
+   |                    ^^^^^^^^^^^^^^^^^^^^^
 help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
    |
-LL |     let q = A { c: 5,..Default::default() };
+LL |     let q = A { c: 5, ..Default::default() };
    |                     +
 
 error[E0308]: mismatched types
-  --> $DIR/struct-record-suggestion.rs:24:20
+  --> $DIR/struct-record-suggestion.rs:23:20
    |
 LL |     let q = B { b: 1..Default::default() };
    |                    ^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found struct `std::ops::Range`
    |
    = note: expected type `u32`
             found struct `std::ops::Range<{integer}>`
+note: this expression may have been misinterpreted as a `..` range expression
+  --> $DIR/struct-record-suggestion.rs:23:20
+   |
+LL |     let q = B { b: 1..Default::default() };
+   |                    ^^^^^^^^^^^^^^^^^^^^^
 help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
    |
-LL |     let q = B { b: 1,..Default::default() };
+LL |     let q = B { b: 1, ..Default::default() };
    |                     +
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0063, E0308.
 For more information about an error, try `rustc --explain E0063`.
index b17c4dc5dfb50998df9cca962e3023e696215420..08d4b99559031e9c9f63d7a357e9e45d4c5f2733 100644 (file)
@@ -2,7 +2,10 @@ error[E0599]: no method named `func` found for type `i32` in the current scope
   --> $DIR/issue-102354.rs:9:7
    |
 LL |     x.func();
-   |       ^^^^ this is an associated function, not a method
+   |     --^^^^--
+   |     | |
+   |     | this is an associated function, not a method
+   |     help: use associated function syntax instead: `i32::func()`
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
 note: the candidate is defined in the trait `Trait`
@@ -10,14 +13,6 @@ note: the candidate is defined in the trait `Trait`
    |
 LL |     fn func() {}
    |     ^^^^^^^^^
-help: use associated function syntax instead
-   |
-LL |     i32::func();
-   |     ~~~~~~~~~~~
-help: disambiguate the associated function for the candidate
-   |
-LL |     <i32 as Trait>::func(x);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/issue-104287.rs b/src/test/ui/suggestions/issue-104287.rs
new file mode 100644 (file)
index 0000000..b7601a5
--- /dev/null
@@ -0,0 +1,9 @@
+// The purpose of this test is not to validate the output of the compiler.
+// Instead, it ensures the suggestion is generated without performing an arithmetic overflow.
+
+fn main() {
+    let x = not_found; //~ ERROR cannot find value `not_found` in this scope
+    simd_gt::<()>(x);
+    //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
+    //~| ERROR cannot find function `simd_gt` in this scope
+}
diff --git a/src/test/ui/suggestions/issue-104287.stderr b/src/test/ui/suggestions/issue-104287.stderr
new file mode 100644 (file)
index 0000000..4b302dd
--- /dev/null
@@ -0,0 +1,36 @@
+error[E0425]: cannot find value `not_found` in this scope
+  --> $DIR/issue-104287.rs:5:13
+   |
+LL |     let x = not_found;
+   |             ^^^^^^^^^ not found in this scope
+
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/issue-104287.rs:6:5
+   |
+LL |     simd_gt::<()>(x);
+   |     ^^^^^^^------ help: remove these generics
+   |     |
+   |     expected 0 generic arguments
+   |
+note: associated function defined here, with 0 generic parameters
+  --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/ord.rs:LL:COL
+   |
+LL |     fn simd_gt(self, other: Self) -> Self::Mask;
+   |        ^^^^^^^
+
+error[E0425]: cannot find function `simd_gt` in this scope
+  --> $DIR/issue-104287.rs:6:5
+   |
+LL |     simd_gt::<()>(x);
+   |     ^^^^^^^ not found in this scope
+   |
+help: use the `.` operator to call the method `SimdPartialOrd::simd_gt` on `[type error]`
+   |
+LL -     simd_gt::<()>(x);
+LL +     x.simd_gt();
+   |
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0107, E0425.
+For more information about an error, try `rustc --explain E0107`.
index 499a64f2816992021f02384361c312da7bd6ca97..6474b2b38e1c089a164cb1c8d86e129126d6b19f 100644 (file)
@@ -2,6 +2,7 @@
 // compile-flags: -Zinline-mir=no
 // error-pattern: overflow evaluating the requirement `(): Sized`
 // error-pattern: function cannot return without recursing
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 
 // Regression test for #91949.
 // This hanged *forever* on 1.56, fixed by #90423.
index 61b6d4b08bb6a1cc3ba4700dd1278a812db73a6a..a74d2524996a10d4d9f85c9ed166f1733264c3fe 100644 (file)
@@ -1,5 +1,5 @@
 warning: function cannot return without recursing
-  --> $DIR/issue-91949-hangs-on-recursion.rs:22:1
+  --> $DIR/issue-91949-hangs-on-recursion.rs:23:1
    |
 LL | / fn recurse<T>(elements: T) -> Vec<char>
 LL | | where
@@ -17,7 +17,8 @@ error[E0275]: overflow evaluating the requirement `(): Sized`
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`)
    = note: required for `std::iter::Empty<()>` to implement `Iterator`
    = note: 171 redundant requirements hidden
-   = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), std::iter::Empty<()>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>` to implement `Iterator`
+   = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>` to implement `Iterator`
+   = note: the full type name has been written to '$TEST_BUILD_DIR/traits/issue-91949-hangs-on-recursion/issue-91949-hangs-on-recursion.long-type-hash.txt'
 
 error: aborting due to previous error; 1 warning emitted
 
index bd3254af3df71837010a1eb3f74c77e537078889..7cd76286a929efbf054860ce2e3561a8ad9b1148 100644 (file)
@@ -7,4 +7,12 @@ fn main() {
         let x: &u32 = item;
         assert_eq!(x, &1);
     }
+    let iter_fun2 = <(&[u32])>::iter;
+    //~^ no function or associated item named `iter` found for reference `&[u32]` in the current scope [E0599]
+    //~| function or associated item not found in `&[u32]`
+    //~| HELP the function `iter` is implemented on `[u32]`
+    for item2 in iter_fun2(&[1,1]) {
+        let x: &u32 = item2;
+        assert_eq!(x, &1);
+    }
 }
index 02a59d4b99c4df3cb7f4e39b1a55541207ea6ceb..f4dac51b2b47852a6c4dd8dd7a640f454a544806 100644 (file)
@@ -9,6 +9,17 @@ help: the function `iter` is implemented on `[u32]`
 LL |     let iter_fun = <[u32]>::iter;
    |                     ~~~~~
 
-error: aborting due to previous error
+error[E0599]: no function or associated item named `iter` found for reference `&[u32]` in the current scope
+  --> $DIR/issue-103271.rs:10:33
+   |
+LL |     let iter_fun2 = <(&[u32])>::iter;
+   |                                 ^^^^ function or associated item not found in `&[u32]`
+   |
+help: the function `iter` is implemented on `[u32]`
+   |
+LL |     let iter_fun2 = <([u32])>::iter;
+   |                       ~~~~~
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0599`.
index ce6fdf811213f905513b0448b7058958c20e89d9..b3c12747414ed15a53432bf5b4055aa3a614dad7 100644 (file)
@@ -7,7 +7,7 @@
 // The exact type depends on optimizations, so disable them.
 
 #![allow(dead_code)]
-#![type_length_limit="4"]
+#![type_length_limit="8"]
 
 macro_rules! link {
     ($id:ident, $t:ty) => {
@@ -15,14 +15,19 @@ macro_rules! link {
     }
 }
 
+link! { A1, B1 }
+link! { B1, C1 }
+link! { C1, D1 }
+link! { D1, E1 }
+link! { E1, A }
 link! { A, B }
 link! { B, C }
 link! { C, D }
 link! { D, E }
 link! { E, F }
-link! { F, G }
+link! { F, G<Option<i32>, Option<i32>> }
 
-pub struct G;
+pub struct G<T, K>(std::marker::PhantomData::<(T, K)>);
 
 fn main() {
     drop::<Option<A>>(None);
index 84ac48b1e77b4ae610b45c204a22901536c97ddc..ff487466902236425d4be9180f9fb20f71ac6bd2 100644 (file)
@@ -1,20 +1,11 @@
-error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((...,....., ...), ..., ...), ..., ...)>>`
+error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((..., ..., ...), ..., ...), ..., ...), ..., ...)>>`
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
    |
 LL | pub fn drop<T>(_x: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
+   = help: consider adding a `#![type_length_limit="10"]` attribute to your crate
    = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
 
-error: reached the type-length limit while instantiating `<[closure@std::rt::lang_start<()...e<()>>::call_once - shim(vtable)`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-LL |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
-   = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
index 16b097879b6f117c8ae698aab054c87f26ff325e..eb5d35917b2395194593c9ca70c3778f60c1573b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 16b097879b6f117c8ae698aab054c87f26ff325e
+Subproject commit eb5d35917b2395194593c9ca70c3778f60c1573b
index 0f1d701865e7d711bbf8ae1bdb949c31d5214611..29425b2e5541791db6c485d904a38981abda173b 100644 (file)
@@ -61,10 +61,10 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
                     }
                 }
             },
-            ExprKind::MethodCall(_, _, ref params, _) => {
-                if let [ref param] = params[..] {
-                    if let ExprKind::Paren(_) = param.kind {
-                        span_lint(cx, DOUBLE_PARENS, param.span, msg);
+            ExprKind::MethodCall(ref call) => {
+                if let [ref arg] = call.args[..] {
+                    if let ExprKind::Paren(_) = arg.kind {
+                        span_lint(cx, DOUBLE_PARENS, arg.span, msg);
                     }
                 }
             },
index bc0c68f535a96f23e1cfd0d9b75ef55665b7d875..d0fab6949604090dfb02129c971eccb4246dd7be 100644 (file)
@@ -73,7 +73,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
                 if format_args.format_string.parts == [kw::Empty];
                 if arg.format.is_default();
                 if match cx.typeck_results().expr_ty(value).peel_refs().kind() {
-                    ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did()),
+                    ty::Adt(adt, _) => Some(adt.did()) == cx.tcx.lang_items().string(),
                     ty::Str => true,
                     _ => false,
                 };
index 9b9f1872bfc1d2cf5b42a86253b05ccb2db63927..68c5c3673fe1544fb3e3c0b80df66870afa9df52 100644 (file)
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use clippy_utils::{match_def_path, paths, peel_hir_expr_refs};
-use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
@@ -41,7 +41,7 @@
 declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]);
 
 fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
-    is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String)
+    is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
 }
 fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
     if let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id {
index cf8b7acd66d22ab4d9e627e95d0a4117573d4df0..74a60b6a0d24b4ba8ba1a70f604d9bce2d5791be 100644 (file)
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::is_integer_literal;
 use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
-use rustc_hir::{def, Expr, ExprKind, PrimTy, QPath, TyKind};
+use rustc_hir::{def, Expr, ExprKind, LangItem, PrimTy, QPath, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -98,5 +98,5 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, exp: &Expr<'tcx>) {
 
 /// Checks if a Ty is `String` or `&str`
 fn is_ty_stringish(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
-    is_type_diagnostic_item(cx, ty, sym::String) || is_type_diagnostic_item(cx, ty, sym::str)
+    is_type_lang_item(cx, ty, LangItem::String) || is_type_diagnostic_item(cx, ty, sym::str)
 }
index 14a37f535b46c9e711cd23436ba89bf445f736be..aaecc4fa8f25698e68b705906deba938d01ed6f8 100644 (file)
@@ -1,8 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
+use clippy_utils::ty::{implements_trait, is_type_lang_item};
 use clippy_utils::{return_ty, trait_ref_of_method};
 use if_chain::if_chain;
-use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind};
+use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
@@ -105,7 +105,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<
             if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
 
             // Check if return type is String
-            if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String);
+            if is_type_lang_item(cx, return_ty(cx, impl_item.hir_id()), LangItem::String);
 
             // Filters instances of to_string which are required by a trait
             if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none();
index 090f9f8ff73cfd40e9825954d4b5c163ae6a6ccc..5c6a342b3d074221eaaa9296b06e4a89c9e8e1ae 100644 (file)
@@ -6,7 +6,7 @@
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound,
-    HirId, IsAsync, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
+    HirId, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -49,7 +49,7 @@ fn check_fn(
     ) {
         if_chain! {
             if let Some(header) = kind.header();
-            if header.asyncness == IsAsync::NotAsync;
+            if !header.asyncness.is_async();
             // Check that this function returns `impl Future`
             if let FnRetTy::Return(ret_ty) = decl.output;
             if let Some((trait_ref, output_lifetimes)) = future_trait_ref(cx, ret_ty);
index 6abbab278feb4e5306de1fb84c19de0c42781440..d6438ca7fec2aca306b8be7c776eef7fef382b33 100644 (file)
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
 use clippy_utils::{get_parent_expr, match_def_path, paths, SpanlessEq};
 use clippy_utils::{meets_msrv, msrvs};
 use rustc_errors::Applicability;
@@ -140,7 +140,7 @@ fn check_to_owned(
         && let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id)
         && match_def_path(cx, chars_expr_def_id, &paths::STR_CHARS)
         && let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
-        && is_type_diagnostic_item(cx, ty, sym::String)
+        && is_type_lang_item(cx, ty, hir::LangItem::String)
         && SpanlessEq::new(cx).eq_expr(left_expr, str_expr) {
         suggest(cx, parent_expr, left_expr, filter_expr);
     }
index 6acfb2ae3471c3b3a4f3840b609d490af95e0cfe..c20d7959fc4a258576c48ec3792fc2f90338c4cb 100644 (file)
@@ -44,7 +44,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
         let ty = cx.typeck_results().expr_ty(expr);
         match ty.kind() {
             ty::Adt(adt_def, _) if adt_def.is_struct() => {
-                if !cx.tcx.is_diagnostic_item(sym::String, adt_def.did()) {
+                if cx.tcx.lang_items().string() != Some(adt_def.did()) {
                     return;
                 }
             },
index 6647322caa37a846520edfc81251261d9e312c6c..675a85ae5553a7833079969be6d354f0291bcdae 100644 (file)
@@ -1,13 +1,13 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::{Arm, Expr, ExprKind, PatKind};
+use rustc_hir::{Arm, Expr, ExprKind, LangItem, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_span::symbol::Symbol;
-use rustc_span::{sym, Span};
+use rustc_span::Span;
 
 use super::MATCH_STR_CASE_MISMATCH;
 
@@ -59,7 +59,7 @@ fn case_altered(&mut self, segment_ident: &str, receiver: &Expr<'_>) -> bool {
         if let Some(case_method) = get_case_method(segment_ident) {
             let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();
 
-            if is_type_diagnostic_item(self.cx, ty, sym::String) || ty.kind() == &ty::Str {
+            if is_type_lang_item(self.cx, ty, LangItem::String) || ty.kind() == &ty::Str {
                 self.case_method = Some(case_method);
                 return true;
             }
index fcfc25b523dac4d6dc16ff284fea4fe55e4d2e2f..89aaad359d4acf09662cd41e666620ec407ac5c6 100644 (file)
@@ -1,11 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
-use rustc_span::sym;
 
 use super::BYTES_COUNT_TO_LEN;
 
@@ -20,7 +19,7 @@ pub(super) fn check<'tcx>(
         if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id);
         if cx.tcx.type_of(impl_id).is_str();
         let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs();
-        if ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String);
+        if ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String);
         then {
             let mut applicability = Applicability::MachineApplicable;
             span_lint_and_sugg(
index 2e96346be977e839716708929bfeede60207d612..d512cc4eeae125acebd79058624d98ade6ab2d49 100644 (file)
@@ -1,10 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use rustc_errors::Applicability;
-use rustc_hir::Expr;
+use rustc_hir::{Expr, LangItem};
 use rustc_lint::LateContext;
-use rustc_span::sym;
 
 use super::BYTES_NTH;
 
@@ -12,7 +11,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
     let ty = cx.typeck_results().expr_ty(recv).peel_refs();
     let caller_type = if ty.is_str() {
         "str"
-    } else if is_type_diagnostic_item(cx, ty, sym::String) {
+    } else if is_type_lang_item(cx, ty, LangItem::String) {
         "String"
     } else {
         return;
index b3c2c7c9a2dcc3a70cac63fe2363ecf238a1d514..d226c0bba6593f4fccfc89237d866d8d8d1784e2 100644 (file)
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, LangItem};
 use rustc_lint::LateContext;
-use rustc_span::{source_map::Spanned, symbol::sym, Span};
+use rustc_span::{source_map::Spanned, Span};
 
 use super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS;
 
@@ -26,7 +26,7 @@ pub(super) fn check<'tcx>(
         if ext_str.chars().skip(1).all(|c| c.is_uppercase() || c.is_ascii_digit())
             || ext_str.chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit());
         let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();
-        if recv_ty.is_str() || is_type_diagnostic_item(cx, recv_ty, sym::String);
+        if recv_ty.is_str() || is_type_lang_item(cx, recv_ty, LangItem::String);
         then {
             span_lint_and_help(
                 cx,
index d0cf411dfd34caca494b9675d518fe742a1c4653..a9189b31c57108990d96fbe740632ede6cb3c6f6 100644 (file)
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn};
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -33,7 +33,7 @@ fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Ex
                     if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && {
                         let arg_type = cx.typeck_results().expr_ty(receiver);
                         let base_type = arg_type.peel_refs();
-                        *base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym::String)
+                        *base_type.kind() == ty::Str || is_type_lang_item(cx, base_type, hir::LangItem::String)
                     } {
                         receiver
                     } else {
@@ -50,7 +50,7 @@ fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Ex
     // converted to string.
     fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
         let arg_ty = cx.typeck_results().expr_ty(arg);
-        if is_type_diagnostic_item(cx, arg_ty, sym::String) {
+        if is_type_lang_item(cx, arg_ty, hir::LangItem::String) {
             return false;
         }
         if let ty::Ref(_, ty, ..) = arg_ty.kind() {
index ede3b8bb74e97c7353dcef5154a167057bceb612..4f4f543e8a912abd079ddaf9b74724100376ce00 100644 (file)
@@ -1,13 +1,13 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::{is_type_diagnostic_item, walk_ptrs_ty_depth};
+use clippy_utils::ty::{is_type_lang_item, walk_ptrs_ty_depth};
 use clippy_utils::{match_def_path, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{Symbol, sym};
 
 use super::INEFFICIENT_TO_STRING;
 
@@ -60,7 +60,7 @@ fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
         return true;
     }
 
-    if is_type_diagnostic_item(cx, ty, sym::String) {
+    if is_type_lang_item(cx, ty, hir::LangItem::String) {
         return true;
     }
 
index 8b6b8f1bf16cbbfcf6952c4dac6fd684448d85e3..13c47c03a80dd583d6a006315dc2ce3fdd3f30f5 100644 (file)
@@ -36,14 +36,14 @@ fn parse_repeat_arg(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<RepeatKind> {
         }
     } else {
         let ty = cx.typeck_results().expr_ty(e);
-        if is_type_diagnostic_item(cx, ty, sym::String)
+        if is_type_lang_item(cx, ty, LangItem::String)
             || (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, Ty::is_str))
             || (is_type_diagnostic_item(cx, ty, sym::Cow) && get_ty_param(ty).map_or(false, Ty::is_str))
         {
             Some(RepeatKind::String)
         } else {
             let ty = ty.peel_refs();
-            (ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)).then_some(RepeatKind::String)
+            (ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)).then_some(RepeatKind::String)
         }
     }
 }
@@ -58,7 +58,7 @@ pub(super) fn check(
     if_chain! {
         if let ExprKind::Call(repeat_fn, [repeat_arg]) = take_self_arg.kind;
         if is_path_diagnostic_item(cx, repeat_fn, sym::iter_repeat);
-        if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(collect_expr), sym::String);
+        if is_type_lang_item(cx, cx.typeck_results().expr_ty(collect_expr), LangItem::String);
         if let Some(collect_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id);
         if let Some(take_id) = cx.typeck_results().type_dependent_def_id(take_expr.hir_id);
         if let Some(iter_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
index a76341855b6db8fbb34cb2fb56f98317091acb2b..01655e860c43fa6c6c3d21f572ffc186d8dd899f 100644 (file)
@@ -1,11 +1,10 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use clippy_utils::SpanlessEq;
 use if_chain::if_chain;
 use rustc_ast::LitKind;
-use rustc_hir::ExprKind;
+use rustc_hir::{ExprKind, LangItem};
 use rustc_lint::LateContext;
-use rustc_span::sym;
 
 use super::NO_EFFECT_REPLACE;
 
@@ -16,7 +15,7 @@ pub(super) fn check<'tcx>(
     arg2: &'tcx rustc_hir::Expr<'_>,
 ) {
     let ty = cx.typeck_results().expr_ty(expr).peel_refs();
-    if !(ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)) {
+    if !(ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)) {
         return;
     }
 
index 0a14f9216ab383f44f197a25820471a84c09f29f..a345ec813ff502f8231fc6cd777b35f042273401 100644 (file)
@@ -1,11 +1,10 @@
 use clippy_utils::consts::{constant_context, Constant};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use rustc_errors::Applicability;
-use rustc_hir::Expr;
+use rustc_hir::{Expr, LangItem};
 use rustc_lint::LateContext;
-use rustc_span::sym;
 
 use super::REPEAT_ONCE;
 
@@ -37,7 +36,7 @@ pub(super) fn check<'tcx>(
                 format!("{}.to_vec()", snippet(cx, recv.span, r#""...""#)),
                 Applicability::MachineApplicable,
             );
-        } else if is_type_diagnostic_item(cx, ty, sym::String) {
+        } else if is_type_lang_item(cx, ty, LangItem::String) {
             span_lint_and_sugg(
                 cx,
                 REPEAT_ONCE,
index 324c9c17b5a9a36a7ad6a8fdf82fc16e18fca695..1c031ad6acbafbda64f697eb47c202da7072a3a2 100644 (file)
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::sugg::deref_closure_args;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use clippy_utils::{is_trait_method, strip_pat_refs};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
@@ -105,7 +105,7 @@ pub(super) fn check<'tcx>(
     else if search_method == "find" {
         let is_string_or_str_slice = |e| {
             let self_ty = cx.typeck_results().expr_ty(e).peel_refs();
-            if is_type_diagnostic_item(cx, self_ty, sym::String) {
+            if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
                 true
             } else {
                 *self_ty.kind() == ty::Str
index 6974260f70dbd4f4da082253a3ed0e16fbaeb1e0..6f4cec546e969693a0ec9b5260dd98f3ea58f519 100644 (file)
@@ -1,18 +1,17 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::method_chain_args;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::symbol::sym;
 
 use super::STRING_EXTEND_CHARS;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
     let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
-    if !is_type_diagnostic_item(cx, obj_ty, sym::String) {
+    if !is_type_lang_item(cx, obj_ty, hir::LangItem::String) {
         return;
     }
     if let Some(arglists) = method_chain_args(arg, &["chars"]) {
@@ -20,7 +19,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
         let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
         let ref_str = if *self_ty.kind() == ty::Str {
             ""
-        } else if is_type_diagnostic_item(cx, self_ty, sym::String) {
+        } else if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
             "&"
         } else {
             return;
index 973b8a7e6bf6a9409f44e399e31d2bbbd3e1ea10..c9b87bc6bf29d8e9df51a8b64291438300d772e1 100644 (file)
@@ -1,10 +1,10 @@
-use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item};
+use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, LangItem};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{Ref, Slice};
-use rustc_span::{sym, Span};
+use rustc_span::Span;
 
 use super::UNNECESSARY_JOIN;
 
@@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
         // the turbofish for collect is ::<Vec<String>>
         if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind();
         if let Slice(slice) = ref_type.kind();
-        if is_type_diagnostic_item(cx, *slice, sym::String);
+        if is_type_lang_item(cx, *slice, LangItem::String);
         // the argument for join is ""
         if let ExprKind::Lit(spanned) = &join_arg.kind;
         if let LitKind::Str(symbol, _) = spanned.node;
index b2e9ce5c94d65db825d650b25e27505c93f48fc3..79aa15b06ef4d4abf97c94ebeef4b35e9dc15b4f 100644 (file)
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
 use clippy_utils::ptr::get_spans;
 use clippy_utils::source::{snippet, snippet_opt};
-use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item};
+use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
 use clippy_utils::{get_trait_def_id, is_self, paths};
 use if_chain::if_chain;
 use rustc_ast::ast::Attribute;
@@ -11,7 +11,7 @@
 use rustc_hir::{
     BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Mutability, Node, PatKind, QPath, TyKind,
 };
-use rustc_hir::{HirIdMap, HirIdSet};
+use rustc_hir::{HirIdMap, HirIdSet, LangItem};
 use rustc_hir_typeck::expr_use_visitor as euv;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
@@ -249,7 +249,7 @@ fn check_fn(
                             }
                         }
 
-                        if is_type_diagnostic_item(cx, ty, sym::String) {
+                        if is_type_lang_item(cx, ty, LangItem::String) {
                             if let Some(clone_spans) =
                                 get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) {
                                 diag.span_suggestion(
index d9ee031c9f9756ffe11968f79499cd56b0277bca..377bddeaa5feabccaa30f4a6e759baf33b152741 100644 (file)
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_direct_expn_of;
 use if_chain::if_chain;
-use rustc_ast::ast::{Expr, ExprKind};
+use rustc_ast::ast::{Expr, ExprKind, MethodCall};
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
@@ -37,8 +37,8 @@
 impl EarlyLintPass for OptionEnvUnwrap {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
         if_chain! {
-            if let ExprKind::MethodCall(path_segment, receiver, _, _) = &expr.kind;
-            if matches!(path_segment.ident.name, sym::expect | sym::unwrap);
+            if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind;
+            if matches!(seg.ident.name, sym::expect | sym::unwrap);
             if let ExprKind::Call(caller, _) = &receiver.kind;
             if is_direct_expn_of(caller.span, "option_env").is_some();
             then {
index bee4a33fb4a019b7dcb9d91fb48c38243431cc40..057b7e30642ec5bc0edd134d913bef1ec8c537e4 100644 (file)
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use if_chain::if_chain;
-use rustc_ast::ast::{BinOpKind, Expr, ExprKind, UnOp};
+use rustc_ast::ast::{BinOpKind, Expr, ExprKind, MethodCall, UnOp};
 use rustc_ast::token;
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
@@ -110,11 +110,11 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
             let mut arg = operand;
 
             let mut all_odd = true;
-            while let ExprKind::MethodCall(path_segment, receiver, _, _) = &arg.kind {
-                let path_segment_str = path_segment.ident.name.as_str();
+            while let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &arg.kind {
+                let seg_str = seg.ident.name.as_str();
                 all_odd &= ALLOWED_ODD_FUNCTIONS
                     .iter()
-                    .any(|odd_function| **odd_function == *path_segment_str);
+                    .any(|odd_function| **odd_function == *seg_str);
                 arg = receiver;
             }
 
index c8c6f32c6c98966cd4d794b0afcbe3f56f105d14..6aa5e13fe3186e31013bc94f0debdfef561cbae9 100644 (file)
@@ -450,7 +450,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                                 substs.type_at(0),
                             ),
                         ),
-                        Some(sym::String) => (
+                        _ if Some(adt.did()) == cx.tcx.lang_items().string() => (
                             [("clone", ".to_owned()"), ("as_str", "")].as_slice(),
                             DerefTy::Str,
                         ),
index aedbe08e3e46e2e340c0263cc7766f4ab9c50c81..c1677fb3da1c4850215dfd6a88e1ee485d4c54ed 100644 (file)
@@ -1,12 +1,12 @@
 use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
 use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap};
 use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, walk_ptrs_ty_depth};
+use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
 use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
-use rustc_hir::{def_id, Body, FnDecl, HirId};
+use rustc_hir::{def_id, Body, FnDecl, HirId, LangItem};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir;
 use rustc_middle::ty::{self, Ty};
@@ -102,7 +102,7 @@ fn check_fn(
             let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
                 || match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
                 || (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD)
-                    && is_type_diagnostic_item(cx, arg_ty, sym::String));
+                    && is_type_lang_item(cx, arg_ty, LangItem::String));
 
             let from_deref = !from_borrow
                 && (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
index 74eea6de4bbeff43d30c92d83a8553c73d6cfab9..4cbe9597c5393eee7221480dbb487aa6d863ce76 100644 (file)
@@ -69,10 +69,10 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
         if_chain! {
             if let ast::ExprKind::Call(ref paren, _) = expr.kind;
             if let ast::ExprKind::Paren(ref closure) = paren.kind;
-            if let ast::ExprKind::Closure(_, _, ref r#async, _, ref decl, ref block, _) = closure.kind;
+            if let ast::ExprKind::Closure(box ast::Closure { ref asyncness, ref fn_decl, ref body, .. }) = closure.kind;
             then {
                 let mut visitor = ReturnVisitor::new();
-                visitor.visit_expr(block);
+                visitor.visit_expr(body);
                 if !visitor.found_return {
                     span_lint_and_then(
                         cx,
@@ -80,13 +80,13 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
                         expr.span,
                         "try not to call a closure in the expression where it is declared",
                         |diag| {
-                            if decl.inputs.is_empty() {
+                            if fn_decl.inputs.is_empty() {
                                 let app = Applicability::MachineApplicable;
-                                let mut hint = Sugg::ast(cx, block, "..");
+                                let mut hint = Sugg::ast(cx, body, "..");
 
-                                if r#async.is_async() {
+                                if asyncness.is_async() {
                                     // `async x` is a syntax error, so it becomes `async { x }`
-                                    if !matches!(block.kind, ast::ExprKind::Block(_, _)) {
+                                    if !matches!(body.kind, ast::ExprKind::Block(_, _)) {
                                         hint = hint.blockify();
                                     }
 
index d356c99c8fc470c1cdd6371e3589acdbc3a8b8c4..f4705481d4e69b3131ad73ce0439ba6903092dca 100644 (file)
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg};
 use clippy_utils::source::{snippet, snippet_with_applicability};
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
 use clippy_utils::{get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths};
 use clippy_utils::{peel_blocks, SpanlessEq};
 use if_chain::if_chain;
@@ -190,7 +190,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
             },
             ExprKind::Index(target, _idx) => {
                 let e_ty = cx.typeck_results().expr_ty(target).peel_refs();
-                if matches!(e_ty.kind(), ty::Str) || is_type_diagnostic_item(cx, e_ty, sym::String) {
+                if matches!(e_ty.kind(), ty::Str) || is_type_lang_item(cx, e_ty, LangItem::String) {
                     span_lint(
                         cx,
                         STRING_SLICE,
@@ -205,7 +205,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
 }
 
 fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
-    is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String)
+    is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
 }
 
 fn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool {
@@ -446,7 +446,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
             if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind;
             if path.ident.name == sym::to_string;
             let ty = cx.typeck_results().expr_ty(self_arg);
-            if is_type_diagnostic_item(cx, ty, sym::String);
+            if is_type_lang_item(cx, ty, LangItem::String);
             then {
                 span_lint_and_help(
                     cx,
index eef9bdc78494002515ec1e615bc726062eaaf1bd..78e83880e1a6121020f0d6e0d724fee457fe46e0 100644 (file)
@@ -580,7 +580,7 @@ fn ident_difference_expr_with_base_location(
         | (Await(_), Await(_))
         | (Async(_, _, _), Async(_, _, _))
         | (Block(_, _), Block(_, _))
-        | (Closure(_, _, _, _, _, _, _), Closure(_, _, _, _, _, _, _))
+        | (Closure(_), Closure(_))
         | (Match(_, _), Match(_, _))
         | (Loop(_, _), Loop(_, _))
         | (ForLoop(_, _, _, _), ForLoop(_, _, _, _))
@@ -593,7 +593,7 @@ fn ident_difference_expr_with_base_location(
         | (Unary(_, _), Unary(_, _))
         | (Binary(_, _, _), Binary(_, _, _))
         | (Tup(_), Tup(_))
-        | (MethodCall(_, _, _, _), MethodCall(_, _, _, _))
+        | (MethodCall(_), MethodCall(_))
         | (Call(_, _), Call(_, _))
         | (ConstBlock(_), ConstBlock(_))
         | (Array(_), Array(_))
index 08020ce663817e1f2b8a60871d206068740d7474..802415e163df541c83b28a9dbcb2b7469be5854e 100644 (file)
@@ -37,18 +37,19 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
 fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol> {
     let param = qpath_generic_tys(qpath).next()?;
     let id = path_def_id(cx, param)?;
-    cx.tcx.get_diagnostic_name(id).filter(|&name| {
-        matches!(
-            name,
-            sym::HashMap
-                | sym::String
-                | sym::Vec
-                | sym::HashSet
-                | sym::VecDeque
-                | sym::LinkedList
-                | sym::BTreeMap
-                | sym::BTreeSet
-                | sym::BinaryHeap
-        )
-    })
+    cx.tcx
+        .get_diagnostic_name(id)
+        .filter(|&name| matches!(name, sym::HashMap | sym::Vec | sym::HashSet
+            | sym::VecDeque
+            | sym::LinkedList
+            | sym::BTreeMap
+            | sym::BTreeSet
+            | sym::BinaryHeap))
+        .or_else(|| {
+            cx.tcx
+                .lang_items()
+                .string()
+                .filter(|did| id == *did)
+                .map(|_| sym::String)
+        })
 }
index fa567b9b2d243661efa259217572da6005efcc9d..855137b14d84bdbee4802b3659225c936aff981f 100644 (file)
@@ -91,10 +91,10 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
 fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
     let ty = qpath_generic_tys(qpath).next()?;
     let id = path_def_id(cx, ty)?;
-    let path = match cx.tcx.get_diagnostic_name(id)? {
-        sym::String => "str",
-        sym::OsString => "std::ffi::OsStr",
-        sym::PathBuf => "std::path::Path",
+    let path = match cx.tcx.get_diagnostic_name(id) {
+        Some(sym::OsString) => "std::ffi::OsStr",
+        Some(sym::PathBuf) => "std::path::Path",
+        _ if Some(id) == cx.tcx.lang_items().string() => "str",
         _ => return None,
     };
     Some(path)
index ab73f0fc44f4edae35d4a18ecb4312c9b049c5b7..9f207d32fcfff1c4fff43c48266a9a24d72f1fa8 100644 (file)
@@ -1,13 +1,12 @@
-use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item};
+use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
 use clippy_utils::{match_def_path, paths};
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};
+use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -61,7 +60,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
                         if let LitKind::Str(symbol, _) = spanned.node;
                         if symbol.is_empty();
                         let inner_expr_type = cx.typeck_results().expr_ty(inner_expr);
-                        if is_type_diagnostic_item(cx, inner_expr_type, sym::String);
+                        if is_type_lang_item(cx, inner_expr_type, LangItem::String);
                         then {
                             span_lint_and_sugg(
                                 cx,
index b305dae76084c3e698263f59701c83698ca470db..bb6fb38e9690e32a3e472c49f1462bc38fa28d1b 100644 (file)
@@ -292,7 +292,7 @@ fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize)
 /// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
 /// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
 fn extend_with_struct_pat(
-    qself1: &Option<ast::QSelf>,
+    qself1: &Option<P<ast::QSelf>>,
     path1: &ast::Path,
     fps1: &mut [ast::PatField],
     rest1: bool,
index bf487c7ca20c89b833004962495f853e0c15ab4f..3538bef6e06185a13eb5a17ea1e5a9fb99816a8d 100644 (file)
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
-use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, IsAsync, YieldSource};
+use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, YieldSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -68,7 +68,7 @@ fn check_fn(
         span: Span,
         hir_id: HirId,
     ) {
-        if !span.from_expansion() && fn_kind.asyncness() == IsAsync::Async {
+        if !span.from_expansion() && fn_kind.asyncness().is_async() {
             let mut visitor = AsyncFnVisitor { cx, found_await: false };
             walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), hir_id);
             if !visitor.found_await {
index 3c1998d0237d989cf9180e4ec8a345468737a3c6..5ab351bc29ca0b8b1ba653287f1933cc70d99217 100644 (file)
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use rustc_ast::ast::{Expr, ExprKind};
+use rustc_ast::ast::{Expr, ExprKind, MethodCall};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -30,8 +30,8 @@
 declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]);
 
 fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> {
-    if let ExprKind::MethodCall(name_ident, receiver, _, _) = &expr.kind
-        && let method_name = name_ident.ident.name.as_str()
+    if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind
+        && let method_name = seg.ident.name.as_str()
         && (method_name == "ceil" || method_name == "round" || method_name == "floor")
         && let ExprKind::Lit(token_lit) = &receiver.kind
         && token_lit.is_semantic_float() {
index 25532dd4e2681e6455921480339e937b536e3e92..22a5aa5351ad5b1c044319975a19c81869ddba15 100644 (file)
@@ -79,22 +79,22 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
         SimplifiedTypeGen::StrSimplifiedType,
     ]
     .iter()
-    .flat_map(|&ty| cx.tcx.incoherent_impls(ty));
-    for item_def_id in lang_items.items().iter().flatten().chain(incoherent_impls) {
-        let lang_item_path = cx.get_def_path(*item_def_id);
+    .flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter().copied());
+    for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) {
+        let lang_item_path = cx.get_def_path(item_def_id);
         if path_syms.starts_with(&lang_item_path) {
             if let [item] = &path_syms[lang_item_path.len()..] {
                 if matches!(
-                    cx.tcx.def_kind(*item_def_id),
+                    cx.tcx.def_kind(item_def_id),
                     DefKind::Mod | DefKind::Enum | DefKind::Trait
                 ) {
-                    for child in cx.tcx.module_children(*item_def_id) {
+                    for child in cx.tcx.module_children(item_def_id) {
                         if child.ident.name == *item {
                             return true;
                         }
                     }
                 } else {
-                    for child in cx.tcx.associated_item_def_ids(*item_def_id) {
+                    for child in cx.tcx.associated_item_def_ids(item_def_id) {
                         if cx.tcx.item_name(*child) == *item {
                             return true;
                         }
index 2a028c8141fcec5e8333bf356b1f55f453e4467b..cfba7fa8791de3c7567f09c8a41f643f7cd38427 100644 (file)
@@ -6,7 +6,7 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Namespace, Res};
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
 use rustc_lint::{LateContext, LateLintPass};
@@ -91,7 +91,7 @@ impl UnnecessaryDefPath {
     #[allow(clippy::too_many_lines)]
     fn check_call(&mut self, cx: &LateContext<'_>, func: &Expr<'_>, args: &[Expr<'_>], span: Span) {
         enum Item {
-            LangItem(Symbol),
+            LangItem(&'static str),
             DiagnosticItem(Symbol),
         }
         static PATHS: &[&[&str]] = &[
@@ -325,18 +325,9 @@ fn inherent_def_path_res(cx: &LateContext<'_>, segments: &[&str]) -> Option<DefI
     })
 }
 
-fn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<Symbol> {
-    if let Some(lang_item) = cx.tcx.lang_items().items().iter().position(|id| *id == Some(def_id)) {
-        let lang_items = def_path_res(cx, &["rustc_hir", "lang_items", "LangItem"], Some(Namespace::TypeNS)).def_id();
-        let item_name = cx
-            .tcx
-            .adt_def(lang_items)
-            .variants()
-            .iter()
-            .nth(lang_item)
-            .unwrap()
-            .name;
-        Some(item_name)
+fn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static str> {
+    if let Some((lang_item, _)) = cx.tcx.lang_items().iter().find(|(_, id)| *id == def_id) {
+        Some(lang_item.variant_name())
     } else {
         None
     }
index 73d1ba727c82108a95d7db8e375b653b774c3b17..23aed4b5ba2f40f2c675009c338736431a5fdd1e 100644 (file)
@@ -75,11 +75,11 @@ pub fn eq_field_pat(l: &PatField, r: &PatField) -> bool {
         && over(&l.attrs, &r.attrs, eq_attr)
 }
 
-pub fn eq_qself(l: &QSelf, r: &QSelf) -> bool {
+pub fn eq_qself(l: &P<QSelf>, r: &P<QSelf>) -> bool {
     l.position == r.position && eq_ty(&l.ty, &r.ty)
 }
 
-pub fn eq_maybe_qself(l: &Option<QSelf>, r: &Option<QSelf>) -> bool {
+pub fn eq_maybe_qself(l: &Option<P<QSelf>>, r: &Option<P<QSelf>>) -> bool {
     match (l, r) {
         (Some(l), Some(r)) => eq_qself(l, r),
         (None, None) => true,
@@ -147,8 +147,11 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
         (Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)),
         (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value),
         (Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)),
-        (MethodCall(lc, ls, la, _), MethodCall(rc, rs, ra, _)) => {
-            eq_path_seg(lc, rc) && eq_expr(ls, rs) && over(la, ra, |l, r| eq_expr(l, r))
+        (
+            MethodCall(box ast::MethodCall { seg: ls, receiver: lr, args: la, .. }),
+            MethodCall(box ast::MethodCall { seg: rs, receiver: rr, args: ra, .. })
+        ) => {
+            eq_path_seg(ls, rs) && eq_expr(lr, rr) && over(la, ra, |l, r| eq_expr(l, r))
         },
         (Binary(lo, ll, lr), Binary(ro, rl, rr)) => lo.node == ro.node && eq_expr(ll, rl) && eq_expr(lr, rr),
         (Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r),
@@ -170,7 +173,26 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
         (AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
         (Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
         (Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),
-        (Closure(lb, lc, la, lm, lf, le, _), Closure(rb, rc, ra, rm, rf, re, _)) => {
+        (
+            Closure(box ast::Closure {
+                binder: lb,
+                capture_clause: lc,
+                asyncness: la,
+                movability: lm,
+                fn_decl: lf,
+                body: le,
+                ..
+            }),
+            Closure(box ast::Closure {
+                binder: rb,
+                capture_clause: rc,
+                asyncness: ra,
+                movability: rm,
+                fn_decl: rf,
+                body: re,
+                ..
+            })
+        ) => {
             eq_closure_binder(lb, rb)
                 && lc == rc
                 && la.is_async() == ra.is_async()
index d32cf1a793672ee64ddff93d816e59b95d857012..3f93b9b491d4cb71e28ffedd0b470baea01a7b88 100644 (file)
 use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
 use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
 use rustc_hir::{
-    def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination, Expr,
-    ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource,
-    Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
-    TraitRef, TyKind, UnOp,
+    def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness,
+    Destination, Expr, ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind,
+    LangItem, Local, MatchSource, Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy,
+    QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp,
 };
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
@@ -434,6 +434,16 @@ pub fn is_expr_path_def_path(cx: &LateContext<'_>, expr: &Expr<'_>, segments: &[
     path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, segments))
 }
 
+/// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
+/// it matches the given lang item.
+pub fn is_path_lang_item<'tcx>(
+    cx: &LateContext<'_>,
+    maybe_path: &impl MaybePath<'tcx>,
+    lang_item: LangItem,
+) -> bool {
+    path_def_id(cx, maybe_path).map_or(false, |id| cx.tcx.lang_items().get(lang_item) == Some(id))
+}
+
 /// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
 /// it matches the given diagnostic item.
 pub fn is_path_diagnostic_item<'tcx>(
@@ -760,7 +770,6 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -
 /// constructor from the std library
 fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool {
     let std_types_symbols = &[
-        sym::String,
         sym::Vec,
         sym::VecDeque,
         sym::LinkedList,
@@ -777,7 +786,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
                 if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() {
                     return std_types_symbols
                         .iter()
-                        .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did()));
+                        .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string());
                 }
             }
         }
@@ -834,7 +843,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &
             ExprKind::Lit(hir::Lit {
                 node: LitKind::Str(ref sym, _),
                 ..
-            }) => return sym.is_empty() && is_path_diagnostic_item(cx, ty, sym::String),
+            }) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String),
             ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
             ExprKind::Repeat(_, ArrayLen::Body(len)) => {
                 if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind &&
@@ -1861,7 +1870,7 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
 
 /// Checks if the given function kind is an async function.
 pub fn is_async_fn(kind: FnKind<'_>) -> bool {
-    matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness == IsAsync::Async)
+    matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness.is_async())
 }
 
 /// Peels away all the compiler generated code surrounding the body of an async function,
index cbbb4652306415b7256435bcdc5f83256c47c6b4..e474f370a5d172cbc4c2b4e469f1bb2daa91483b 100644 (file)
@@ -48,14 +48,14 @@ fn _f<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, did: DefId, expr: &Expr<'_>) {
     let _ = is_type_lang_item(cx, ty, LangItem::OwnedBox);
     let _ = is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit);
 
-    let _ = cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did);
+    let _ = cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did);
     let _ = cx.tcx.is_diagnostic_item(sym::Option, did);
-    let _ = cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did);
+    let _ = cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did);
 
     let _ = is_trait_method(cx, expr, sym::AsRef);
 
     let _ = is_path_diagnostic_item(cx, expr, sym::Option);
-    let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().require(LangItem::IteratorNext).ok() == Some(id));
+    let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id));
     let _ = is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome);
 }
 
index a99a8f71fa6a73aac3b1713ec2f7cb2ea1dcb9cb..3ca29f099771b9607ab423d6087c0bb2c95cabaf 100644 (file)
@@ -57,7 +57,7 @@ error: use of a def path to a `LangItem`
   --> $DIR/unnecessary_def_path.rs:51:13
    |
 LL |     let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did)`
 
 error: use of a def path to a diagnostic item
   --> $DIR/unnecessary_def_path.rs:52:13
@@ -69,7 +69,7 @@ error: use of a def path to a `LangItem`
   --> $DIR/unnecessary_def_path.rs:53:13
    |
 LL |     let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did)`
    |
    = help: if this `DefId` came from a constructor expression or pattern then the parent `DefId` should be used instead
 
@@ -89,7 +89,7 @@ error: use of a def path to a `LangItem`
   --> $DIR/unnecessary_def_path.rs:58:13
    |
 LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().require(LangItem::IteratorNext).ok() == Some(id))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id))`
 
 error: use of a def path to a `LangItem`
   --> $DIR/unnecessary_def_path.rs:59:13
index af46d87bf676e42816316dcf94aef37abb063059..2a240cc249b0c768f084dab5b6f220ae53a59399 100644 (file)
@@ -1,10 +1,10 @@
-error: hardcoded path to a language item
-  --> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
+error: hardcoded path to a diagnostic item
+  --> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
    |
-LL |     const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: convert all references to use `LangItem::DerefMut`
+   = help: convert all references to use `sym::Deref`
    = note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
 
 error: hardcoded path to a diagnostic item
@@ -15,13 +15,13 @@ LL |     const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref",
    |
    = help: convert all references to use `sym::deref_method`
 
-error: hardcoded path to a diagnostic item
-  --> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
+error: hardcoded path to a language item
+  --> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
    |
-LL |     const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: convert all references to use `sym::Deref`
+   = help: convert all references to use `LangItem::DerefMut`
 
 error: aborting due to 3 previous errors
 
index 9a432f11f82ffe4b228b4cdcaf2b434fbc434f44..07b80b8baac1639ee9270142114cbb3f271246b3 100644 (file)
@@ -230,6 +230,9 @@ pub struct Config {
     /// The directory where programs should be built
     pub build_base: PathBuf,
 
+    /// The directory containing the compiler sysroot
+    pub sysroot_base: PathBuf,
+
     /// The name of the stage being built (stage1, etc)
     pub stage_id: String,
 
index bcd222b5a93220f8dd010b11cd829fbdb179be83..e42b8c5240842a1387a490dfdbb02569a22e18e7 100644 (file)
@@ -46,6 +46,7 @@ fn config() -> Config {
         "--jsondocck-path=",
         "--src-base=",
         "--build-base=",
+        "--sysroot-base=",
         "--stage-id=stage2",
         "--cc=c",
         "--cxx=c++",
index 19cf54780c1f90c7219a83188d287f94eaf155a1..519da685f940a24a6b18a2ab5780ad20db66146f 100644 (file)
@@ -69,6 +69,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         .optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR")
         .reqopt("", "src-base", "directory to scan for test files", "PATH")
         .reqopt("", "build-base", "directory to deposit test outputs", "PATH")
+        .reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH")
         .reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET")
         .reqopt(
             "",
@@ -234,6 +235,7 @@ fn make_absolute(path: PathBuf) -> PathBuf {
         llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(PathBuf::from),
         src_base,
         build_base: opt_path(matches, "build-base"),
+        sysroot_base: opt_path(matches, "sysroot-base"),
         stage_id: matches.opt_str("stage-id").unwrap(),
         mode,
         suite: matches.opt_str("suite").unwrap(),
index ebce0283fbaf1c1bd55016060ea231d9c0031d05..e07b71a7c47802b07e5be842899be0f3706cb896 100644 (file)
@@ -711,7 +711,7 @@ fn run_debuginfo_cdb_test_no_opt(&self) {
             script_str.push_str("\n");
         }
 
-        script_str.push_str("\nqq\n"); // Quit the debugger (including remote debugger, if any)
+        script_str.push_str("qq\n"); // Quit the debugger (including remote debugger, if any)
 
         // Write the script into a file
         debug!("script_str = {}", script_str);
@@ -3533,22 +3533,25 @@ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> S
         let parent_dir = self.testpaths.file.parent().unwrap();
         normalize_path(parent_dir, "$DIR");
 
-        // Paths into the libstd/libcore
-        let base_dir = self.config.src_base.parent().unwrap().parent().unwrap().parent().unwrap();
-        let src_dir = base_dir.join("library");
-        normalize_path(&src_dir, "$SRC_DIR");
-
-        // `ui-fulldeps` tests can show paths to the compiler source when testing macros from
-        // `rustc_macros`
-        // eg. /home/user/rust/compiler
-        let compiler_src_dir = base_dir.join("compiler");
-        normalize_path(&compiler_src_dir, "$COMPILER_DIR");
-
-        if let Some(virtual_rust_source_base_dir) =
-            option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from)
-        {
-            normalize_path(&virtual_rust_source_base_dir.join("library"), "$SRC_DIR");
-            normalize_path(&virtual_rust_source_base_dir.join("compiler"), "$COMPILER_DIR");
+        let source_bases = &[
+            // Source base on the current filesystem (calculated as parent of `src/test/$suite`):
+            Some(self.config.src_base.parent().unwrap().parent().unwrap().parent().unwrap().into()),
+            // Source base on the sysroot (from the src components downloaded by `download-rustc`):
+            Some(self.config.sysroot_base.join("lib").join("rustlib").join("src").join("rust")),
+            // Virtual `/rustc/$sha` remapped paths (if `remap-debuginfo` is enabled):
+            option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from),
+            // Virtual `/rustc/$sha` coming from download-rustc:
+            std::env::var_os("FAKE_DOWNLOAD_RUSTC_PREFIX").map(PathBuf::from),
+        ];
+        for base_dir in source_bases {
+            if let Some(base_dir) = base_dir {
+                // Paths into the libstd/libcore
+                normalize_path(&base_dir.join("library"), "$SRC_DIR");
+                // `ui-fulldeps` tests can show paths to the compiler source when testing macros from
+                // `rustc_macros`
+                // eg. /home/user/rust/compiler
+                normalize_path(&base_dir.join("compiler"), "$COMPILER_DIR");
+            }
         }
 
         // Paths into the build directory
index 3c890df08cc26d7d8c97fa52ade29d1078d24c6c..15fc89b86818ac6cbb72e3d954c2c899e3c09fe1 100644 (file)
@@ -383,7 +383,6 @@ dependencies = [
  "regex",
  "rustc-workspace-hack",
  "rustc_version",
- "shell-escape",
  "smallvec",
  "ui_test",
 ]
@@ -632,12 +631,6 @@ dependencies = [
  "lazy_static",
 ]
 
-[[package]]
-name = "shell-escape"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
-
 [[package]]
 name = "smallvec"
 version = "1.9.0"
index 65ef92e21d6b101e38fb9434c3502e1d106ee680..0f69a0baef4fb29fae46fbe6348129515b294a66 100644 (file)
@@ -21,7 +21,6 @@ doctest = false # and no doc tests
 getrandom = { version = "0.2", features = ["std"] }
 env_logger = "0.9"
 log = "0.4"
-shell-escape = "0.1.4"
 rand = "0.8"
 smallvec = "1.7"
 
index e9738cbc515ff7028652b2ec0c415249e793335d..dac0a9820b90e35350de14929acdc6449feb4da2 100644 (file)
@@ -1,10 +1,5 @@
 # Miri
 
-[![Actions build status][actions-badge]][actions-url]
-
-[actions-badge]: https://github.com/rust-lang/miri/workflows/CI/badge.svg?branch=master
-[actions-url]: https://github.com/rust-lang/miri/actions
-
 An experimental interpreter for [Rust][rust]'s
 [mid-level intermediate representation][mir] (MIR). It can run binaries and
 test suites of cargo projects and detect certain classes of
@@ -200,7 +195,7 @@ randomness that is used to determine allocation base addresses. The following
 snippet calls Miri in a loop with different values for the seed:
 
 ```
-for SEED in $({ echo obase=16; seq 0 255; } | bc); do
+for SEED in $(seq 0 255); do
   echo "Trying seed: $SEED"
   MIRIFLAGS=-Zmiri-seed=$SEED cargo miri test || { echo "Failing seed: $SEED"; break; };
 done
@@ -308,7 +303,7 @@ environment variable. We first document the most relevant and most commonly used
   tell what it is doing when a program just keeps running. You can customize how frequently the
   report is printed via `-Zmiri-report-progress=<blocks>`, which prints the report every N basic
   blocks.
-* `-Zmiri-seed=<hex>` configures the seed of the RNG that Miri uses to resolve non-determinism. This
+* `-Zmiri-seed=<num>` configures the seed of the RNG that Miri uses to resolve non-determinism. This
   RNG is used to pick base addresses for allocations, to determine preemption and failure of
   `compare_exchange_weak`, and to control store buffering for weak memory emulation. When isolation
   is enabled (the default), this is also used to emulate system entropy. The default seed is 0. You
index b09897c294cd17f3bf539b6a74420510f44e3d18..38d36898768e18c12f185a9e6966dcd86b55dd7f 100755 (executable)
@@ -48,10 +48,10 @@ Update and activate the rustup toolchain 'miri' to the commit given in the
 `rustup-toolchain-install-master` must be installed for this to work. Any extra
 flags are passed to `rustup-toolchain-install-master`.
 
-./miri rustc-pull:
-Pull and merge Miri changes from the rustc repo. The fetched commit is stored in
-the `rust-version` file, so the next `./miri toolchain` will install the rustc
-we just pulled.
+./miri rustc-pull <commit>:
+Pull and merge Miri changes from the rustc repo. Defaults to fetching the latest
+rustc commit. The fetched commit is stored in the `rust-version` file, so the
+next `./miri toolchain` will install the rustc that just got pulled.
 
 ./miri rustc-push <github user> <branch>:
 Push Miri changes back to the rustc repo. This will pull a copy of the rustc
@@ -113,18 +113,17 @@ toolchain)
     ;;
 rustc-pull)
     cd "$MIRIDIR"
-    FETCH_COMMIT=$(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1)
-    # We can't pull from a commit with josh
-    # (https://github.com/josh-project/josh/issues/1034), so we just hope that
-    # nothing gets merged into rustc *during* this pull.
-    git fetch http://localhost:8000/rust-lang/rust.git$JOSH_FILTER.git master
-    # Just verify that `master` didn't move.
-    if [[ $FETCH_COMMIT != $(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1) ]]; then
-        echo "Looks like something got merged into Rust *while we were pulling*. Aborting. Please try again."
+    FETCH_COMMIT="$1"
+    if [ -z "$FETCH_COMMIT" ]; then
+        FETCH_COMMIT=$(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1)
     fi
-    echo "$FETCH_COMMIT" > rust-version # do this *before* merging as merging will fail in case of conflicts
+    # Update rust-version file. As a separate commit, since making it part of
+    # the merge has confused the heck out of josh in the past.
+    echo "$FETCH_COMMIT" > rust-version
+    git commit rust-version -m "Preparing for merge from rustc"
+    # Fetch given rustc commit and note down which one that was
+    git fetch http://localhost:8000/rust-lang/rust.git@$FETCH_COMMIT$JOSH_FILTER.git
     git merge FETCH_HEAD --no-ff -m "Merge from rustc"
-    git commit rust-version --amend -m "Merge from rustc"
     exit 0
     ;;
 rustc-push)
@@ -157,16 +156,27 @@ rustc-push)
     fi
     git fetch https://github.com/rust-lang/rust $BASE
     git push https://github.com/$USER/rust $BASE:refs/heads/$BRANCH -f
+    echo
     # Do the actual push.
     cd "$MIRIDIR"
     echo "Pushing Miri changes..."
     git push http://localhost:8000/$USER/rust.git$JOSH_FILTER.git HEAD:$BRANCH
-    exit 0
+    # Do a round-trip check to make sure the push worked as expected.
+    echo
+    git fetch http://localhost:8000/$USER/rust.git@$JOSH_FILTER.git $BRANCH &>/dev/null
+    if [[ $(git rev-parse HEAD) != $(git rev-parse FETCH_HEAD) ]]; then
+        echo "ERROR: Josh created a non-roundtrip push! Do NOT merge this into rustc!"
+        exit 1
+    else
+        echo "Confirmed that the push round-trips back to Miri properly. Please create a rustc PR:"
+        echo "    https://github.com/$USER/rust/pull/new/$BRANCH"
+        exit 0
+    fi
     ;;
 many-seeds)
-    for SEED in $({ echo obase=16; seq 0 255; } | bc); do
+    for SEED in $(seq 0 255); do
         echo "Trying seed: $SEED"
-        MIRIFLAGS="$MIRIFLAGS -Zmiri-seed=$SEED" $@ || { echo "Failing seed: $SEED"; break; }
+        MIRIFLAGS="$MIRIFLAGS -Zlayout-seed=$SEED -Zmiri-seed=$SEED" $@ || { echo "Failing seed: $SEED"; break; }
     done
     exit 0
     ;;
index 746fcb2e183c656781a766a8266d4207113f666e..d007f952a67a175717311a644e95bb7461ed84d0 100644 (file)
@@ -1 +1 @@
-101e1822c3e54e63996c8aaa014d55716f3937eb
+7477c1f4f7d6bef037d523099b240d22aa1b63a0
index e673ea67dbc5bbf32c8ae1bd238f4317e1e21004..ffe89921d98665219644fab5baa94bedb051c23b 100644 (file)
@@ -394,10 +394,9 @@ fn main() {
             if miri_config.seed.is_some() {
                 show_error!("Cannot specify -Zmiri-seed multiple times!");
             }
-            let seed = u64::from_str_radix(param, 16)
-                        .unwrap_or_else(|_| show_error!(
-                            "-Zmiri-seed should only contain valid hex digits [0-9a-fA-F] and must fit into a u64 (max 16 characters)"
-                        ));
+            let seed = param.parse::<u64>().unwrap_or_else(|_| {
+                show_error!("-Zmiri-seed must be an integer that fits into u64")
+            });
             miri_config.seed = Some(seed);
         } else if let Some(_param) = arg.strip_prefix("-Zmiri-env-exclude=") {
             show_error!(
index 6004e2078ad4fb6edf21e811f8c12daf25a8e1b4..5ea82adb9c69c762d48e492010958647c85dae10 100644 (file)
@@ -368,11 +368,6 @@ fn emulate_intrinsic_by_name(
             }
 
             // Other
-            "exact_div" => {
-                let [num, denom] = check_arg_count(args)?;
-                this.exact_div(&this.read_immediate(num)?, &this.read_immediate(denom)?, dest)?;
-            }
-
             "breakpoint" => {
                 let [] = check_arg_count(args)?;
                 // normally this would raise a SIGTRAP, which aborts if no debugger is connected
index dcb99a27668261dc35553f411e5437374bbe9f2a..b6efad6b5ee0803c8cb111a1298e07bf85b9e11c 100644 (file)
@@ -89,6 +89,12 @@ fn align_offset(
         }
 
         let ptr = this.read_pointer(ptr_op)?;
+        // If this carries no provenance, treat it like an integer.
+        if ptr.provenance.is_none() {
+            // Use actual implementation.
+            return Ok(false);
+        }
+
         if let Ok((alloc_id, _offset, _)) = this.ptr_try_get_alloc_id(ptr) {
             // Only do anything if we can identify the allocation this goes to.
             let (_size, cur_align, _kind) = this.get_alloc_info(alloc_id);
index 617f90dfaa59fb602a7940a03c2c1069a9c667b0..bc0b71fbc2096438dce1d725341353ef06d516ad 100644 (file)
@@ -22,21 +22,44 @@ fn clock_gettime(
 
         let this = self.eval_context_mut();
 
-        this.assert_target_os("linux", "clock_gettime");
+        this.assert_target_os_is_unix("clock_gettime");
 
         let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
 
-        // Linux has two main kinds of clocks. REALTIME clocks return the actual time since the
-        // Unix epoch, including effects which may cause time to move backwards such as NTP.
-        // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
-        // is just specified to be "faster and less precise", so we implement both the same way.
-        let absolute_clocks =
-            [this.eval_libc_i32("CLOCK_REALTIME")?, this.eval_libc_i32("CLOCK_REALTIME_COARSE")?];
-        // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are
-        // never allowed to go backwards. We don't need to do any additonal monotonicity
-        // enforcement because std::time::Instant already guarantees that it is monotonic.
-        let relative_clocks =
-            [this.eval_libc_i32("CLOCK_MONOTONIC")?, this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?];
+        let absolute_clocks;
+        let mut relative_clocks;
+
+        match this.tcx.sess.target.os.as_ref() {
+            "linux" => {
+                // Linux has two main kinds of clocks. REALTIME clocks return the actual time since the
+                // Unix epoch, including effects which may cause time to move backwards such as NTP.
+                // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
+                // is just specified to be "faster and less precise", so we implement both the same way.
+                absolute_clocks = vec![
+                    this.eval_libc_i32("CLOCK_REALTIME")?,
+                    this.eval_libc_i32("CLOCK_REALTIME_COARSE")?,
+                ];
+                // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are
+                // never allowed to go backwards. We don't need to do any additonal monotonicity
+                // enforcement because std::time::Instant already guarantees that it is monotonic.
+                relative_clocks = vec![
+                    this.eval_libc_i32("CLOCK_MONOTONIC")?,
+                    this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?,
+                ];
+            }
+            "macos" => {
+                absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")?];
+                relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")?];
+                // Some clocks only seem to exist in the aarch64 version of the target.
+                if this.tcx.sess.target.arch == "aarch64" {
+                    // `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but
+                    // that's not really something a program running inside Miri can tell, anyway.
+                    // We need to support it because std uses it.
+                    relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW")?);
+                }
+            }
+            target => throw_unsup_format!("`clock_gettime` is not supported on target OS {target}"),
+        }
 
         let duration = if absolute_clocks.contains(&clk_id) {
             this.check_no_isolation("`clock_gettime` with `REALTIME` clocks")?;
@@ -44,6 +67,7 @@ fn clock_gettime(
         } else if relative_clocks.contains(&clk_id) {
             this.machine.clock.now().duration_since(this.machine.clock.anchor())
         } else {
+            // Unsupported clock.
             let einval = this.eval_libc("EINVAL")?;
             this.set_last_error(einval)?;
             return Ok(Scalar::from_i32(-1));
index 44a433df1e9c0d45f08c11304d8375a7468fa414..d746f9df90ac300fdec3d0a33a4e0a4f50d525c2 100644 (file)
@@ -180,6 +180,12 @@ fn emulate_foreign_item_by_name(
                 let result = this.gettimeofday(tv, tz)?;
                 this.write_scalar(Scalar::from_i32(result), dest)?;
             }
+            "clock_gettime" => {
+                let [clk_id, tp] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let result = this.clock_gettime(clk_id, tp)?;
+                this.write_scalar(result, dest)?;
+            }
 
             // Allocation
             "posix_memalign" => {
index 2b53152688bb787abd713355236435213048034c..34076e842d55b51226df6ddfcf1ce6f1dc3f450b 100644 (file)
@@ -43,15 +43,6 @@ fn emulate_foreign_item_by_name(
                 this.write_scalar(result, dest)?;
             }
 
-            // Time related shims
-            "clock_gettime" => {
-                // This is a POSIX function but it has only been tested on linux.
-                let [clk_id, tp] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                let result = this.clock_gettime(clk_id, tp)?;
-                this.write_scalar(result, dest)?;
-            }
-
             // Threading
             "pthread_condattr_setclock" => {
                 let [attr, clock_id] =
index 9ce02a02ec408faae64fddf54aaf14036e352f58..f2e2df5ad08004c1711256d94d7d5ebe09c4f6d0 100644 (file)
@@ -14,7 +14,6 @@
 use rustc_middle::ty::{
     self,
     layout::{HasParamEnv, LayoutOf},
-    Ty,
 };
 use rustc_target::abi::Abi;
 use rustc_target::abi::Size;
@@ -983,28 +982,6 @@ fn retag(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>) -> Inter
         let mut visitor = RetagVisitor { ecx: this, kind, retag_cause, retag_fields };
         return visitor.visit_value(place);
 
-        // Determine mutability and whether to add a protector.
-        // Cannot use `builtin_deref` because that reports *immutable* for `Box`,
-        // making it useless.
-        fn qualify(ty: Ty<'_>, kind: RetagKind) -> Option<(RefKind, bool)> {
-            match ty.kind() {
-                // References are simple.
-                ty::Ref(_, _, Mutability::Mut) =>
-                    Some((
-                        RefKind::Unique { two_phase: kind == RetagKind::TwoPhase },
-                        kind == RetagKind::FnEntry,
-                    )),
-                ty::Ref(_, _, Mutability::Not) =>
-                    Some((RefKind::Shared, kind == RetagKind::FnEntry)),
-                // Raw pointers need to be enabled.
-                ty::RawPtr(tym) if kind == RetagKind::Raw =>
-                    Some((RefKind::Raw { mutable: tym.mutbl == Mutability::Mut }, false)),
-                // Boxes are handled separately due to that allocator situation,
-                // see the visitor below.
-                _ => None,
-            }
-        }
-
         // The actual visitor.
         struct RetagVisitor<'ecx, 'mir, 'tcx> {
             ecx: &'ecx mut MiriInterpCx<'mir, 'tcx>,
@@ -1057,34 +1034,58 @@ fn visit_value(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tc
                     return Ok(());
                 }
 
-                let recurse_for_fields = || {
-                    match self.retag_fields {
-                        RetagFields::No => false,
-                        RetagFields::Yes => true,
-                        RetagFields::OnlyScalar => {
-                            // Matching `ArgAbi::new` at the time of writing, only fields of
-                            // `Scalar` and `ScalarPair` ABI are considered.
-                            matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..))
+                // Check the type of this value to see what to do with it (retag, or recurse).
+                match place.layout.ty.kind() {
+                    ty::Ref(_, _, mutbl) => {
+                        let ref_kind = match mutbl {
+                            Mutability::Mut =>
+                                RefKind::Unique { two_phase: self.kind == RetagKind::TwoPhase },
+                            Mutability::Not => RefKind::Shared,
+                        };
+                        self.retag_place(
+                            place,
+                            ref_kind,
+                            self.retag_cause,
+                            /*protector*/ self.kind == RetagKind::FnEntry,
+                        )?;
+                    }
+                    ty::RawPtr(tym) => {
+                        // We definitely do *not* want to recurse into raw pointers -- wide raw
+                        // pointers have fields, and for dyn Trait pointees those can have reference
+                        // type!
+                        if self.kind == RetagKind::Raw {
+                            // Raw pointers need to be enabled.
+                            self.retag_place(
+                                place,
+                                RefKind::Raw { mutable: tym.mutbl == Mutability::Mut },
+                                self.retag_cause,
+                                /*protector*/ false,
+                            )?;
+                        }
+                    }
+                    _ if place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box()) => {
+                        // Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
+                        // (Yes this means we technically also recursively retag the allocator itself
+                        // even if field retagging is not enabled. *shrug*)
+                        self.walk_value(place)?;
+                    }
+                    _ => {
+                        // Not a reference/pointer/box. Only recurse if configured appropriately.
+                        let recurse = match self.retag_fields {
+                            RetagFields::No => false,
+                            RetagFields::Yes => true,
+                            RetagFields::OnlyScalar => {
+                                // Matching `ArgAbi::new` at the time of writing, only fields of
+                                // `Scalar` and `ScalarPair` ABI are considered.
+                                matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..))
+                            }
+                        };
+                        if recurse {
+                            self.walk_value(place)?;
                         }
                     }
-                };
-
-                if let Some((ref_kind, protector)) = qualify(place.layout.ty, self.kind) {
-                    self.retag_place(place, ref_kind, self.retag_cause, protector)?;
-                } else if matches!(place.layout.ty.kind(), ty::RawPtr(..)) {
-                    // Wide raw pointers *do* have fields and their types are strange.
-                    // vtables have a type like `&[*const (); 3]` or so!
-                    // Do *not* recurse into them.
-                    // (No need to worry about wide references, those always "qualify". And Boxes
-                    // are handles specially by the visitor anyway.)
-                } else if recurse_for_fields()
-                    || place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box())
-                {
-                    // Recurse deeper. Need to always recurse for `Box` to even hit `visit_box`.
-                    // (Yes this means we technically also recursively retag the allocator itself
-                    // even if field retagging is not enabled. *shrug*)
-                    self.walk_value(place)?;
                 }
+
                 Ok(())
             }
         }
index c611b9c44be9df792b13dede1a94fe61d262d680..46b3afa70e5b0fd0e3fd89f5f7d47cd358a9fdbf 100755 (executable)
@@ -133,7 +133,7 @@ def test_cargo_miri_test():
     test("`cargo miri test`",
         cargo_miri("test"),
         default_ref, "test.stderr-empty.ref",
-        env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-seed=feed"},
+        env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-seed=4242"},
     )
     test("`cargo miri test` (no isolation, no doctests)",
         cargo_miri("test") + ["--bins", "--tests"], # no `--lib`, we disabled that in `Cargo.toml`
index 904ae2fb17f9b3080449234ea6c41cc25a6c8aaa..2a4300fcd049ec2d2669d77800b8631cc9e7d90c 100644 (file)
@@ -181,17 +181,25 @@ fn test_thread_local_errno() {
 }
 
 /// Tests whether clock support exists at all
-#[cfg(target_os = "linux")]
 fn test_clocks() {
     let mut tp = std::mem::MaybeUninit::<libc::timespec>::uninit();
     let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) };
     assert_eq!(is_error, 0);
-    let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) };
-    assert_eq!(is_error, 0);
     let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, tp.as_mut_ptr()) };
     assert_eq!(is_error, 0);
-    let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) };
-    assert_eq!(is_error, 0);
+    #[cfg(target_os = "linux")]
+    {
+        let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) };
+        assert_eq!(is_error, 0);
+        let is_error =
+            unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) };
+        assert_eq!(is_error, 0);
+    }
+    #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
+    {
+        let is_error = unsafe { libc::clock_gettime(libc::CLOCK_UPTIME_RAW, tp.as_mut_ptr()) };
+        assert_eq!(is_error, 0);
+    }
 }
 
 fn test_posix_gettimeofday() {
@@ -293,11 +301,11 @@ fn main() {
     test_thread_local_errno();
 
     test_isatty();
+    test_clocks();
 
     #[cfg(target_os = "linux")]
     {
         test_posix_fadvise();
         test_sync_file_range();
-        test_clocks();
     }
 }
index b3e5733836390731d1b2dba5e5a312fca190dd0f..4e1584b838714c415c70e8d2133d287fcedb6f0b 100644 (file)
@@ -1,4 +1,7 @@
 //@compile-flags: -Zmiri-symbolic-alignment-check
+#![feature(strict_provenance)]
+
+use std::ptr;
 
 fn test_align_offset() {
     let d = Box::new([0u32; 4]);
@@ -16,6 +19,9 @@ fn test_align_offset() {
     assert_eq!(raw.wrapping_offset(2).align_offset(2), 0);
     assert_eq!(raw.wrapping_offset(2).align_offset(4), 2);
     assert_eq!(raw.wrapping_offset(2).align_offset(8), usize::MAX); // requested alignment higher than allocation alignment
+
+    let p = ptr::invalid::<()>(1);
+    assert_eq!(p.align_offset(1), 0);
 }
 
 fn test_align_to() {
diff --git a/src/tools/miri/tests/pass/issues/issue-miri-2433.rs b/src/tools/miri/tests/pass/issues/issue-miri-2433.rs
deleted file mode 100644 (file)
index a8281d3..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#![feature(type_alias_impl_trait)]
-
-trait T {
-    type Item;
-}
-
-type Alias<'a> = impl T<Item = &'a ()>;
-
-struct S;
-impl<'a> T for &'a S {
-    type Item = &'a ();
-}
-
-fn filter_positive<'a>() -> Alias<'a> {
-    &S
-}
-
-fn with_positive(fun: impl Fn(Alias<'_>)) {
-    fun(filter_positive());
-}
-
-fn main() {
-    with_positive(|_| ());
-}
index 308904406538c1a510ab4cf52155897b8bae2485..5d57df4e52bfabec0eff2ebbaeb223bd435182c4 100644 (file)
@@ -69,7 +69,7 @@ fn main() {
     });
 
     test(Some("align_offset: align is not a power-of-two"), |_old_val| {
-        (0usize as *const u8).align_offset(3);
+        let _ = (0usize as *const u8).align_offset(3);
         loop {}
     });
 
index 96819d3547b29987b0ce6aae8e5330e8887fedd0..cfba7d583b138633d8ad151badc188f60a1784b0 100644 (file)
@@ -11,7 +11,7 @@ pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec<
     let test_file_contents = fs::read_to_string(&testfile).unwrap();
 
     let test_dir = testfile.parent().unwrap();
-    let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace("-", "_");
+    let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_");
 
     let bit_width = if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") {
         format!(".{}bit", bit_width)
index ccc2fd0d5f5899881167285d76554aabdffb2f65..23f55db773e6c01e52ab624b95a681b019f7ddbb 100644 (file)
@@ -290,10 +290,10 @@ impl Rewrite for ast::MetaItem {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         Some(match self.kind {
             ast::MetaItemKind::Word => {
-                rewrite_path(context, PathContext::Type, None, &self.path, shape)?
+                rewrite_path(context, PathContext::Type, &None, &self.path, shape)?
             }
             ast::MetaItemKind::List(ref list) => {
-                let path = rewrite_path(context, PathContext::Type, None, &self.path, shape)?;
+                let path = rewrite_path(context, PathContext::Type, &None, &self.path, shape)?;
                 let has_trailing_comma = crate::expr::span_ends_with_comma(context, self.span);
                 overflow::rewrite_with_parens(
                     context,
@@ -311,7 +311,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
                 )?
             }
             ast::MetaItemKind::NameValue(ref literal) => {
-                let path = rewrite_path(context, PathContext::Type, None, &self.path, shape)?;
+                let path = rewrite_path(context, PathContext::Type, &None, &self.path, shape)?;
                 // 3 = ` = `
                 let lit_shape = shape.shrink_left(path.len() + 3)?;
                 // `rewrite_literal` returns `None` when `literal` exceeds max
index fcc02eca42987c47c2d3f4393ce31253a81a3677..a1a73cf4bd570f2ee495766e207e2e7935487773 100644 (file)
@@ -145,8 +145,8 @@ fn is_tup_field_access(expr: &ast::Expr) -> bool {
 
     fn from_ast(context: &RewriteContext<'_>, expr: &ast::Expr) -> (ChainItemKind, Span) {
         let (kind, span) = match expr.kind {
-            ast::ExprKind::MethodCall(ref segment, ref receiver, ref expressions, _) => {
-                let types = if let Some(ref generic_args) = segment.args {
+            ast::ExprKind::MethodCall(ref call) => {
+                let types = if let Some(ref generic_args) = call.seg.args {
                     if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
                         data.args
                             .iter()
@@ -163,8 +163,8 @@ fn from_ast(context: &RewriteContext<'_>, expr: &ast::Expr) -> (ChainItemKind, S
                 } else {
                     vec![]
                 };
-                let span = mk_sp(receiver.span.hi(), expr.span.hi());
-                let kind = ChainItemKind::MethodCall(segment.clone(), types, expressions.clone());
+                let span = mk_sp(call.receiver.span.hi(), expr.span.hi());
+                let kind = ChainItemKind::MethodCall(call.seg.clone(), types, call.args.clone());
                 (kind, span)
             }
             ast::ExprKind::Field(ref nested, field) => {
@@ -400,9 +400,7 @@ fn make_subexpr_list(expr: &ast::Expr, context: &RewriteContext<'_>) -> Vec<ast:
     // is a try! macro, we'll convert it to shorthand when the option is set.
     fn pop_expr_chain(expr: &ast::Expr, context: &RewriteContext<'_>) -> Option<ast::Expr> {
         match expr.kind {
-            ast::ExprKind::MethodCall(_, ref receiver, _, _) => {
-                Some(Self::convert_try(&receiver, context))
-            }
+            ast::ExprKind::MethodCall(ref call) => Some(Self::convert_try(&call.receiver, context)),
             ast::ExprKind::Field(ref subexpr, _)
             | ast::ExprKind::Try(ref subexpr)
             | ast::ExprKind::Await(ref subexpr) => Some(Self::convert_try(subexpr, context)),
index 88a6bebb68c84157ecd08400e7b116483bae8518..423c3a997f53da7e8879bbb797b92a2774026569 100644 (file)
@@ -326,16 +326,16 @@ pub(crate) fn rewrite_last_closure(
     expr: &ast::Expr,
     shape: Shape,
 ) -> Option<String> {
-    if let ast::ExprKind::Closure(
-        ref binder,
-        capture,
-        ref is_async,
-        movability,
-        ref fn_decl,
-        ref body,
-        _,
-    ) = expr.kind
-    {
+    if let ast::ExprKind::Closure(ref closure) = expr.kind {
+        let ast::Closure {
+            ref binder,
+            capture_clause,
+            ref asyncness,
+            movability,
+            ref fn_decl,
+            ref body,
+            fn_decl_span: _,
+        } = **closure;
         let body = match body.kind {
             ast::ExprKind::Block(ref block, _)
                 if !is_unsafe_block(block)
@@ -347,7 +347,15 @@ pub(crate) fn rewrite_last_closure(
             _ => body,
         };
         let (prefix, extra_offset) = rewrite_closure_fn_decl(
-            binder, capture, is_async, movability, fn_decl, body, expr.span, context, shape,
+            binder,
+            capture_clause,
+            asyncness,
+            movability,
+            fn_decl,
+            body,
+            expr.span,
+            context,
+            shape,
         )?;
         // If the closure goes multi line before its body, do not overflow the closure.
         if prefix.contains('\n') {
index b4f1a178dbf44d4a03d0ba82cf00007733ccad6f..aba1c484bf1ddc028e8507fd59517c9a9691e6a1 100644 (file)
@@ -116,7 +116,7 @@ pub(crate) fn format_expr(
             rewrite_struct_lit(
                 context,
                 path,
-                qself.as_ref(),
+                qself,
                 fields,
                 rest,
                 &expr.attrs,
@@ -169,7 +169,7 @@ pub(crate) fn format_expr(
             rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs)
         }
         ast::ExprKind::Path(ref qself, ref path) => {
-            rewrite_path(context, PathContext::Expr, qself.as_ref(), path, shape)
+            rewrite_path(context, PathContext::Expr, qself, path, shape)
         }
         ast::ExprKind::Assign(ref lhs, ref rhs, _) => {
             rewrite_assignment(context, lhs, rhs, None, shape)
@@ -203,16 +203,16 @@ pub(crate) fn format_expr(
                 Some("yield".to_string())
             }
         }
-        ast::ExprKind::Closure(
-            ref binder,
-            capture,
-            ref is_async,
-            movability,
-            ref fn_decl,
-            ref body,
-            _,
-        ) => closures::rewrite_closure(
-            binder, capture, is_async, movability, fn_decl, body, expr.span, context, shape,
+        ast::ExprKind::Closure(ref cl) => closures::rewrite_closure(
+            &cl.binder,
+            cl.capture_clause,
+            &cl.asyncness,
+            cl.movability,
+            &cl.fn_decl,
+            &cl.body,
+            expr.span,
+            context,
+            shape,
         ),
         ast::ExprKind::Try(..)
         | ast::ExprKind::Field(..)
@@ -1537,7 +1537,7 @@ fn struct_lit_can_be_aligned(fields: &[ast::ExprField], has_base: bool) -> bool
 fn rewrite_struct_lit<'a>(
     context: &RewriteContext<'_>,
     path: &ast::Path,
-    qself: Option<&ast::QSelf>,
+    qself: &Option<ptr::P<ast::QSelf>>,
     fields: &'a [ast::ExprField],
     struct_rest: &ast::StructRest,
     attrs: &[ast::Attribute],
index e2fe92b28f23e9fc53a256fe1538b188849bccf6..3f335172590ec808e44a3a667905e1764cd01aba 100644 (file)
@@ -227,11 +227,10 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
             }
             PatKind::Tuple(ref items) => rewrite_tuple_pat(items, None, self.span, context, shape),
             PatKind::Path(ref q_self, ref path) => {
-                rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)
+                rewrite_path(context, PathContext::Expr, q_self, path, shape)
             }
             PatKind::TupleStruct(ref q_self, ref path, ref pat_vec) => {
-                let path_str =
-                    rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)?;
+                let path_str = rewrite_path(context, PathContext::Expr, q_self, path, shape)?;
                 rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape)
             }
             PatKind::Lit(ref expr) => expr.rewrite(context, shape),
@@ -271,7 +270,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
 }
 
 fn rewrite_struct_pat(
-    qself: &Option<ast::QSelf>,
+    qself: &Option<ptr::P<ast::QSelf>>,
     path: &ast::Path,
     fields: &[ast::PatField],
     ellipsis: bool,
@@ -281,7 +280,7 @@ fn rewrite_struct_pat(
 ) -> Option<String> {
     // 2 =  ` {`
     let path_shape = shape.sub_width(2)?;
-    let path_str = rewrite_path(context, PathContext::Expr, qself.as_ref(), path, path_shape)?;
+    let path_str = rewrite_path(context, PathContext::Expr, qself, path, path_shape)?;
 
     if fields.is_empty() && !ellipsis {
         return Some(format!("{} {{}}", path_str));
index 2627886db109d7fc5aa0547f394a6b5f2d9c0a8b..d5177a2057b8ab05fb3daebe466de1d87dc32710 100644 (file)
@@ -38,11 +38,11 @@ pub(crate) enum PathContext {
 pub(crate) fn rewrite_path(
     context: &RewriteContext<'_>,
     path_context: PathContext,
-    qself: Option<&ast::QSelf>,
+    qself: &Option<ptr::P<ast::QSelf>>,
     path: &ast::Path,
     shape: Shape,
 ) -> Option<String> {
-    let skip_count = qself.map_or(0, |x| x.position);
+    let skip_count = qself.as_ref().map_or(0, |x| x.position);
 
     let mut result = if path.is_global() && qself.is_none() && path_context != PathContext::Import {
         "::".to_owned()
@@ -655,7 +655,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
 
 impl Rewrite for ast::TraitRef {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        rewrite_path(context, PathContext::Type, None, &self.path, shape)
+        rewrite_path(context, PathContext::Type, &None, &self.path, shape)
     }
 }
 
@@ -800,7 +800,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
                 rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
             }
             ast::TyKind::Path(ref q_self, ref path) => {
-                rewrite_path(context, PathContext::Type, q_self.as_ref(), path, shape)
+                rewrite_path(context, PathContext::Type, q_self, path, shape)
             }
             ast::TyKind::Array(ref ty, ref repeats) => rewrite_pair(
                 &**ty,
index c47b3b314dd4b31873405c3875aec1b698881032..136a2c7fce24a802aac4c6e252e818b12db00ea1 100644 (file)
@@ -479,9 +479,9 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
         | ast::ExprKind::Binary(_, _, ref expr)
         | ast::ExprKind::Index(_, ref expr)
         | ast::ExprKind::Unary(_, ref expr)
-        | ast::ExprKind::Closure(_, _, _, _, _, ref expr, _)
         | ast::ExprKind::Try(ref expr)
         | ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
+        ast::ExprKind::Closure(ref closure) => is_block_expr(context, &closure.body, repr),
         // This can only be a string lit
         ast::ExprKind::Lit(_) => {
             repr.contains('\n') && trimmed_last_line_width(repr) <= context.config.tab_spaces()
index f1f5a1941579b93044a764faa5e5bd4c7040d2f7..8155ec9dd27e22e0ffb15809efe04a87ca065f06 100644 (file)
     "hashbrown",
     "hermit-abi",
     "humantime",
+    "icu_list",
+    "icu_locid",
+    "icu_provider",
+    "icu_provider_adapters",
+    "icu_provider_macros",
     "if_chain",
     "indexmap",
     "instant",
     "libc",
     "libloading",
     "libz-sys",
+    "litemap",
     "lock_api",
     "log",
     "matchers",
     "winapi-i686-pc-windows-gnu",
     "winapi-util",
     "winapi-x86_64-pc-windows-gnu",
+    "writeable",
     // this is a false-positive: it's only used by rustfmt, but because it's enabled through a
     // feature, tidy thinks it's used by rustc as well.
     "yansi-term",
+    "yoke",
+    "yoke-derive",
+    "zerofrom",
+    "zerofrom-derive",
+    "zerovec",
+    "zerovec-derive",
 ];
 
 const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[