From 923072b8013b17b229df96598af0b6e0f8f869eb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fabian=20Gr=C3=BCnbichler?= Date: Tue, 15 Nov 2022 19:41:33 +0100 Subject: [PATCH] New upstream version 1.63.0+dfsg1 --- Cargo.lock | 521 +- Cargo.toml | 2 - README.md | 2 +- RELEASES.md | 195 +- compiler/rustc/Cargo.toml | 9 +- compiler/rustc/Windows Manifest.xml | 28 + compiler/rustc/build.rs | 24 + compiler/rustc/src/main.rs | 4 +- compiler/rustc_apfloat/src/lib.rs | 1 - compiler/rustc_ast/src/ast.rs | 63 +- compiler/rustc_ast/src/ast/tests.rs | 11 - compiler/rustc_ast/src/ast_traits.rs | 8 +- compiler/rustc_ast/src/attr/mod.rs | 4 +- compiler/rustc_ast/src/entry.rs | 2 +- compiler/rustc_ast/src/lib.rs | 2 - compiler/rustc_ast/src/mut_visit.rs | 5 +- compiler/rustc_ast/src/ptr.rs | 10 +- compiler/rustc_ast/src/token.rs | 2 +- compiler/rustc_ast/src/tokenstream.rs | 262 +- compiler/rustc_ast/src/visit.rs | 26 +- compiler/rustc_ast_lowering/Cargo.toml | 1 + compiler/rustc_ast_lowering/src/asm.rs | 20 +- compiler/rustc_ast_lowering/src/expr.rs | 123 +- compiler/rustc_ast_lowering/src/index.rs | 11 +- compiler/rustc_ast_lowering/src/item.rs | 337 +- compiler/rustc_ast_lowering/src/lib.rs | 938 +-- compiler/rustc_ast_lowering/src/pat.rs | 12 +- compiler/rustc_ast_lowering/src/path.rs | 127 +- .../rustc_ast_passes/src/ast_validation.rs | 39 +- compiler/rustc_ast_passes/src/feature_gate.rs | 58 +- compiler/rustc_ast_passes/src/node_count.rs | 2 +- compiler/rustc_ast_pretty/src/lib.rs | 1 - compiler/rustc_ast_pretty/src/pprust/mod.rs | 32 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 152 +- .../rustc_ast_pretty/src/pprust/state/item.rs | 50 +- compiler/rustc_attr/src/builtin.rs | 194 +- compiler/rustc_attr/src/lib.rs | 1 + compiler/rustc_borrowck/src/borrow_set.rs | 12 +- .../rustc_borrowck/src/borrowck_errors.rs | 50 +- .../src/constraint_generation.rs | 4 +- .../rustc_borrowck/src/constraints/graph.rs | 32 +- .../rustc_borrowck/src/constraints/mod.rs | 16 +- compiler/rustc_borrowck/src/dataflow.rs | 4 +- .../src/diagnostics/bound_region_errors.rs | 10 +- .../src/diagnostics/conflict_errors.rs | 37 +- .../src/diagnostics/explain_borrow.rs | 24 +- .../src/diagnostics/find_use.rs | 6 +- .../rustc_borrowck/src/diagnostics/mod.rs | 24 +- .../src/diagnostics/move_errors.rs | 2 +- .../src/diagnostics/mutability_errors.rs | 6 +- .../src/diagnostics/outlives_suggestion.rs | 11 +- .../src/diagnostics/region_errors.rs | 232 +- .../src/diagnostics/region_name.rs | 121 +- .../src/diagnostics/var_name.rs | 14 +- compiler/rustc_borrowck/src/facts.rs | 2 +- compiler/rustc_borrowck/src/invalidation.rs | 5 +- compiler/rustc_borrowck/src/lib.rs | 18 +- compiler/rustc_borrowck/src/location.rs | 2 +- .../rustc_borrowck/src/member_constraints.rs | 29 +- compiler/rustc_borrowck/src/nll.rs | 8 +- compiler/rustc_borrowck/src/place_ext.rs | 2 +- .../rustc_borrowck/src/places_conflict.rs | 4 +- .../src/region_infer/graphviz.rs | 4 +- .../rustc_borrowck/src/region_infer/mod.rs | 181 +- .../src/region_infer/reverse_sccs.rs | 2 +- .../rustc_borrowck/src/region_infer/values.rs | 82 +- .../src/type_check/canonical.rs | 10 +- .../src/type_check/constraint_conversion.rs | 8 +- .../src/type_check/free_region_relations.rs | 30 +- .../src/type_check/input_output.rs | 12 +- .../src/type_check/liveness/local_use_map.rs | 14 +- .../src/type_check/liveness/polonius.rs | 16 +- compiler/rustc_borrowck/src/type_check/mod.rs | 193 +- .../src/type_check/relate_tys.rs | 6 +- .../rustc_borrowck/src/universal_regions.rs | 6 +- compiler/rustc_borrowck/src/used_muts.rs | 6 +- compiler/rustc_builtin_macros/Cargo.toml | 1 + compiler/rustc_builtin_macros/src/asm.rs | 2 +- compiler/rustc_builtin_macros/src/assert.rs | 74 +- .../src/assert/context.rs | 387 ++ compiler/rustc_builtin_macros/src/cfg.rs | 24 +- .../src/cfg_accessible.rs | 2 +- compiler/rustc_builtin_macros/src/cfg_eval.rs | 15 +- compiler/rustc_builtin_macros/src/derive.rs | 4 +- .../src/deriving/generic/mod.rs | 6 +- .../rustc_builtin_macros/src/deriving/mod.rs | 4 +- compiler/rustc_builtin_macros/src/format.rs | 2 +- compiler/rustc_builtin_macros/src/lib.rs | 6 +- .../src/proc_macro_harness.rs | 69 +- compiler/rustc_builtin_macros/src/test.rs | 2 +- .../rustc_builtin_macros/src/test_harness.rs | 11 +- .../.github/workflows/main.yml | 6 +- .../.github/workflows/nightly-cranelift.yml | 4 +- .../.github/workflows/rustc.yml | 4 +- .../.vscode/settings.json | 2 +- compiler/rustc_codegen_cranelift/Cargo.lock | 8 +- compiler/rustc_codegen_cranelift/Cargo.toml | 12 +- .../build_sysroot/Cargo.lock | 12 +- .../build_system/build_backend.rs | 12 - .../build_system/build_sysroot.rs | 86 +- .../build_system/mod.rs | 1 + .../rustc_codegen_cranelift/docs/usage.md | 6 +- .../example/mini_core.rs | 2 +- .../example/mini_core_hello_world.rs | 7 + ...027-sysroot-128bit-atomic-operations.patch | 10 +- .../rustc_codegen_cranelift/rust-toolchain | 2 +- .../scripts/cargo-clif.rs | 26 +- .../rustc_codegen_cranelift/scripts/config.sh | 6 - .../scripts/ext_config.sh | 32 - .../scripts/filter_profile.rs | 3 +- .../scripts/rustc-clif.rs | 36 + .../scripts/setup_rust_fork.sh | 18 +- .../scripts/test_rustc_tests.sh | 3 +- .../rustc_codegen_cranelift/scripts/tests.sh | 53 +- .../rustc_codegen_cranelift/src/abi/mod.rs | 47 +- .../src/abi/returning.rs | 51 +- .../rustc_codegen_cranelift/src/archive.rs | 43 +- compiler/rustc_codegen_cranelift/src/base.rs | 38 +- .../src/bin/cg_clif.rs | 94 - .../src/bin/cg_clif_build_sysroot.rs | 93 - .../rustc_codegen_cranelift/src/common.rs | 52 +- .../rustc_codegen_cranelift/src/constant.rs | 17 +- .../rustc_codegen_cranelift/src/driver/aot.rs | 33 +- .../rustc_codegen_cranelift/src/driver/jit.rs | 6 +- .../src/intrinsics/llvm.rs | 7 +- .../src/intrinsics/mod.rs | 126 +- .../src/value_and_place.rs | 1 + .../.github/workflows/ci.yml | 24 +- compiler/rustc_codegen_gcc/.rustfmt.toml | 1 + compiler/rustc_codegen_gcc/Cargo.lock | 4 +- compiler/rustc_codegen_gcc/Cargo.toml | 12 +- compiler/rustc_codegen_gcc/build.sh | 25 +- .../build_sysroot/build_sysroot.sh | 2 +- .../build_sysroot/prepare_sysroot_src.sh | 2 +- compiler/rustc_codegen_gcc/cargo.sh | 4 +- compiler/rustc_codegen_gcc/clean_all.sh | 3 +- compiler/rustc_codegen_gcc/config.sh | 4 +- .../0002-rand-Disable-failing-test.patch | 32 + .../rustc_codegen_gcc/example/mini_core.rs | 2 +- .../example/mini_core_hello_world.rs | 7 + .../rustc_codegen_gcc/example/std_example.rs | 58 +- ...0024-core-Disable-portable-simd-test.patch | 199 - compiler/rustc_codegen_gcc/prepare.sh | 10 +- compiler/rustc_codegen_gcc/prepare_build.sh | 3 +- compiler/rustc_codegen_gcc/rust-toolchain | 2 +- .../rustc_patches/compile_test.patch | 14 + compiler/rustc_codegen_gcc/rustup.sh | 2 +- compiler/rustc_codegen_gcc/src/archive.rs | 47 +- compiler/rustc_codegen_gcc/src/asm.rs | 44 +- compiler/rustc_codegen_gcc/src/base.rs | 10 + compiler/rustc_codegen_gcc/src/builder.rs | 276 +- compiler/rustc_codegen_gcc/src/common.rs | 82 +- compiler/rustc_codegen_gcc/src/consts.rs | 25 +- compiler/rustc_codegen_gcc/src/context.rs | 42 +- compiler/rustc_codegen_gcc/src/declare.rs | 8 +- compiler/rustc_codegen_gcc/src/int.rs | 18 +- .../rustc_codegen_gcc/src/intrinsic/archs.rs | 5722 +++++++++++++++++ .../rustc_codegen_gcc/src/intrinsic/llvm.rs | 264 +- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 100 +- .../rustc_codegen_gcc/src/intrinsic/simd.rs | 575 +- compiler/rustc_codegen_gcc/src/lib.rs | 19 +- compiler/rustc_codegen_gcc/src/type_.rs | 40 +- compiler/rustc_codegen_gcc/src/type_of.rs | 24 + compiler/rustc_codegen_gcc/test.sh | 225 +- .../tests/{lib.rs => lang_tests_common.rs} | 20 +- .../tests/lang_tests_debug.rs | 5 + .../tests/lang_tests_release.rs | 5 + compiler/rustc_codegen_gcc/tests/run/int.rs | 451 +- .../tests/run/int_overflow.rs | 17 +- .../tools/generate_intrinsics.py | 238 + compiler/rustc_codegen_llvm/Cargo.toml | 2 +- compiler/rustc_codegen_llvm/src/abi.rs | 1 + compiler/rustc_codegen_llvm/src/asm.rs | 9 +- .../rustc_codegen_llvm/src/back/archive.rs | 120 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 20 +- compiler/rustc_codegen_llvm/src/back/write.rs | 39 +- compiler/rustc_codegen_llvm/src/builder.rs | 11 +- compiler/rustc_codegen_llvm/src/consts.rs | 6 +- compiler/rustc_codegen_llvm/src/context.rs | 27 +- .../rustc_codegen_llvm/src/debuginfo/gdb.rs | 56 +- .../src/debuginfo/metadata.rs | 263 +- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 6 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 16 +- compiler/rustc_codegen_llvm/src/lib.rs | 6 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 21 +- compiler/rustc_codegen_llvm/src/llvm_util.rs | 70 +- compiler/rustc_codegen_llvm/src/type_.rs | 30 +- compiler/rustc_codegen_ssa/Cargo.toml | 5 +- .../rustc_codegen_ssa/src/back/archive.rs | 6 +- .../rustc_codegen_ssa/src/back/command.rs | 7 +- compiler/rustc_codegen_ssa/src/back/link.rs | 196 +- compiler/rustc_codegen_ssa/src/back/linker.rs | 34 +- .../rustc_codegen_ssa/src/back/metadata.rs | 19 +- compiler/rustc_codegen_ssa/src/back/write.rs | 56 +- compiler/rustc_codegen_ssa/src/base.rs | 127 +- compiler/rustc_codegen_ssa/src/common.rs | 9 +- .../src/debuginfo/type_names.rs | 18 +- compiler/rustc_codegen_ssa/src/glue.rs | 7 +- compiler/rustc_codegen_ssa/src/lib.rs | 23 +- compiler/rustc_codegen_ssa/src/meth.rs | 52 +- compiler/rustc_codegen_ssa/src/mir/analyze.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 62 +- .../rustc_codegen_ssa/src/mir/constant.rs | 10 +- .../rustc_codegen_ssa/src/mir/intrinsic.rs | 10 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 14 +- compiler/rustc_codegen_ssa/src/mir/place.rs | 26 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 16 +- .../rustc_codegen_ssa/src/target_features.rs | 3 + .../rustc_codegen_ssa/src/traits/intrinsic.rs | 8 + compiler/rustc_const_eval/Cargo.toml | 1 + .../rustc_const_eval/src/const_eval/error.rs | 2 + .../src/const_eval/eval_queries.rs | 8 +- .../src/const_eval/fn_queries.rs | 21 +- .../src/const_eval/machine.rs | 17 +- .../rustc_const_eval/src/const_eval/mod.rs | 185 +- .../src/const_eval/valtrees.rs | 158 +- .../rustc_const_eval/src/interpret/cast.rs | 80 +- .../src/interpret/eval_context.rs | 41 +- .../src/interpret/intrinsics.rs | 164 +- .../interpret/intrinsics/caller_location.rs | 8 +- .../src/interpret/intrinsics/type_name.rs | 2 +- .../rustc_const_eval/src/interpret/machine.rs | 46 +- .../rustc_const_eval/src/interpret/memory.rs | 69 +- .../rustc_const_eval/src/interpret/mod.rs | 2 +- .../rustc_const_eval/src/interpret/operand.rs | 35 +- .../src/interpret/operator.rs | 4 +- .../rustc_const_eval/src/interpret/place.rs | 43 +- .../rustc_const_eval/src/interpret/step.rs | 21 +- .../src/interpret/terminator.rs | 69 +- .../rustc_const_eval/src/interpret/traits.rs | 29 +- .../rustc_const_eval/src/interpret/util.rs | 10 +- .../src/interpret/validity.rs | 53 +- compiler/rustc_const_eval/src/lib.rs | 24 +- .../src/transform/check_consts/check.rs | 82 +- .../src/transform/check_consts/mod.rs | 49 +- .../src/transform/check_consts/ops.rs | 17 +- .../src/transform/check_consts/qualifs.rs | 3 +- .../src/transform/promote_consts.rs | 63 +- .../src/transform/validate.rs | 137 +- compiler/rustc_data_structures/Cargo.toml | 6 +- .../rustc_data_structures/src/base_n/tests.rs | 4 +- .../rustc_data_structures/src/fingerprint.rs | 19 +- .../src/graph/scc/tests.rs | 3 + .../rustc_data_structures/src/jobserver.rs | 4 +- compiler/rustc_data_structures/src/lib.rs | 46 - .../src/obligation_forest/mod.rs | 155 +- .../src/obligation_forest/tests.rs | 15 +- .../src/owning_ref/tests.rs | 4 + .../rustc_data_structures/src/profiling.rs | 17 +- compiler/rustc_data_structures/src/sip128.rs | 3 +- compiler/rustc_data_structures/src/sso/set.rs | 5 +- .../src/stable_hasher.rs | 4 +- compiler/rustc_data_structures/src/svh.rs | 4 +- compiler/rustc_data_structures/src/sync.rs | 4 +- compiler/rustc_driver/Cargo.toml | 7 +- compiler/rustc_driver/src/lib.rs | 30 +- compiler/rustc_error_codes/src/error_codes.rs | 9 +- .../src/error_codes/E0060.md | 4 +- .../src/error_codes/E0263.md | 4 +- .../src/error_codes/E0312.md | 4 +- .../src/error_codes/E0432.md | 12 +- .../src/error_codes/E0451.md | 12 +- .../src/error_codes/E0455.md | 5 + .../src/error_codes/E0458.md | 1 + .../src/error_codes/E0477.md | 4 +- .../src/error_codes/E0495.md | 4 +- .../src/error_codes/E0574.md | 10 +- .../src/error_codes/E0577.md | 6 +- .../src/error_codes/E0603.md | 10 +- .../src/error_codes/E0623.md | 65 +- .../src/error_codes/E0632.md | 4 +- .../src/error_codes/E0713.md | 2 - .../src/error_codes/E0742.md | 16 +- .../src/error_codes/E0759.md | 4 +- .../src/error_codes/E0772.md | 4 +- .../src/error_codes/E0788.md | 26 + .../locales/en-US/builtin_macros.ftl | 5 + .../locales/en-US/parser.ftl | 27 + .../locales/en-US/typeck.ftl | 6 - compiler/rustc_error_messages/src/lib.rs | 92 +- compiler/rustc_errors/Cargo.toml | 2 + .../src/annotate_snippet_emitter_writer.rs | 2 +- compiler/rustc_errors/src/diagnostic.rs | 112 +- .../rustc_errors/src/diagnostic_builder.rs | 59 +- compiler/rustc_errors/src/emitter.rs | 303 +- compiler/rustc_errors/src/json.rs | 38 +- compiler/rustc_errors/src/json/tests.rs | 26 +- compiler/rustc_errors/src/lib.rs | 143 +- compiler/rustc_expand/src/base.rs | 41 +- compiler/rustc_expand/src/build.rs | 8 +- compiler/rustc_expand/src/config.rs | 8 +- compiler/rustc_expand/src/expand.rs | 11 +- compiler/rustc_expand/src/lib.rs | 6 +- compiler/rustc_expand/src/mbe.rs | 12 +- compiler/rustc_expand/src/mbe/macro_parser.rs | 12 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 64 +- compiler/rustc_expand/src/mbe/metavar_expr.rs | 36 +- compiler/rustc_expand/src/mbe/quoted.rs | 2 +- compiler/rustc_expand/src/module.rs | 6 +- compiler/rustc_expand/src/parse/tests.rs | 4 +- compiler/rustc_expand/src/proc_macro.rs | 14 +- .../rustc_expand/src/proc_macro_server.rs | 161 +- compiler/rustc_expand/src/tests.rs | 10 +- .../rustc_expand/src/tokenstream/tests.rs | 8 +- compiler/rustc_feature/src/accepted.rs | 6 + compiler/rustc_feature/src/active.rs | 20 +- compiler/rustc_feature/src/builtin_attrs.rs | 29 +- compiler/rustc_feature/src/lib.rs | 1 - compiler/rustc_feature/src/removed.rs | 8 + compiler/rustc_graphviz/src/lib.rs | 1 - compiler/rustc_hir/Cargo.toml | 1 - compiler/rustc_hir/src/def.rs | 49 +- compiler/rustc_hir/src/definitions.rs | 56 +- compiler/rustc_hir/src/hir.rs | 198 +- compiler/rustc_hir/src/intravisit.rs | 114 +- compiler/rustc_hir/src/itemlikevisit.rs | 50 - compiler/rustc_hir/src/lang_items.rs | 4 +- compiler/rustc_hir/src/lib.rs | 2 +- compiler/rustc_hir/src/weak_lang_items.rs | 4 +- compiler/rustc_hir_pretty/src/lib.rs | 60 +- .../rustc_incremental/src/assert_dep_graph.rs | 2 +- compiler/rustc_incremental/src/lib.rs | 1 - .../src/persist/dirty_clean.rs | 3 +- .../src/persist/file_format.rs | 49 +- .../rustc_incremental/src/persist/load.rs | 26 +- .../rustc_incremental/src/persist/save.rs | 36 +- .../src/persist/work_product.rs | 52 +- compiler/rustc_index/src/bit_set.rs | 95 +- compiler/rustc_index/src/bit_set/tests.rs | 70 +- compiler/rustc_index/src/interval.rs | 152 +- compiler/rustc_index/src/interval/tests.rs | 2 +- compiler/rustc_index/src/vec.rs | 10 +- compiler/rustc_infer/Cargo.toml | 1 - compiler/rustc_infer/src/infer/at.rs | 21 + .../src/infer/canonical/canonicalizer.rs | 6 +- .../rustc_infer/src/infer/canonical/mod.rs | 2 +- .../src/infer/canonical/query_response.rs | 45 +- .../src/infer/canonical/substitute.rs | 2 +- compiler/rustc_infer/src/infer/combine.rs | 71 +- compiler/rustc_infer/src/infer/equate.rs | 4 +- .../src/infer/error_reporting/mod.rs | 162 +- .../infer/error_reporting/need_type_info.rs | 1685 +++-- .../nice_region_error/different_lifetimes.rs | 50 +- .../mismatched_static_lifetime.rs | 2 +- .../error_reporting/nice_region_error/mod.rs | 2 +- .../nice_region_error/named_anon_conflict.rs | 5 +- .../nice_region_error/static_impl_trait.rs | 16 +- .../trait_impl_difference.rs | 2 +- .../error_reporting/nice_region_error/util.rs | 13 +- .../src/infer/error_reporting/note.rs | 11 +- compiler/rustc_infer/src/infer/freshen.rs | 17 +- compiler/rustc_infer/src/infer/fudge.rs | 4 +- compiler/rustc_infer/src/infer/glb.rs | 20 +- .../src/infer/higher_ranked/mod.rs | 96 +- .../src/infer/lexical_region_resolve/mod.rs | 67 +- compiler/rustc_infer/src/infer/lub.rs | 20 +- compiler/rustc_infer/src/infer/mod.rs | 150 +- .../rustc_infer/src/infer/nll_relate/mod.rs | 14 +- .../rustc_infer/src/infer/opaque_types.rs | 14 +- .../rustc_infer/src/infer/outlives/mod.rs | 3 +- .../src/infer/outlives/obligations.rs | 49 +- .../src/infer/outlives/test_type_match.rs | 207 + .../rustc_infer/src/infer/outlives/verify.rs | 113 +- .../src/infer/region_constraints/mod.rs | 86 +- compiler/rustc_infer/src/infer/resolve.rs | 4 +- compiler/rustc_infer/src/infer/sub.rs | 3 +- compiler/rustc_infer/src/lib.rs | 2 +- compiler/rustc_infer/src/traits/mod.rs | 9 +- .../src/traits/structural_impls.rs | 7 +- compiler/rustc_interface/Cargo.toml | 8 +- compiler/rustc_interface/src/callbacks.rs | 2 +- compiler/rustc_interface/src/lib.rs | 1 - compiler/rustc_interface/src/passes.rs | 62 +- compiler/rustc_interface/src/tests.rs | 5 +- compiler/rustc_interface/src/util.rs | 6 +- compiler/rustc_lint/Cargo.toml | 1 + compiler/rustc_lint/src/array_into_iter.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 85 +- compiler/rustc_lint/src/context.rs | 47 +- compiler/rustc_lint/src/early.rs | 49 +- compiler/rustc_lint/src/expect.rs | 16 +- compiler/rustc_lint/src/internal.rs | 325 +- compiler/rustc_lint/src/late.rs | 26 +- compiler/rustc_lint/src/levels.rs | 38 +- compiler/rustc_lint/src/lib.rs | 31 +- .../rustc_lint/src/redundant_semicolon.rs | 4 +- compiler/rustc_lint/src/types.rs | 11 +- compiler/rustc_lint/src/unused.rs | 2 +- compiler/rustc_lint_defs/Cargo.toml | 1 + compiler/rustc_lint_defs/src/builtin.rs | 8 +- compiler/rustc_lint_defs/src/lib.rs | 37 +- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 18 + compiler/rustc_llvm/src/lib.rs | 1 - compiler/rustc_log/src/lib.rs | 8 +- compiler/rustc_macros/Cargo.toml | 4 + .../src/diagnostics/diagnostic.rs | 191 +- .../rustc_macros/src/diagnostics/fluent.rs | 260 + compiler/rustc_macros/src/diagnostics/mod.rs | 10 +- .../src/diagnostics/subdiagnostic.rs | 3 +- .../rustc_macros/src/diagnostics/utils.rs | 3 +- compiler/rustc_macros/src/lib.rs | 59 + compiler/rustc_macros/src/newtype.rs | 4 +- compiler/rustc_macros/src/serialize.rs | 64 +- compiler/rustc_macros/src/type_foldable.rs | 4 +- compiler/rustc_metadata/Cargo.toml | 1 + compiler/rustc_metadata/src/creader.rs | 26 +- .../rustc_metadata/src/dependency_format.rs | 2 +- .../rustc_metadata/src/foreign_modules.rs | 2 +- compiler/rustc_metadata/src/lib.rs | 7 +- compiler/rustc_metadata/src/locator.rs | 22 +- compiler/rustc_metadata/src/native_libs.rs | 505 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 354 +- .../src/rmeta/decoder/cstore_impl.rs | 90 +- .../src/rmeta/def_path_hash_map.rs | 15 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 595 +- compiler/rustc_metadata/src/rmeta/mod.rs | 299 +- compiler/rustc_metadata/src/rmeta/table.rs | 66 +- compiler/rustc_middle/Cargo.toml | 4 +- compiler/rustc_middle/src/arena.rs | 9 +- .../rustc_middle/src/dep_graph/dep_node.rs | 7 +- compiler/rustc_middle/src/dep_graph/mod.rs | 2 +- compiler/rustc_middle/src/hir/map/mod.rs | 140 +- compiler/rustc_middle/src/hir/mod.rs | 33 +- .../rustc_middle/src/hir/nested_filter.rs | 2 +- compiler/rustc_middle/src/infer/canonical.rs | 2 +- compiler/rustc_middle/src/lib.rs | 5 +- compiler/rustc_middle/src/lint.rs | 16 +- compiler/rustc_middle/src/macros.rs | 8 +- compiler/rustc_middle/src/middle/region.rs | 83 +- .../src/middle/resolve_lifetime.rs | 19 +- compiler/rustc_middle/src/middle/stability.rs | 81 +- .../rustc_middle/src/mir/generic_graph.rs | 2 +- .../src/mir/graph_cyclic_cache.rs | 12 +- .../src/mir/interpret/allocation.rs | 183 +- .../rustc_middle/src/mir/interpret/error.rs | 12 +- .../rustc_middle/src/mir/interpret/mod.rs | 47 +- .../rustc_middle/src/mir/interpret/queries.rs | 125 +- .../rustc_middle/src/mir/interpret/value.rs | 40 +- compiler/rustc_middle/src/mir/mod.rs | 437 +- compiler/rustc_middle/src/mir/mono.rs | 2 +- compiler/rustc_middle/src/mir/patch.rs | 9 +- compiler/rustc_middle/src/mir/predecessors.rs | 12 +- compiler/rustc_middle/src/mir/pretty.rs | 28 +- compiler/rustc_middle/src/mir/query.rs | 22 +- compiler/rustc_middle/src/mir/spanview.rs | 2 +- .../rustc_middle/src/mir/switch_sources.rs | 10 +- compiler/rustc_middle/src/mir/terminator.rs | 81 +- compiler/rustc_middle/src/mir/traversal.rs | 18 +- .../rustc_middle/src/mir/type_foldable.rs | 101 +- compiler/rustc_middle/src/mir/visit.rs | 19 +- compiler/rustc_middle/src/query/mod.rs | 105 +- compiler/rustc_middle/src/thir.rs | 80 +- compiler/rustc_middle/src/thir/visit.rs | 2 +- compiler/rustc_middle/src/traits/chalk.rs | 3 +- compiler/rustc_middle/src/traits/mod.rs | 126 +- compiler/rustc_middle/src/ty/_match.rs | 2 +- compiler/rustc_middle/src/ty/assoc.rs | 6 +- compiler/rustc_middle/src/ty/codec.rs | 276 +- compiler/rustc_middle/src/ty/consts.rs | 65 +- compiler/rustc_middle/src/ty/consts/int.rs | 6 +- compiler/rustc_middle/src/ty/consts/kind.rs | 83 +- .../rustc_middle/src/ty/consts/valtree.rs | 59 + compiler/rustc_middle/src/ty/context.rs | 366 +- compiler/rustc_middle/src/ty/diagnostics.rs | 205 +- compiler/rustc_middle/src/ty/erase_regions.rs | 2 +- compiler/rustc_middle/src/ty/error.rs | 11 +- compiler/rustc_middle/src/ty/fast_reject.rs | 314 +- compiler/rustc_middle/src/ty/flags.rs | 2 +- compiler/rustc_middle/src/ty/fold.rs | 296 +- compiler/rustc_middle/src/ty/generics.rs | 75 + compiler/rustc_middle/src/ty/impls_ty.rs | 42 +- .../rustc_middle/src/ty/inhabitedness/mod.rs | 3 +- compiler/rustc_middle/src/ty/instance.rs | 3 +- compiler/rustc_middle/src/ty/layout.rs | 13 +- compiler/rustc_middle/src/ty/list.rs | 11 +- compiler/rustc_middle/src/ty/mod.rs | 237 +- compiler/rustc_middle/src/ty/parameterized.rs | 119 + compiler/rustc_middle/src/ty/print/mod.rs | 44 +- compiler/rustc_middle/src/ty/print/pretty.rs | 301 +- compiler/rustc_middle/src/ty/query.rs | 11 +- compiler/rustc_middle/src/ty/relate.rs | 82 +- compiler/rustc_middle/src/ty/rvalue_scopes.rs | 57 + .../rustc_middle/src/ty/structural_impls.rs | 266 +- compiler/rustc_middle/src/ty/sty.rs | 374 +- compiler/rustc_middle/src/ty/subst.rs | 65 +- compiler/rustc_middle/src/ty/trait_def.rs | 10 +- compiler/rustc_middle/src/ty/util.rs | 150 +- compiler/rustc_middle/src/ty/vtable.rs | 9 +- compiler/rustc_middle/src/ty/walk.rs | 2 +- compiler/rustc_mir_build/src/build/block.rs | 2 +- compiler/rustc_mir_build/src/build/cfg.rs | 22 +- .../src/build/expr/as_constant.rs | 18 +- .../src/build/expr/as_operand.rs | 8 +- .../src/build/expr/as_place.rs | 115 +- .../src/build/expr/as_rvalue.rs | 77 +- .../rustc_mir_build/src/build/expr/as_temp.rs | 2 +- .../src/build/expr/category.rs | 6 +- .../rustc_mir_build/src/build/expr/into.rs | 37 +- .../rustc_mir_build/src/build/expr/mod.rs | 2 +- .../rustc_mir_build/src/build/expr/stmt.rs | 2 +- .../rustc_mir_build/src/build/matches/mod.rs | 143 +- .../src/build/matches/simplify.rs | 28 +- .../rustc_mir_build/src/build/matches/test.rs | 82 +- .../rustc_mir_build/src/build/matches/util.rs | 11 +- compiler/rustc_mir_build/src/build/misc.rs | 13 +- compiler/rustc_mir_build/src/build/mod.rs | 91 +- compiler/rustc_mir_build/src/build/scope.rs | 43 +- .../rustc_mir_build/src/check_unsafety.rs | 4 +- compiler/rustc_mir_build/src/lib.rs | 2 +- compiler/rustc_mir_build/src/lints.rs | 2 +- compiler/rustc_mir_build/src/thir/constant.rs | 101 +- compiler/rustc_mir_build/src/thir/cx/block.rs | 12 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 59 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 38 +- compiler/rustc_mir_build/src/thir/mod.rs | 6 +- .../src/thir/pattern/check_match.rs | 52 +- .../src/thir/pattern/const_to_pat.rs | 52 +- .../src/thir/pattern/deconstruct_pat.rs | 63 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 230 +- .../src/thir/pattern/usefulness.rs | 30 +- compiler/rustc_mir_build/src/thir/util.rs | 2 +- compiler/rustc_mir_dataflow/Cargo.toml | 1 - .../rustc_mir_dataflow/src/elaborate_drops.rs | 21 +- .../src/framework/cursor.rs | 8 +- .../src/framework/direction.rs | 40 +- .../src/framework/engine.rs | 4 +- .../src/framework/graphviz.rs | 20 +- .../rustc_mir_dataflow/src/framework/tests.rs | 12 +- .../src/impls/borrowed_locals.rs | 28 +- .../rustc_mir_dataflow/src/impls/liveness.rs | 176 +- compiler/rustc_mir_dataflow/src/impls/mod.rs | 2 + .../src/impls/storage_liveness.rs | 19 +- compiler/rustc_mir_dataflow/src/lib.rs | 1 - .../src/move_paths/builder.rs | 5 +- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 8 +- compiler/rustc_mir_dataflow/src/storage.rs | 34 +- compiler/rustc_mir_transform/Cargo.toml | 1 - .../src/abort_unwinding_calls.rs | 7 + .../src/add_call_guards.rs | 7 +- compiler/rustc_mir_transform/src/add_retag.rs | 6 +- .../src/const_debuginfo.rs | 2 +- .../rustc_mir_transform/src/const_prop.rs | 47 +- .../src/const_prop_lint.rs | 59 +- .../src/coverage/counters.rs | 8 +- .../rustc_mir_transform/src/coverage/debug.rs | 34 +- .../rustc_mir_transform/src/coverage/graph.rs | 33 +- .../rustc_mir_transform/src/coverage/mod.rs | 2 +- .../rustc_mir_transform/src/coverage/spans.rs | 2 +- .../rustc_mir_transform/src/coverage/tests.rs | 13 +- .../src/dead_store_elimination.rs | 86 + .../src/deref_separator.rs | 110 +- compiler/rustc_mir_transform/src/dest_prop.rs | 75 +- .../src/elaborate_box_derefs.rs | 184 + .../src/elaborate_drops.rs | 15 +- .../src/function_item_references.rs | 1 + compiler/rustc_mir_transform/src/generator.rs | 130 +- compiler/rustc_mir_transform/src/inline.rs | 137 +- .../rustc_mir_transform/src/inline/cycle.rs | 4 +- .../rustc_mir_transform/src/instcombine.rs | 18 +- compiler/rustc_mir_transform/src/lib.rs | 13 +- .../src/lower_intrinsics.rs | 30 +- .../src/lower_slice_len.rs | 6 +- .../src/normalize_array_len.rs | 5 +- .../src/remove_noop_landing_pads.rs | 6 +- .../src/required_consts.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 10 +- compiler/rustc_mir_transform/src/simplify.rs | 14 +- compiler/rustc_monomorphize/Cargo.toml | 1 - compiler/rustc_monomorphize/src/collector.rs | 138 +- compiler/rustc_monomorphize/src/lib.rs | 1 - .../rustc_monomorphize/src/polymorphize.rs | 6 +- compiler/rustc_monomorphize/src/util.rs | 2 +- compiler/rustc_parse/src/lexer/mod.rs | 2 +- .../src/lexer/unescape_error_reporting.rs | 8 +- .../rustc_parse/src/lexer/unicode_chars.rs | 2 +- compiler/rustc_parse/src/lib.rs | 120 +- compiler/rustc_parse/src/parser/attr.rs | 15 +- .../rustc_parse/src/parser/diagnostics.rs | 339 +- compiler/rustc_parse/src/parser/expr.rs | 369 +- compiler/rustc_parse/src/parser/generics.rs | 4 +- compiler/rustc_parse/src/parser/item.rs | 194 +- compiler/rustc_parse/src/parser/mod.rs | 62 +- compiler/rustc_parse/src/parser/pat.rs | 119 +- compiler/rustc_parse/src/parser/path.rs | 32 +- compiler/rustc_parse/src/parser/stmt.rs | 36 +- compiler/rustc_parse/src/parser/ty.rs | 27 +- compiler/rustc_passes/Cargo.toml | 2 +- compiler/rustc_passes/src/check_attr.rs | 253 +- compiler/rustc_passes/src/check_const.rs | 85 +- compiler/rustc_passes/src/dead.rs | 409 +- .../rustc_passes/src/debugger_visualizer.rs | 138 +- compiler/rustc_passes/src/diagnostic_items.rs | 67 +- compiler/rustc_passes/src/entry.rs | 94 +- compiler/rustc_passes/src/hir_id_validator.rs | 70 +- compiler/rustc_passes/src/hir_stats.rs | 4 +- compiler/rustc_passes/src/layout_test.rs | 146 +- compiler/rustc_passes/src/lib.rs | 6 - compiler/rustc_passes/src/lib_features.rs | 2 +- compiler/rustc_passes/src/liveness.rs | 18 +- compiler/rustc_passes/src/loops.rs | 16 +- compiler/rustc_passes/src/naked_functions.rs | 11 +- compiler/rustc_passes/src/reachable.rs | 164 +- compiler/rustc_passes/src/stability.rs | 89 +- compiler/rustc_passes/src/upvars.rs | 2 +- compiler/rustc_passes/src/weak_lang_items.rs | 2 +- compiler/rustc_plugin_impl/Cargo.toml | 2 - compiler/rustc_plugin_impl/src/lib.rs | 1 - compiler/rustc_privacy/src/lib.rs | 190 +- compiler/rustc_query_impl/Cargo.toml | 2 +- compiler/rustc_query_impl/src/lib.rs | 5 +- .../rustc_query_impl/src/on_disk_cache.rs | 251 +- compiler/rustc_query_impl/src/plumbing.rs | 11 +- .../rustc_query_impl/src/profiling_support.rs | 3 + compiler/rustc_query_system/Cargo.toml | 2 +- .../src/dep_graph/dep_node.rs | 1 - .../rustc_query_system/src/dep_graph/graph.rs | 6 +- .../src/dep_graph/serialized.rs | 29 +- compiler/rustc_query_system/src/ich/hcx.rs | 22 +- .../src/ich/impls_syntax.rs | 16 +- .../rustc_query_system/src/query/plumbing.rs | 16 +- compiler/rustc_resolve/Cargo.toml | 1 - compiler/rustc_resolve/src/access_levels.rs | 1 - .../rustc_resolve/src/build_reduced_graph.rs | 64 +- compiler/rustc_resolve/src/check_unused.rs | 38 +- compiler/rustc_resolve/src/def_collector.rs | 3 +- compiler/rustc_resolve/src/diagnostics.rs | 106 +- compiler/rustc_resolve/src/ident.rs | 53 +- compiler/rustc_resolve/src/imports.rs | 43 +- compiler/rustc_resolve/src/late.rs | 1200 ++-- .../rustc_resolve/src/late/diagnostics.rs | 313 +- compiler/rustc_resolve/src/late/lifetimes.rs | 1150 +--- compiler/rustc_resolve/src/lib.rs | 202 +- compiler/rustc_resolve/src/macros.rs | 49 +- .../rustc_save_analysis/src/dump_visitor.rs | 6 +- compiler/rustc_save_analysis/src/lib.rs | 1 - compiler/rustc_serialize/Cargo.toml | 4 +- .../rustc_serialize/src/collection_impls.rs | 124 +- compiler/rustc_serialize/src/json.rs | 2368 ------- compiler/rustc_serialize/src/json/tests.rs | 147 - compiler/rustc_serialize/src/lib.rs | 3 - compiler/rustc_serialize/src/opaque.rs | 290 +- compiler/rustc_serialize/src/serialize.rs | 326 +- compiler/rustc_serialize/tests/json.rs | 978 --- compiler/rustc_serialize/tests/opaque.rs | 15 +- compiler/rustc_session/src/config.rs | 272 +- compiler/rustc_session/src/lib.rs | 4 +- compiler/rustc_session/src/options.rs | 142 +- compiler/rustc_session/src/parse.rs | 2 + compiler/rustc_session/src/session.rs | 31 +- compiler/rustc_session/src/utils.rs | 58 - compiler/rustc_smir/Cargo.toml | 28 + compiler/rustc_smir/README.md | 75 + compiler/rustc_smir/rust-toolchain.toml | 3 + compiler/rustc_smir/src/lib.rs | 17 + compiler/rustc_smir/src/mir.rs | 10 + compiler/rustc_smir/src/very_unstable.rs | 27 + compiler/rustc_span/src/def_id.rs | 19 +- compiler/rustc_span/src/hygiene.rs | 55 +- compiler/rustc_span/src/lib.rs | 360 +- compiler/rustc_span/src/source_map.rs | 166 +- compiler/rustc_span/src/source_map/tests.rs | 169 +- compiler/rustc_span/src/symbol.rs | 30 +- compiler/rustc_span/src/tests.rs | 2 +- compiler/rustc_symbol_mangling/Cargo.toml | 1 - compiler/rustc_symbol_mangling/src/legacy.rs | 13 +- compiler/rustc_symbol_mangling/src/lib.rs | 8 +- compiler/rustc_symbol_mangling/src/v0.rs | 111 +- compiler/rustc_target/Cargo.toml | 1 + compiler/rustc_target/src/abi/call/mod.rs | 5 + compiler/rustc_target/src/abi/mod.rs | 71 +- compiler/rustc_target/src/asm/aarch64.rs | 2 +- compiler/rustc_target/src/asm/mod.rs | 2 + compiler/rustc_target/src/asm/x86.rs | 13 + compiler/rustc_target/src/json.rs | 91 + compiler/rustc_target/src/lib.rs | 2 +- .../src/spec/aarch64_apple_watchos_sim.rs | 38 + compiler/rustc_target/src/spec/abi.rs | 3 + compiler/rustc_target/src/spec/apple_base.rs | 9 + .../rustc_target/src/spec/apple_sdk_base.rs | 8 +- .../src/spec/arm64_32_apple_watchos.rs | 28 + .../src/spec/armv6k_nintendo_3ds.rs | 3 +- .../src/spec/armv7k_apple_watchos.rs | 28 + .../src/spec/asmjs_unknown_emscripten.rs | 10 +- compiler/rustc_target/src/spec/crt_objects.rs | 2 +- .../rustc_target/src/spec/fuchsia_base.rs | 1 - .../rustc_target/src/spec/mipsel_sony_psp.rs | 3 +- .../src/spec/mipsel_sony_psp_linker_script.ld | 21 +- compiler/rustc_target/src/spec/mod.rs | 279 +- .../src/spec/riscv32imac_unknown_xous_elf.rs | 24 + .../rustc_target/src/spec/tests/tests_impl.rs | 5 + .../src/spec/wasm32_unknown_emscripten.rs | 12 +- .../src/spec/x86_64_apple_watchos_sim.rs | 35 + compiler/rustc_target/src/tests.rs | 8 +- compiler/rustc_trait_selection/src/lib.rs | 5 +- .../rustc_trait_selection/src/opaque_types.rs | 8 +- .../src/traits/auto_trait.rs | 16 +- .../src/traits/chalk_fulfill.rs | 2 +- .../src/traits/coherence.rs | 64 +- .../src/traits/const_evaluatable.rs | 285 +- .../src/traits/error_reporting/mod.rs | 106 +- .../error_reporting/on_unimplemented.rs | 8 +- .../src/traits/error_reporting/suggestions.rs | 702 +- .../src/traits/fulfill.rs | 128 +- .../rustc_trait_selection/src/traits/misc.rs | 4 +- .../rustc_trait_selection/src/traits/mod.rs | 18 +- .../src/traits/object_safety.rs | 13 +- .../src/traits/on_unimplemented.rs | 16 +- .../src/traits/project.rs | 66 +- .../src/traits/query/normalize.rs | 33 +- .../query/type_op/implied_outlives_bounds.rs | 13 +- .../src/traits/select/candidate_assembly.rs | 12 +- .../src/traits/select/confirmation.rs | 59 +- .../src/traits/select/mod.rs | 172 +- .../src/traits/specialize/mod.rs | 2 +- .../traits/specialize/specialization_graph.rs | 9 +- .../src/traits/structural_match.rs | 34 +- .../rustc_trait_selection/src/traits/util.rs | 14 +- .../rustc_trait_selection/src/traits/wf.rs | 57 +- compiler/rustc_traits/src/chalk/db.rs | 4 +- compiler/rustc_traits/src/chalk/lowering.rs | 43 +- compiler/rustc_traits/src/chalk/mod.rs | 8 +- compiler/rustc_traits/src/dropck_outlives.rs | 4 +- .../rustc_traits/src/evaluate_obligation.rs | 2 +- .../src/implied_outlives_bounds.rs | 2 +- compiler/rustc_traits/src/lib.rs | 2 - .../src/normalize_erasing_regions.rs | 3 +- .../src/normalize_projection_ty.rs | 2 +- compiler/rustc_traits/src/type_op.rs | 2 +- compiler/rustc_ty_utils/Cargo.toml | 1 + compiler/rustc_ty_utils/src/instance.rs | 28 +- compiler/rustc_ty_utils/src/lib.rs | 1 - compiler/rustc_ty_utils/src/ty.rs | 21 +- compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/codec.rs | 64 + compiler/rustc_type_ir/src/lib.rs | 224 + compiler/rustc_type_ir/src/sty.rs | 1429 ++++ compiler/rustc_typeck/Cargo.toml | 1 + compiler/rustc_typeck/src/astconv/errors.rs | 2 +- compiler/rustc_typeck/src/astconv/generics.rs | 72 +- compiler/rustc_typeck/src/astconv/mod.rs | 424 +- compiler/rustc_typeck/src/check/_match.rs | 82 +- compiler/rustc_typeck/src/check/callee.rs | 27 +- compiler/rustc_typeck/src/check/cast.rs | 28 +- compiler/rustc_typeck/src/check/check.rs | 250 +- compiler/rustc_typeck/src/check/closure.rs | 14 +- compiler/rustc_typeck/src/check/coercion.rs | 141 +- .../rustc_typeck/src/check/compare_method.rs | 66 +- compiler/rustc_typeck/src/check/demand.rs | 52 +- compiler/rustc_typeck/src/check/dropck.rs | 106 +- compiler/rustc_typeck/src/check/expr.rs | 399 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 26 +- .../src/check/fn_ctxt/arg_matrix.rs | 351 + .../rustc_typeck/src/check/fn_ctxt/checks.rs | 949 ++- .../rustc_typeck/src/check/fn_ctxt/mod.rs | 7 +- .../src/check/fn_ctxt/suggestions.rs | 235 +- .../src/check/generator_interior.rs | 157 +- .../check/generator_interior/drop_ranges.rs | 3 +- .../drop_ranges/cfg_build.rs | 10 +- .../drop_ranges/record_consumed_borrow.rs | 81 +- compiler/rustc_typeck/src/check/inherited.rs | 6 + .../src/check}/intrinsicck.rs | 144 +- .../rustc_typeck/src/check/method/confirm.rs | 4 +- compiler/rustc_typeck/src/check/method/mod.rs | 4 +- .../rustc_typeck/src/check/method/probe.rs | 4 +- .../rustc_typeck/src/check/method/suggest.rs | 280 +- compiler/rustc_typeck/src/check/mod.rs | 14 + compiler/rustc_typeck/src/check/op.rs | 67 +- compiler/rustc_typeck/src/check/pat.rs | 71 +- .../src => rustc_typeck/src/check}/region.rs | 89 +- compiler/rustc_typeck/src/check/regionck.rs | 22 +- .../rustc_typeck/src/check/rvalue_scopes.rs | 83 + compiler/rustc_typeck/src/check/upvar.rs | 17 +- compiler/rustc_typeck/src/check/wfcheck.rs | 72 +- compiler/rustc_typeck/src/check/writeback.rs | 12 +- compiler/rustc_typeck/src/check_unused.rs | 58 +- .../rustc_typeck/src/coherence/builtin.rs | 85 +- .../src/coherence/inherent_impls.rs | 4 +- compiler/rustc_typeck/src/coherence/mod.rs | 6 +- compiler/rustc_typeck/src/coherence/orphan.rs | 81 +- compiler/rustc_typeck/src/collect.rs | 149 +- compiler/rustc_typeck/src/collect/type_of.rs | 74 +- .../src/constrained_generic_params.rs | 4 +- compiler/rustc_typeck/src/errors.rs | 26 +- compiler/rustc_typeck/src/expr_use_visitor.rs | 46 +- compiler/rustc_typeck/src/hir_wf_check.rs | 5 +- .../src/impl_wf_check/min_specialization.rs | 4 +- compiler/rustc_typeck/src/lib.rs | 14 +- .../rustc_typeck/src/mem_categorization.rs | 39 +- compiler/rustc_typeck/src/outlives/mod.rs | 2 +- .../src/outlives/outlives_bounds.rs | 63 +- compiler/rustc_typeck/src/outlives/utils.rs | 11 +- .../missing_cast_for_variadic_arg.rs | 6 +- .../wrong_number_of_generic_args.rs | 127 +- .../rustc_typeck/src/variance/constraints.rs | 6 +- config.toml.example | 35 +- git-commit-hash | 2 +- library/alloc/benches/vec_deque.rs | 32 + library/alloc/src/alloc.rs | 4 +- library/alloc/src/alloc/tests.rs | 2 +- library/alloc/src/borrow.rs | 3 +- library/alloc/src/boxed.rs | 99 +- library/alloc/src/boxed/thin.rs | 65 +- library/alloc/src/collections/binary_heap.rs | 64 +- .../src/collections/binary_heap/tests.rs | 12 +- library/alloc/src/collections/btree/append.rs | 20 +- library/alloc/src/collections/btree/fix.rs | 58 +- library/alloc/src/collections/btree/map.rs | 409 +- .../alloc/src/collections/btree/map/entry.rs | 81 +- .../alloc/src/collections/btree/map/tests.rs | 35 +- library/alloc/src/collections/btree/mod.rs | 1 + .../alloc/src/collections/btree/navigate.rs | 59 +- library/alloc/src/collections/btree/node.rs | 110 +- .../alloc/src/collections/btree/node/tests.rs | 13 +- library/alloc/src/collections/btree/remove.rs | 22 +- library/alloc/src/collections/btree/search.rs | 15 +- library/alloc/src/collections/btree/set.rs | 328 +- .../alloc/src/collections/btree/set/tests.rs | 23 + .../alloc/src/collections/btree/set_val.rs | 29 + library/alloc/src/collections/btree/split.rs | 15 +- library/alloc/src/collections/linked_list.rs | 4 +- .../src/collections/linked_list/tests.rs | 22 +- .../alloc/src/collections/vec_deque/iter.rs | 12 +- .../alloc/src/collections/vec_deque/mod.rs | 56 +- .../src/collections/vec_deque/spec_extend.rs | 59 + .../alloc/src/collections/vec_deque/tests.rs | 97 + library/alloc/src/ffi/c_str.rs | 78 - library/alloc/src/ffi/mod.rs | 3 - library/alloc/src/fmt.rs | 13 +- library/alloc/src/lib.rs | 7 +- library/alloc/src/macros.rs | 27 +- library/alloc/src/rc.rs | 47 +- library/alloc/src/rc/tests.rs | 12 +- library/alloc/src/slice.rs | 2 + library/alloc/src/str.rs | 75 +- library/alloc/src/string.rs | 95 +- library/alloc/src/sync.rs | 76 +- library/alloc/src/sync/tests.rs | 10 +- library/alloc/src/vec/mod.rs | 121 +- library/alloc/tests/lib.rs | 4 +- library/alloc/tests/slice.rs | 14 +- library/alloc/tests/str.rs | 14 + library/alloc/tests/thin_box.rs | 229 + library/alloc/tests/vec.rs | 19 +- library/backtrace/.github/workflows/main.yml | 9 +- library/backtrace/Cargo.toml | 7 +- library/backtrace/ci/miri-rustup.sh | 7 - library/backtrace/crates/as-if-std/Cargo.toml | 2 +- library/backtrace/src/backtrace/dbghelp.rs | 4 +- library/backtrace/src/backtrace/miri.rs | 51 +- library/backtrace/src/backtrace/mod.rs | 2 +- library/backtrace/src/lib.rs | 2 +- library/backtrace/src/print/fuchsia.rs | 2 +- library/backtrace/src/symbolize/gimli.rs | 8 +- library/backtrace/src/symbolize/mod.rs | 4 +- library/core/benches/fmt.rs | 11 + library/core/src/alloc/global.rs | 8 +- library/core/src/alloc/layout.rs | 2 +- library/core/src/alloc/mod.rs | 6 +- library/core/src/any.rs | 376 +- library/core/src/array/mod.rs | 14 +- library/core/src/asserting.rs | 109 + library/core/src/cell.rs | 103 +- library/core/src/cell/lazy.rs | 104 + library/core/src/cell/once.rs | 283 + library/core/src/clone.rs | 4 +- library/core/src/cmp.rs | 18 +- library/core/src/ffi/c_str.rs | 39 +- library/core/src/ffi/mod.rs | 3 +- library/core/src/fmt/mod.rs | 98 +- library/core/src/future/into_future.rs | 119 + library/core/src/hash/mod.rs | 55 +- library/core/src/hash/sip.rs | 8 +- library/core/src/intrinsics.rs | 26 +- .../core/src/iter/adapters/by_ref_sized.rs | 6 +- library/core/src/iter/adapters/mod.rs | 3 +- library/core/src/iter/mod.rs | 10 +- library/core/src/iter/sources.rs | 8 + .../core/src/iter/sources/from_generator.rs | 43 + library/core/src/iter/traits/iterator.rs | 4 + library/core/src/lazy.rs | 388 -- library/core/src/lib.rs | 3 +- library/core/src/macros/mod.rs | 4 +- library/core/src/marker.rs | 1 - library/core/src/mem/maybe_uninit.rs | 2 +- library/core/src/mem/mod.rs | 24 +- library/core/src/mem/valid_align.rs | 9 +- library/core/src/num/dec2flt/common.rs | 2 +- library/core/src/num/dec2flt/mod.rs | 7 +- library/core/src/num/dec2flt/parse.rs | 6 +- library/core/src/ops/generator.rs | 3 +- library/core/src/ops/try_trait.rs | 1 - library/core/src/option.rs | 20 + library/core/src/pin.rs | 7 +- library/core/src/primitive_docs.rs | 115 +- library/core/src/ptr/const_ptr.rs | 176 +- library/core/src/ptr/mod.rs | 89 +- library/core/src/ptr/mut_ptr.rs | 303 +- library/core/src/ptr/non_null.rs | 15 +- library/core/src/result.rs | 20 + library/core/src/slice/index.rs | 2 +- library/core/src/slice/iter.rs | 48 + library/core/src/slice/mod.rs | 6 +- library/core/src/slice/raw.rs | 8 +- library/core/src/slice/sort.rs | 19 +- library/core/src/str/converts.rs | 5 +- library/core/src/str/error.rs | 6 +- library/core/src/str/mod.rs | 3 +- library/core/src/str/traits.rs | 8 +- library/core/src/sync/atomic.rs | 27 +- library/core/src/task/wake.rs | 13 + library/core/src/time.rs | 136 +- library/core/src/tuple.rs | 141 +- library/core/src/unicode/printable.py | 11 +- library/core/src/unicode/printable.rs | 11 +- library/core/tests/any.rs | 71 +- library/core/tests/array.rs | 2 +- library/core/tests/asserting.rs | 37 + library/core/tests/cell.rs | 6 +- library/core/tests/clone.rs | 4 +- .../core/tests/iter/traits/double_ended.rs | 3 +- library/core/tests/lazy.rs | 5 +- library/core/tests/lib.rs | 6 +- library/core/tests/option.rs | 4 +- library/core/tests/ptr.rs | 53 + library/core/tests/result.rs | 2 +- library/core/tests/slice.rs | 2 - library/panic_abort/src/lib.rs | 3 +- library/panic_unwind/src/emcc.rs | 23 +- library/panic_unwind/src/lib.rs | 3 +- .../crates/core_simd/src/intrinsics.rs | 1 - .../crates/core_simd/src/vector/ptr.rs | 19 - library/proc_macro/src/bridge/buffer.rs | 61 +- library/proc_macro/src/bridge/client.rs | 136 +- library/proc_macro/src/bridge/closure.rs | 6 +- library/proc_macro/src/bridge/handle.rs | 25 +- library/proc_macro/src/bridge/mod.rs | 149 +- library/proc_macro/src/bridge/rpc.rs | 55 +- .../proc_macro/src/bridge/selfless_reify.rs | 83 + library/proc_macro/src/bridge/server.rs | 198 +- library/proc_macro/src/lib.rs | 155 +- library/profiler_builtins/src/lib.rs | 1 - library/std/Cargo.toml | 4 +- library/std/build.rs | 1 + library/std/src/alloc.rs | 22 +- library/std/src/collections/hash/map.rs | 201 +- library/std/src/collections/hash/set.rs | 61 +- library/std/src/env.rs | 3 + library/std/src/error.rs | 146 +- library/std/src/ffi/mod.rs | 2 +- library/std/src/ffi/os_str.rs | 79 +- library/std/src/ffi/os_str/tests.rs | 14 + library/std/src/fs.rs | 12 +- library/std/src/io/buffered/bufwriter.rs | 4 +- library/std/src/io/buffered/linewriter.rs | 4 +- library/std/src/io/error/tests.rs | 6 +- library/std/src/io/impls.rs | 46 + library/std/src/io/mod.rs | 62 +- library/std/src/io/readbuf.rs | 18 +- library/std/src/io/stdio.rs | 9 +- library/std/src/io/tests.rs | 8 +- library/std/src/keyword_docs.rs | 19 +- library/std/src/lazy.rs | 616 -- library/std/src/lib.rs | 6 +- library/std/src/macros.rs | 14 +- library/std/src/net/ip.rs | 10 +- library/std/src/os/fd/mod.rs | 2 +- library/std/src/os/fd/owned.rs | 85 +- library/std/src/os/fd/tests.rs | 19 + library/std/src/os/horizon/fs.rs | 95 + library/std/src/os/horizon/mod.rs | 6 + library/std/src/os/horizon/raw.rs | 70 + library/std/src/os/mod.rs | 2 + library/std/src/os/unix/io/fd.rs | 3 +- library/std/src/os/unix/io/mod.rs | 49 +- library/std/src/os/unix/mod.rs | 2 + library/std/src/os/unix/net/ancillary.rs | 6 +- library/std/src/os/unix/net/datagram.rs | 79 +- library/std/src/os/unix/net/listener.rs | 6 +- library/std/src/os/unix/net/mod.rs | 33 +- library/std/src/os/unix/net/stream.rs | 43 +- library/std/src/os/unix/net/tests.rs | 41 +- library/std/src/os/unix/process.rs | 60 +- library/std/src/os/windows/io/handle.rs | 91 +- library/std/src/os/windows/io/mod.rs | 13 +- library/std/src/os/windows/io/socket.rs | 79 +- library/std/src/os/windows/io/tests.rs | 21 + library/std/src/os/windows/process.rs | 46 +- library/std/src/panicking.rs | 4 +- library/std/src/path.rs | 21 +- library/std/src/path/tests.rs | 1 + library/std/src/prelude/v1.rs | 4 - library/std/src/primitive_docs.rs | 115 +- library/std/src/process.rs | 67 +- library/std/src/sync/condvar.rs | 4 +- library/std/src/sync/lazy_lock.rs | 121 + library/std/src/sync/lazy_lock/tests.rs | 143 + library/std/src/sync/mod.rs | 7 + library/std/src/sync/mpsc/cache_aligned.rs | 3 +- library/std/src/sync/mpsc/mpsc_queue/tests.rs | 4 +- library/std/src/sync/mpsc/spsc_queue/tests.rs | 4 +- library/std/src/sync/mpsc/sync_tests.rs | 12 +- library/std/src/sync/mpsc/tests.rs | 14 +- library/std/src/sync/mutex.rs | 58 +- library/std/src/sync/once_lock.rs | 496 ++ .../std/src/{lazy => sync/once_lock}/tests.rs | 165 +- library/std/src/sync/poison.rs | 15 +- library/std/src/sync/rwlock.rs | 51 +- library/std/src/sys/hermit/condvar.rs | 15 +- library/std/src/sys/hermit/mutex.rs | 3 - library/std/src/sys/hermit/rwlock.rs | 6 - library/std/src/sys/itron/condvar.rs | 2 - library/std/src/sys/itron/mutex.rs | 5 +- library/std/src/sys/sgx/condvar.rs | 15 +- library/std/src/sys/sgx/mutex.rs | 12 +- library/std/src/sys/sgx/rwlock.rs | 12 +- library/std/src/sys/solid/rwlock.rs | 5 +- library/std/src/sys/unix/alloc.rs | 3 +- library/std/src/sys/unix/args.rs | 3 +- library/std/src/sys/unix/env.rs | 11 + library/std/src/sys/unix/fd.rs | 41 +- library/std/src/sys/unix/fs.rs | 25 +- library/std/src/sys/unix/futex.rs | 50 + library/std/src/sys/unix/locks/futex.rs | 9 - .../std/src/sys/unix/locks/futex_rwlock.rs | 17 +- library/std/src/sys/unix/locks/mod.rs | 10 +- .../std/src/sys/unix/locks/pthread_condvar.rs | 41 +- .../std/src/sys/unix/locks/pthread_mutex.rs | 23 +- .../std/src/sys/unix/locks/pthread_rwlock.rs | 18 +- library/std/src/sys/unix/mod.rs | 107 +- library/std/src/sys/unix/net.rs | 20 +- library/std/src/sys/unix/os.rs | 8 +- library/std/src/sys/unix/process/mod.rs | 3 +- .../std/src/sys/unix/process/process_unix.rs | 83 +- .../sys/unix/process/process_unix/tests.rs | 6 +- .../sys/unix/process/process_unsupported.rs | 13 +- library/std/src/sys/unix/rand.rs | 31 +- library/std/src/sys/unix/stdio.rs | 12 +- library/std/src/sys/unix/thread_local_dtor.rs | 2 +- library/std/src/sys/unix/thread_parker.rs | 3 +- library/std/src/sys/unix/time.rs | 5 +- .../std/src/sys/unsupported/locks/condvar.rs | 7 +- .../std/src/sys/unsupported/locks/mutex.rs | 4 +- .../std/src/sys/unsupported/locks/rwlock.rs | 4 +- library/std/src/sys/wasm/mod.rs | 4 +- library/std/src/sys/windows/c.rs | 13 +- library/std/src/sys/windows/compat.rs | 18 +- library/std/src/sys/windows/handle.rs | 2 +- library/std/src/sys/windows/locks/condvar.rs | 8 +- library/std/src/sys/windows/locks/mutex.rs | 6 +- library/std/src/sys/windows/locks/rwlock.rs | 6 +- library/std/src/sys/windows/mod.rs | 6 +- library/std/src/sys/windows/net.rs | 4 +- library/std/src/sys/windows/rand.rs | 74 +- library/std/src/sys_common/condvar.rs | 13 +- library/std/src/sys_common/condvar/check.rs | 3 +- library/std/src/sys_common/lazy_box.rs | 77 + library/std/src/sys_common/mod.rs | 1 + library/std/src/sys_common/mutex.rs | 21 +- library/std/src/sys_common/net.rs | 14 +- library/std/src/sys_common/remutex.rs | 7 - library/std/src/sys_common/rwlock.rs | 18 +- .../std/src/sys_common/thread_local_dtor.rs | 2 +- .../std/src/sys_common/thread_local_key.rs | 2 +- .../std/src/sys_common/thread_parker/mod.rs | 1 + library/std/src/thread/mod.rs | 28 +- library/std/src/thread/scoped.rs | 35 +- library/std/src/thread/tests.rs | 17 +- library/std/src/time.rs | 4 +- library/test/src/lib.rs | 1 - library/unwind/src/lib.rs | 3 +- library/unwind/src/libunwind.rs | 5 +- src/bootstrap/CHANGELOG.md | 1 + src/bootstrap/Cargo.toml | 9 + src/bootstrap/bin/rustc.rs | 12 +- src/bootstrap/bootstrap.py | 334 +- src/bootstrap/builder.rs | 493 +- src/bootstrap/builder/tests.rs | 43 +- src/bootstrap/cache.rs | 4 +- src/bootstrap/compile.rs | 30 +- src/bootstrap/config.rs | 361 +- src/bootstrap/configure.py | 2 +- src/bootstrap/dist.rs | 49 +- src/bootstrap/doc.rs | 4 + src/bootstrap/download-ci-llvm-stamp | 2 +- src/bootstrap/flags.rs | 10 +- src/bootstrap/format.rs | 24 +- src/bootstrap/install.rs | 27 +- src/bootstrap/lib.rs | 110 +- src/bootstrap/metrics.rs | 208 + src/bootstrap/native.rs | 271 +- src/bootstrap/setup.rs | 24 +- src/bootstrap/tarball.rs | 20 +- src/bootstrap/test.rs | 56 +- src/bootstrap/tool.rs | 33 +- src/bootstrap/util.rs | 28 +- src/ci/azure-pipelines/auto.yml | 26 - src/ci/azure-pipelines/try.yml | 22 - .../host-x86_64/dist-various-2/Dockerfile | 6 +- .../dist-various-2/build-wasi-toolchain.sh | 15 +- .../dist-x86_64-freebsd/Dockerfile | 6 +- .../host-x86_64/dist-x86_64-linux/Dockerfile | 4 +- .../x86_64-gnu-tools/browser-ui-test.version | 2 +- src/ci/docker/scripts/freebsd-toolchain.sh | 8 +- src/ci/github-actions/ci.yml | 4 - src/ci/init_repo.sh | 4 - src/ci/pgo.sh | 51 +- src/ci/run.sh | 1 + src/ci/scripts/clean-disk.sh | 16 - src/ci/scripts/disable-git-crlf-conversion.sh | 2 +- src/ci/scripts/setup-environment.sh | 15 - src/ci/scripts/symlink-build-dir.sh | 15 - src/ci/scripts/upload-artifacts.sh | 16 +- src/ci/shared.sh | 31 +- src/doc/book/.github/workflows/main.yml | 4 +- src/doc/book/CONTRIBUTING.md | 23 + src/doc/book/Cargo.lock | 224 +- src/doc/book/book.toml | 2 +- src/doc/book/ci/dictionary.txt | 11 + .../output.txt | 3 +- .../src/main.rs | 4 +- .../no-listing-06-option-examples/src/main.rs | 2 +- .../output.txt | 7 +- .../listing-08-04/src/main.rs | 15 +- .../listing-08-05/src/main.rs | 9 +- .../output.txt | 0 .../listing-08-06/src/main.rs | 9 +- .../listing-08-07/src/main.rs | 11 +- .../listing-08-08/src/main.rs | 6 +- .../listing-08-09/src/main.rs | 13 +- .../listing-08-10/src/main.rs | 16 +- .../listing-08-21/src/main.rs | 10 +- .../listing-08-23/src/main.rs | 5 +- .../listing-08-24/src/main.rs | 5 +- .../listing-08-25/src/main.rs | 13 +- .../listing-08-26/Cargo.lock | 6 - .../listing-08-26/Cargo.toml | 6 - .../listing-08-26/src/main.rs | 16 - .../output.txt | 2 +- .../listing-09-03/src/main.rs | 2 +- .../listing-09-04/src/main.rs | 4 +- .../listing-09-05/src/main.rs | 6 +- .../listing-09-06/src/main.rs | 10 +- .../listing-09-07/src/main.rs | 8 +- .../listing-09-08/src/main.rs | 6 +- .../listing-09-10/output.txt | 6 +- .../listing-09-10/src/main.rs | 2 +- .../listing-09-12/src/main.rs | 2 +- .../Cargo.lock | 6 - .../Cargo.toml | 6 - .../output.txt | 15 - .../src/main.rs | 7 - .../no-listing-04-unwrap/src/main.rs | 2 +- .../no-listing-05-expect/src/main.rs | 3 +- .../src/main.rs | 4 +- .../listing-10-01/src/main.rs | 6 +- .../listing-10-02/src/main.rs | 8 +- .../listing-10-03/src/main.rs | 10 +- .../listing-10-04/src/main.rs | 16 +- .../listing-10-05/output.txt | 8 +- .../listing-10-05/src/main.rs | 6 +- .../src/lib.rs | 0 .../listing-10-15/src/main.rs | 23 - .../listing-10-16/output.txt | 15 + .../listing-10-16/src/main.rs | 10 + .../listing-10-17/Cargo.lock | 2 - .../listing-10-17/output.txt | 15 - .../rustfmt-ignore | 0 .../listing-10-17/src/main.rs | 22 +- .../listing-10-18/src/main.rs | 20 +- .../listing-10-19/Cargo.lock | 2 + .../listing-10-19/src/main.rs | 15 +- .../output.txt | 0 .../listing-10-20/src/main.rs | 10 + .../listing-10-21/src/main.rs | 2 +- .../listing-10-22/src/main.rs | 14 +- .../output.txt | 0 .../listing-10-23/src/main.rs | 6 +- .../listing-10-24/src/main.rs | 24 +- .../listing-10-25/Cargo.lock | 2 +- .../listing-10-25/Cargo.toml | 2 +- .../listing-10-25/src/main.rs | 32 +- .../listing-10-26/Cargo.lock | 6 - .../listing-10-26/src/main.rs | 29 - .../src/main.rs | 2 +- .../src/main.rs | 2 +- .../Cargo.lock | 6 - .../Cargo.toml | 6 - .../output.txt | 25 - .../src/main.rs | 25 - .../listing-11-01/output.txt | 2 +- .../listing-11-03/output.txt | 2 +- .../listing-11-06/output.txt | 2 +- .../listing-11-07/output.txt | 2 +- .../listing-11-08/output.txt | 2 +- .../listing-11-09/src/lib.rs | 3 +- .../listing-11-10/output.txt | 2 +- .../listing-11-11/output.txt | 2 +- .../listing-11-13/output.txt | 2 +- .../output.txt | 2 +- .../output.txt | 2 +- .../output.txt | 2 +- .../no-listing-04-bug-in-add-two/output.txt | 2 +- .../no-listing-06-greeter-with-bug/output.txt | 2 +- .../output.txt | 2 +- .../no-listing-08-guess-with-bug/output.txt | 2 +- .../output.txt | 4 +- .../src/lib.rs | 2 +- .../no-listing-11-ignore-a-test/output.txt | 2 +- .../output.txt | 2 +- .../output-only-01-show-output/output.txt | 2 +- .../output-only-02-single-test/output.txt | 2 +- .../output-only-03-multiple-tests/output.txt | 2 +- .../output-only-04-running-ignored/output.txt | 2 +- .../listing-12-01/output.txt | 4 +- .../listing-12-01/src/main.rs | 2 +- .../listing-12-02/output.txt | 2 +- .../listing-12-02/src/main.rs | 4 +- .../listing-12-03/src/main.rs | 4 +- .../listing-12-04/output.txt | 2 +- .../listing-12-04/src/main.rs | 10 +- .../listing-12-05/src/main.rs | 14 +- .../listing-12-06/src/main.rs | 14 +- .../listing-12-07/src/main.rs | 14 +- .../listing-12-08/src/main.rs | 14 +- .../listing-12-09/src/main.rs | 16 +- .../listing-12-10/src/main.rs | 20 +- .../listing-12-11/src/main.rs | 20 +- .../listing-12-12/src/main.rs | 18 +- .../listing-12-13/src/lib.rs | 12 +- .../listing-12-13/src/main.rs | 8 +- .../listing-12-14/src/lib.rs | 12 +- .../listing-12-14/src/main.rs | 8 +- .../listing-12-15/src/lib.rs | 10 +- .../listing-12-15/src/main.rs | 6 +- .../listing-12-16/output.txt | 2 +- .../listing-12-16/src/lib.rs | 10 +- .../listing-12-16/src/main.rs | 6 +- .../listing-12-17/src/lib.rs | 10 +- .../listing-12-17/src/main.rs | 6 +- .../listing-12-18/src/lib.rs | 10 +- .../listing-12-18/src/main.rs | 6 +- .../listing-12-19/output.txt | 4 +- .../listing-12-19/src/lib.rs | 10 +- .../listing-12-19/src/main.rs | 6 +- .../listing-12-20/src/lib.rs | 12 +- .../listing-12-20/src/main.rs | 6 +- .../listing-12-21/output.txt | 4 +- .../listing-12-21/src/lib.rs | 12 +- .../listing-12-21/src/main.rs | 6 +- .../listing-12-22/src/lib.rs | 12 +- .../listing-12-22/src/main.rs | 6 +- .../listing-12-23/output.txt | 2 +- .../listing-12-23/src/lib.rs | 12 +- .../listing-12-23/src/main.rs | 6 +- .../listing-12-24/src/lib.rs | 12 +- .../listing-12-24/src/main.rs | 6 +- .../src/main.rs | 20 +- .../output.txt | 2 +- .../src/lib.rs | 12 +- .../src/main.rs | 6 +- .../output-only-01-with-args/output.txt | 8 +- .../output-only-01-with-args/src/main.rs | 2 +- .../src/lib.rs | 10 +- .../src/main.rs | 6 +- .../output.txt | 2 +- .../src/lib.rs | 12 +- .../src/main.rs | 6 +- .../output-only-04-no-matches/output.txt | 2 +- .../output-only-04-no-matches/src/lib.rs | 12 +- .../output-only-04-no-matches/src/main.rs | 6 +- .../listing-12-23-reproduced/src/lib.rs | 12 +- .../listing-12-23-reproduced/src/main.rs | 6 +- .../listing-12-24-reproduced/src/lib.rs | 12 +- .../listing-12-24-reproduced/src/main.rs | 6 +- .../listing-13-07/.rustfmt.toml | 2 + .../listing-13-07/src/main.rs | 15 +- .../listing-13-08/.rustfmt.toml | 2 + .../listing-13-08/src/main.rs | 15 +- .../listing-13-09/.rustfmt.toml | 2 + .../listing-13-09/src/main.rs | 15 +- .../listing-13-18/src/lib.rs | 12 +- .../listing-13-18/src/main.rs | 6 +- .../listing-13-19/src/lib.rs | 12 +- .../listing-13-19/src/main.rs | 6 +- .../listing-13-20/src/lib.rs | 14 +- .../listing-13-20/src/main.rs | 6 +- .../listing-13-22/src/lib.rs | 14 +- .../listing-13-22/src/main.rs | 6 +- .../listing-14-07/add/adder/src/main.rs | 3 +- .../listing-15-11/src/main.rs | 2 +- .../listing-15-12/src/main.rs | 2 +- .../listing-15-13/src/main.rs | 2 +- .../listing-15-21/output.txt | 1 - .../listing-15-23/output.txt | 2 +- .../listing-18-01/src/main.rs | 2 +- .../listing-18-05/output.txt | 4 +- .../listing-18-08/output.txt | 5 +- .../listing-18-11/src/main.rs | 4 +- .../listing-18-19/src/main.rs | 2 +- .../listing-18-24/src/main.rs | 2 +- .../listing-18-27/src/main.rs | 4 +- .../ch20-web-server/listing-20-02/src/main.rs | 18 +- .../ch20-web-server/listing-20-03/src/main.rs | 19 +- .../ch20-web-server/listing-20-04/src/main.rs | 24 - .../ch20-web-server/listing-20-05/src/main.rs | 30 +- .../ch20-web-server/listing-20-06/src/main.rs | 27 +- .../{listing-20-08 => listing-20-07}/404.html | 0 .../ch20-web-server/listing-20-07/src/main.rs | 35 +- .../ch20-web-server/listing-20-08/Cargo.lock | 6 - .../ch20-web-server/listing-20-08/Cargo.toml | 6 - .../ch20-web-server/listing-20-08/hello.html | 11 - .../ch20-web-server/listing-20-08/src/main.rs | 47 - .../ch20-web-server/listing-20-09/src/main.rs | 33 +- .../ch20-web-server/listing-20-10/src/main.rs | 46 +- .../ch20-web-server/listing-20-11/src/main.rs | 48 +- .../ch20-web-server/listing-20-12/output.txt | 4 +- .../ch20-web-server/listing-20-12/src/main.rs | 48 +- .../listing-20-13/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-13/src/lib.rs | 1 - .../ch20-web-server/listing-20-13/src/main.rs | 43 + .../listing-20-14/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-14/src/lib.rs | 1 - .../ch20-web-server/listing-20-14/src/main.rs | 43 + .../listing-20-15/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-15/src/main.rs | 43 + .../listing-20-16/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-16/src/lib.rs | 4 +- .../ch20-web-server/listing-20-16/src/main.rs | 43 + .../ch20-web-server/listing-20-17/output.txt | 6 +- .../listing-20-17/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-17/src/lib.rs | 3 +- .../ch20-web-server/listing-20-17/src/main.rs | 43 + .../listing-20-18/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-18/src/lib.rs | 8 +- .../ch20-web-server/listing-20-18/src/main.rs | 43 + .../listing-20-19/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-19/src/lib.rs | 8 +- .../ch20-web-server/listing-20-19/src/main.rs | 43 + .../listing-20-20/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-20/src/lib.rs | 10 +- .../ch20-web-server/listing-20-20/src/main.rs | 43 + .../listing-20-21/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-21/src/lib.rs | 10 +- .../ch20-web-server/listing-20-21/src/main.rs | 43 + .../ch20-web-server/listing-20-22/output.txt | 12 +- .../listing-20-22/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-22/src/lib.rs | 10 +- .../ch20-web-server/listing-20-22/src/main.rs | 43 + .../listing-20-23/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-23/src/lib.rs | 58 +- .../ch20-web-server/listing-20-23/src/main.rs | 45 + .../listing-20-24/src/bin/main.rs | 49 - .../ch20-web-server/listing-20-24/src/lib.rs | 49 +- .../ch20-web-server/listing-20-24/src/main.rs | 45 + .../ch20-web-server/listing-20-25/src/lib.rs | 43 +- .../listing-20-25/src/{bin => }/main.rs | 2 +- .../output.txt | 4 +- .../src/bin/main.rs | 51 - .../src/main.rs | 45 + .../output.txt | 4 +- .../src/bin/main.rs | 49 - .../src/main.rs | 43 + .../src/bin/main.rs | 49 - .../no-listing-03-define-execute/src/main.rs | 43 + .../output.txt | 4 +- .../src/bin/main.rs | 49 - .../src/lib.rs | 10 +- .../src/main.rs | 43 + .../src/bin/main.rs | 49 - .../no-listing-05-fix-worker-new/src/lib.rs | 10 +- .../no-listing-05-fix-worker-new/src/main.rs | 43 + .../src/bin/main.rs | 49 - .../src/lib.rs | 10 +- .../src/main.rs | 45 + .../Cargo.lock | 6 - .../Cargo.toml | 6 - .../hello.html | 11 - .../src/bin/main.rs | 49 - .../404.html | 0 .../Cargo.lock | 0 .../Cargo.toml | 0 .../hello.html | 0 .../src/lib.rs | 44 +- .../src}/main.rs | 4 +- .../no-listing-08-final-code/404.html | 11 - .../no-listing-08-final-code/Cargo.lock | 6 - .../no-listing-08-final-code/Cargo.toml | 6 - .../no-listing-08-final-code/hello.html | 11 - .../no-listing-08-final-code/src/lib.rs | 101 - src/doc/book/nostarch/appendix.md | 765 +++ src/doc/book/nostarch/chapter01.md | 624 ++ src/doc/book/nostarch/chapter05.md | 167 +- src/doc/book/nostarch/chapter06.md | 116 +- src/doc/book/nostarch/chapter07.md | 597 +- src/doc/book/nostarch/chapter08.md | 554 +- src/doc/book/nostarch/chapter09.md | 527 +- src/doc/book/nostarch/chapter10.md | 480 +- src/doc/book/nostarch/chapter11.md | 105 +- src/doc/book/nostarch/chapter12.md | 351 +- src/doc/book/nostarch/chapter13.md | 655 +- src/doc/book/nostarch/chapter14.md | 66 +- src/doc/book/nostarch/chapter15.md | 107 +- src/doc/book/nostarch/chapter16.md | 95 +- src/doc/book/nostarch/chapter17.md | 328 +- src/doc/book/nostarch/chapter18.md | 326 +- src/doc/book/nostarch/chapter19.md | 485 +- src/doc/book/nostarch/chapter20.md | 1947 ++++++ src/doc/book/nostarch/introduction.md | 184 + src/doc/book/rust-toolchain | 2 +- src/doc/book/src/SUMMARY.md | 2 +- src/doc/book/src/appendix-01-keywords.md | 29 +- src/doc/book/src/appendix-02-operators.md | 8 +- .../book/src/appendix-03-derivable-traits.md | 8 +- .../appendix-04-useful-development-tools.md | 31 +- src/doc/book/src/ch01-01-installation.md | 73 +- src/doc/book/src/ch01-02-hello-world.md | 48 +- src/doc/book/src/ch01-03-hello-cargo.md | 36 +- .../src/ch03-01-variables-and-mutability.md | 6 +- .../src/ch04-02-references-and-borrowing.md | 2 +- src/doc/book/src/ch05-00-structs.md | 13 +- src/doc/book/src/ch05-01-defining-structs.md | 22 +- src/doc/book/src/ch05-02-example-structs.md | 19 +- src/doc/book/src/ch05-03-method-syntax.md | 14 +- src/doc/book/src/ch06-00-enums.md | 4 - src/doc/book/src/ch06-01-defining-an-enum.md | 37 +- src/doc/book/src/ch06-02-match.md | 37 +- ...ojects-with-packages-crates-and-modules.md | 35 +- .../book/src/ch07-01-packages-and-crates.md | 57 +- ...ng-modules-to-control-scope-and-privacy.md | 121 +- ...referring-to-an-item-in-the-module-tree.md | 190 +- ...g-paths-into-scope-with-the-use-keyword.md | 23 +- ...separating-modules-into-different-files.md | 75 +- src/doc/book/src/ch08-01-vectors.md | 104 +- src/doc/book/src/ch08-02-strings.md | 60 +- src/doc/book/src/ch08-03-hash-maps.md | 165 +- ...ch09-01-unrecoverable-errors-with-panic.md | 26 +- .../ch09-02-recoverable-errors-with-result.md | 211 +- .../src/ch09-03-to-panic-or-not-to-panic.md | 63 +- src/doc/book/src/ch10-00-generics.md | 26 +- src/doc/book/src/ch10-01-syntax.md | 41 +- src/doc/book/src/ch10-02-traits.md | 82 +- src/doc/book/src/ch10-03-lifetime-syntax.md | 121 +- src/doc/book/src/ch11-01-writing-tests.md | 18 +- src/doc/book/src/ch11-02-running-tests.md | 4 +- src/doc/book/src/ch11-03-test-organization.md | 57 +- src/doc/book/src/ch12-00-an-io-project.md | 4 +- ...h12-01-accepting-command-line-arguments.md | 29 +- src/doc/book/src/ch12-02-reading-a-file.md | 6 +- ...improving-error-handling-and-modularity.md | 90 +- ...2-05-working-with-environment-variables.md | 6 +- ...-06-writing-to-stderr-instead-of-stdout.md | 4 +- .../book/src/ch13-00-functional-features.md | 12 +- src/doc/book/src/ch13-01-closures.md | 266 +- src/doc/book/src/ch13-02-iterators.md | 61 +- .../src/ch13-03-improving-our-io-project.md | 50 +- .../src/ch14-02-publishing-to-crates-io.md | 12 +- src/doc/book/src/ch14-03-cargo-workspaces.md | 9 +- src/doc/book/src/ch15-01-box.md | 9 +- src/doc/book/src/ch15-02-deref.md | 2 +- .../book/src/ch15-05-interior-mutability.md | 26 +- src/doc/book/src/ch16-03-shared-state.md | 6 + src/doc/book/src/ch17-00-oop.md | 24 +- src/doc/book/src/ch17-01-what-is-oo.md | 67 +- src/doc/book/src/ch17-02-trait-objects.md | 61 +- .../book/src/ch17-03-oo-design-patterns.md | 128 +- src/doc/book/src/ch18-00-patterns.md | 9 +- .../ch18-01-all-the-places-for-patterns.md | 79 +- src/doc/book/src/ch18-02-refutability.md | 10 +- src/doc/book/src/ch18-03-pattern-syntax.md | 155 +- src/doc/book/src/ch19-00-advanced-features.md | 10 +- src/doc/book/src/ch19-01-unsafe-rust.md | 122 +- src/doc/book/src/ch19-03-advanced-traits.md | 115 +- src/doc/book/src/ch19-04-advanced-types.md | 85 +- ...ch19-05-advanced-functions-and-closures.md | 33 +- src/doc/book/src/ch19-06-macros.md | 91 +- .../src/ch20-00-final-project-a-web-server.md | 25 +- src/doc/book/src/ch20-01-single-threaded.md | 240 +- src/doc/book/src/ch20-02-multithreaded.md | 250 +- .../ch20-03-graceful-shutdown-and-cleanup.md | 150 +- src/doc/book/src/title-page.md | 2 +- src/doc/book/tools/src/bin/concat_chapters.rs | 4 +- src/doc/book/tools/src/bin/convert_quotes.rs | 10 +- src/doc/book/tools/src/bin/lfp.rs | 14 +- src/doc/book/tools/src/bin/link2print.rs | 12 +- .../book/tools/src/bin/release_listings.rs | 8 +- .../book/tools/src/bin/remove_hidden_lines.rs | 2 +- src/doc/book/tools/src/bin/remove_links.rs | 4 +- src/doc/book/tools/src/bin/remove_markup.rs | 4 +- src/doc/book/tools/update-rustc.sh | 4 +- src/doc/embedded-book/src/intro/index.md | 3 + src/doc/embedded-book/src/start/registers.md | 2 +- src/doc/nomicon/.github/workflows/main.yml | 2 +- src/doc/nomicon/src/borrow-splitting.md | 8 +- src/doc/nomicon/src/destructors.md | 2 +- src/doc/nomicon/src/exotic-sizes.md | 4 +- src/doc/nomicon/src/ffi.md | 113 +- src/doc/nomicon/src/intro.md | 2 +- src/doc/nomicon/src/phantom-data.md | 177 +- src/doc/nomicon/src/subtyping.md | 2 +- src/doc/reference/src/const_eval.md | 5 +- .../reference/src/expressions/match-expr.md | 3 +- src/doc/reference/src/inline-assembly.md | 12 +- .../reference/src/items/external-blocks.md | 31 +- src/doc/reference/src/names/namespaces.md | 8 +- src/doc/reference/src/paths.md | 3 + src/doc/reference/src/procedural-macros.md | 5 +- src/doc/reference/src/subtyping.md | 34 +- src/doc/reference/src/tokens.md | 40 +- src/doc/reference/src/types.md | 3 - .../error/multiple_error_types/wrap_error.md | 2 +- .../src/flow_control/match/guard.md | 36 +- .../rust-by-example/src/generics/phantom.md | 18 +- src/doc/rust-by-example/src/hello/print.md | 4 +- src/doc/rust-by-example/src/macros/dsl.md | 4 +- .../rust-by-example/src/primitives/array.md | 17 +- src/doc/rust-by-example/src/std/arc.md | 15 +- .../src/testing/doc_testing.md | 9 +- .../src/trait/disambiguating.md | 12 +- .../rust-by-example/src/trait/impl_trait.md | 4 +- src/doc/rust-by-example/src/unsafe/asm.md | 24 +- src/doc/rustc-dev-guide/book.toml | 14 +- .../rustc-dev-guide/ci/date-check/Cargo.lock | 34 +- .../examples/rustc-driver-example.rs | 30 +- .../rustc-driver-getting-diagnostics.rs | 15 +- .../rustc-driver-interacting-with-the-ast.rs | 23 +- src/doc/rustc-dev-guide/src/SUMMARY.md | 11 +- .../src/borrow_check/region_inference.md | 7 +- .../src/borrow_check/type_check.md | 54 + .../src/building/how-to-build-and-run.md | 6 + .../src/building/new-target.md | 6 + .../rustc-dev-guide/src/building/suggested.md | 21 +- src/doc/rustc-dev-guide/src/compiler-src.md | 48 +- src/doc/rustc-dev-guide/src/contributing.md | 6 +- src/doc/rustc-dev-guide/src/diagnostics.md | 111 +- .../src/diagnostics/diagnostic-codes.md | 8 +- .../src/diagnostics/diagnostic-items.md | 147 +- .../src/diagnostics/diagnostic-structs.md | 359 ++ .../src/diagnostics/error-guaranteed.md | 3 - .../src/diagnostics/lintstore.md | 124 +- .../src/diagnostics/sessiondiagnostic.md | 207 - .../src/diagnostics/translation.md | 239 + src/doc/rustc-dev-guide/src/git.md | 2 +- .../rustc-dev-guide/src/macro-expansion.md | 24 +- src/doc/rustc-dev-guide/src/mir/dataflow.md | 9 +- src/doc/rustc-dev-guide/src/overview.md | 4 +- .../incremental-compilation-in-detail.md | 4 +- src/doc/rustc-dev-guide/src/query.md | 2 +- .../src/rustc-driver-getting-diagnostics.md | 6 +- .../rustc-driver-interacting-with-the-ast.md | 9 +- src/doc/rustc-dev-guide/src/rustc-driver.md | 2 +- .../rustc-dev-guide/src/rustdoc-internals.md | 33 +- src/doc/rustc-dev-guide/src/stability.md | 33 +- .../rustc-dev-guide/src/tests/compiletest.md | 11 +- src/doc/rustc-dev-guide/src/tests/docker.md | 2 +- src/doc/rustc-dev-guide/src/tests/headers.md | 2 +- src/doc/rustc-dev-guide/src/tests/running.md | 12 +- src/doc/rustc-dev-guide/src/tests/ui.md | 15 +- src/doc/rustc-dev-guide/src/tracing.md | 24 + src/doc/rustc-dev-guide/src/traits/chalk.md | 11 +- .../rustc-dev-guide/src/traits/resolution.md | 2 +- src/doc/rustc/src/SUMMARY.md | 23 +- src/doc/rustc/src/codegen-options/index.md | 2 +- src/doc/rustc/src/command-line-arguments.md | 25 +- src/doc/rustc/src/instrument-coverage.md | 2 +- src/doc/rustc/src/linker-plugin-lto.md | 2 +- src/doc/rustc/src/lints/levels.md | 2 +- .../src/lints/listing/allowed-by-default.md | 2 +- .../src/lints/listing/deny-by-default.md | 2 +- src/doc/rustc/src/lints/listing/index.md | 2 +- .../src/lints/listing/warn-by-default.md | 2 +- src/doc/rustc/src/platform-support.md | 7 +- .../src/platform-support/apple-watchos.md | 55 + .../platform-support/armv6k-nintendo-3ds.md | 130 + .../platform-support/pc-windows-gnullvm.md | 4 +- .../riscv32imac-unknown-xous-elf.md | 50 + .../rustc/src/profile-guided-optimization.md | 2 +- src/doc/rustdoc/src/how-to-read-rustdoc.md | 17 +- .../write-documentation/the-doc-attribute.md | 4 +- .../write-documentation/what-to-include.md | 5 +- .../src/compiler-flags/extern-options.md | 22 + .../src/compiler-flags/sanitizer.md | 5 +- .../virtual-function-elimination.md | 39 + .../crate-visibility-modifier.md | 20 - .../language-features/debugger-visualizer.md | 4 +- .../explicit-generic-args-with-impl-trait.md | 53 - .../infer-static-outlives-requirements.md | 44 - .../src/language-features/lang-items.md | 4 +- .../native-link-modifiers-bundle.md | 19 - src/etc/cpu-usage-over-time-plot.sh | 20 +- src/etc/htmldocck.py | 49 +- src/etc/natvis/libcore.natvis | 8 +- src/librustdoc/Cargo.toml | 6 +- src/librustdoc/clean/auto_trait.rs | 46 +- src/librustdoc/clean/blanket_impl.rs | 6 +- src/librustdoc/clean/cfg.rs | 28 +- src/librustdoc/clean/cfg/tests.rs | 2 +- src/librustdoc/clean/inline.rs | 73 +- src/librustdoc/clean/mod.rs | 910 +-- src/librustdoc/clean/render_macro_matchers.rs | 2 +- src/librustdoc/clean/simplify.rs | 4 +- src/librustdoc/clean/types.rs | 689 +- src/librustdoc/clean/utils.rs | 113 +- src/librustdoc/config.rs | 146 +- src/librustdoc/core.rs | 82 +- src/librustdoc/docfs.rs | 21 +- src/librustdoc/doctest.rs | 38 +- src/librustdoc/error.rs | 6 +- src/librustdoc/externalfiles.rs | 14 +- src/librustdoc/fold.rs | 24 +- src/librustdoc/formats/cache.rs | 191 +- src/librustdoc/formats/item_type.rs | 4 +- src/librustdoc/formats/mod.rs | 60 +- src/librustdoc/formats/renderer.rs | 4 +- src/librustdoc/html/escape.rs | 2 +- src/librustdoc/html/format.rs | 345 +- src/librustdoc/html/highlight.rs | 125 +- src/librustdoc/html/layout.rs | 42 +- src/librustdoc/html/markdown.rs | 103 +- src/librustdoc/html/mod.rs | 16 +- src/librustdoc/html/render/context.rs | 154 +- src/librustdoc/html/render/mod.rs | 152 +- src/librustdoc/html/render/print_item.rs | 102 +- src/librustdoc/html/render/search_index.rs | 118 +- src/librustdoc/html/render/span_map.rs | 93 +- src/librustdoc/html/render/write_shared.rs | 35 +- src/librustdoc/html/sources.rs | 37 +- src/librustdoc/html/static/.eslintrc.js | 62 + src/librustdoc/html/static/css/noscript.css | 4 - src/librustdoc/html/static/css/rustdoc.css | 69 +- src/librustdoc/html/static/css/settings.css | 93 +- src/librustdoc/html/static/css/themes/ayu.css | 68 +- .../html/static/css/themes/dark.css | 56 +- .../html/static/css/themes/light.css | 57 +- src/librustdoc/html/static/images/brush.svg | 1 - src/librustdoc/html/static/js/main.js | 281 +- .../html/static/js/scrape-examples.js | 6 +- src/librustdoc/html/static/js/search.js | 205 +- src/librustdoc/html/static/js/settings.js | 91 +- .../html/static/js/source-script.js | 57 +- src/librustdoc/html/static/js/storage.js | 24 +- src/librustdoc/html/static_files.rs | 96 +- src/librustdoc/html/templates/page.html | 30 +- src/librustdoc/html/toc.rs | 21 +- src/librustdoc/html/url_parts_builder.rs | 16 +- src/librustdoc/json/conversions.rs | 136 +- src/librustdoc/json/mod.rs | 79 +- src/librustdoc/lib.rs | 10 +- src/librustdoc/lint.rs | 6 +- src/librustdoc/markdown.rs | 4 +- src/librustdoc/passes/bare_urls.rs | 8 +- .../passes/calculate_doc_coverage.rs | 4 +- .../passes/check_code_block_syntax.rs | 11 +- .../passes/check_doc_test_visibility.rs | 12 +- .../passes/collect_intra_doc_links.rs | 247 +- .../passes/collect_intra_doc_links/early.rs | 44 +- src/librustdoc/passes/collect_trait_impls.rs | 35 +- src/librustdoc/passes/html_tags.rs | 10 +- src/librustdoc/passes/mod.rs | 58 +- src/librustdoc/passes/propagate_doc_cfg.rs | 4 +- src/librustdoc/passes/strip_hidden.rs | 15 +- src/librustdoc/passes/strip_priv_imports.rs | 4 +- src/librustdoc/passes/strip_private.rs | 4 +- src/librustdoc/passes/stripper.rs | 21 +- src/librustdoc/scrape_examples.rs | 48 +- src/librustdoc/theme.rs | 13 +- src/librustdoc/theme/tests.rs | 2 +- src/librustdoc/visit.rs | 3 +- src/librustdoc/visit_ast.rs | 37 +- src/librustdoc/visit_lib.rs | 8 +- src/rustdoc-json-types/lib.rs | 25 +- src/stage0.json | 584 +- src/test/assembly/asm/hexagon-types.rs | 6 +- .../stack-protector-heuristics-effect.rs | 2 +- .../codegen-units/item-collection/unsizing.rs | 1 + .../codegen/abi-main-signature-32bit-c-int.rs | 2 +- src/test/codegen/adjustments.rs | 6 +- src/test/codegen/align-enum.rs | 2 +- src/test/codegen/align-struct.rs | 5 +- src/test/codegen/array-equality.rs | 19 +- src/test/codegen/asm-clobber_abi.rs | 8 +- src/test/codegen/asm-target-clobbers.rs | 7 + src/test/codegen/atomic-operations.rs | 36 +- src/test/codegen/c-variadic.rs | 8 +- .../codegen/cold-call-declare-and-call.rs | 18 + src/test/codegen/consts.rs | 6 +- src/test/codegen/debug-alignment.rs | 8 + src/test/codegen/fastcall-inreg.rs | 2 +- src/test/codegen/ffi-out-of-bounds-loads.rs | 2 +- src/test/codegen/function-arguments-noopt.rs | 8 +- src/test/codegen/function-arguments.rs | 44 +- src/test/codegen/gdb_debug_script_load.rs | 2 +- src/test/codegen/intrinsics/nontemporal.rs | 2 +- src/test/codegen/intrinsics/prefetch.rs | 32 +- src/test/codegen/intrinsics/volatile.rs | 6 +- src/test/codegen/intrinsics/volatile_order.rs | 2 +- src/test/codegen/issue-37945.rs | 8 +- src/test/codegen/issue-56267-2.rs | 2 +- src/test/codegen/issue-56267.rs | 2 +- src/test/codegen/issue-56927.rs | 14 +- src/test/codegen/issue-58881.rs | 2 +- .../codegen/issue-96497-slice-size-nowrap.rs | 29 + src/test/codegen/lifetime_start_end.rs | 28 +- src/test/codegen/loads.rs | 42 +- src/test/codegen/match.rs | 4 +- src/test/codegen/mem-replace-direct-memcpy.rs | 4 +- src/test/codegen/noalias-refcell.rs | 14 + src/test/codegen/packed.rs | 40 +- src/test/codegen/personality_lifetimes.rs | 8 +- src/test/codegen/refs.rs | 8 +- src/test/codegen/remap_path_prefix/main.rs | 2 +- src/test/codegen/repeat-trusted-len.rs | 2 +- .../codegen/repr-transparent-aggregates-1.rs | 16 +- src/test/codegen/repr-transparent.rs | 6 +- .../riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs | 10 +- .../simd-intrinsic-generic-gather.rs | 4 +- .../simd-intrinsic-generic-scatter.rs | 4 +- .../simd-intrinsic-transmute-array.rs | 12 +- src/test/codegen/simd_arith_offset.rs | 2 +- src/test/codegen/slice-init.rs | 12 +- src/test/codegen/slice-iter-len-eq-zero.rs | 2 +- src/test/codegen/slice-ref-equality.rs | 12 +- src/test/codegen/stores.rs | 12 +- src/test/codegen/swap-large-types.rs | 6 +- src/test/codegen/thread-local.rs | 8 +- src/test/codegen/transmute-scalar.rs | 42 +- src/test/codegen/uninit-consts.rs | 8 +- src/test/codegen/union-abi.rs | 10 +- .../unwind-abis/c-unwind-abi-panic-abort.rs | 21 +- src/test/codegen/used_with_arg.rs | 4 +- .../virtual-function-elimination-32bit.rs | 35 + .../codegen/virtual-function-elimination.rs | 100 + src/test/codegen/zst-offset.rs | 9 +- ...ependency-with-embedded-visualizers.natvis | 10 + .../dependency-with-embedded-visualizers.py | 23 + .../dependency-with-embedded-visualizers.rs | 19 + ...atvis => embedded-visualizer-point.natvis} | 10 +- .../debuginfo/embedded-visualizer-point.py | 23 + src/test/debuginfo/embedded-visualizer.natvis | 10 + src/test/debuginfo/embedded-visualizer.py | 23 + src/test/debuginfo/embedded-visualizer.rs | 112 + src/test/debuginfo/function-names.rs | 4 +- src/test/debuginfo/lexical-scope-in-if-let.rs | 100 + src/test/debuginfo/msvc-embedded-natvis.rs | 64 - src/test/debuginfo/thread-names.rs | 51 + .../incremental/hashes/call_expressions.rs | 2 +- .../incremental/hashes/closure_expressions.rs | 8 +- src/test/incremental/hashes/consts.rs | 2 +- .../incremental/hashes/enum_constructors.rs | 22 +- src/test/incremental/hashes/enum_defs.rs | 2 +- .../incremental/hashes/exported_vs_not.rs | 2 +- src/test/incremental/hashes/extern_mods.rs | 2 +- src/test/incremental/hashes/for_loops.rs | 8 +- .../incremental/hashes/function_interfaces.rs | 2 +- src/test/incremental/hashes/if_expressions.rs | 2 +- .../hashes/indexing_expressions.rs | 2 +- src/test/incremental/hashes/inherent_impls.rs | 2 +- src/test/incremental/hashes/inline_asm.rs | 2 +- .../incremental/hashes/let_expressions.rs | 6 +- .../incremental/hashes/loop_expressions.rs | 6 +- .../incremental/hashes/match_expressions.rs | 2 +- src/test/incremental/hashes/panic_exprs.rs | 2 +- src/test/incremental/hashes/statics.rs | 2 +- .../incremental/hashes/struct_constructors.rs | 2 +- src/test/incremental/hashes/struct_defs.rs | 2 +- src/test/incremental/hashes/trait_defs.rs | 2 +- src/test/incremental/hashes/trait_impls.rs | 2 +- src/test/incremental/hashes/type_defs.rs | 2 +- .../hashes/unary_and_binary_exprs.rs | 2 +- .../incremental/hashes/while_let_loops.rs | 2 +- src/test/incremental/hashes/while_loops.rs | 10 +- src/test/incremental/issue-54242.rs | 2 +- ..._of_reborrow.SimplifyCfg-initial.after.mir | 60 +- ...c_abort.main.AbortUnwindingCalls.after.mir | 24 + src/test/mir-opt/asm_unwind_panic_abort.rs | 16 + ...ignment.main.SimplifyCfg-initial.after.mir | 4 +- ...allocation2.main.ConstProp.after.32bit.mir | 30 +- ...allocation2.main.ConstProp.after.64bit.mir | 32 +- .../const_debuginfo.main.ConstDebugInfo.diff | 1 + .../const_prop/boxes.main.ConstProp.diff | 14 +- ..._prop_fails_gracefully.main.ConstProp.diff | 2 +- ...l_flow_simplification.hello.ConstProp.diff | 2 +- .../discriminant.main.ConstProp.32bit.diff | 22 +- .../discriminant.main.ConstProp.64bit.diff | 22 +- ...riable.main.SimplifyLocals.after.32bit.mir | 3 - ...riable.main.SimplifyLocals.after.64bit.mir | 3 - .../reify_fn_ptr.main.ConstProp.diff | 4 +- .../cycle.cycle.DeadStoreElimination.diff | 75 + .../mir-opt/dead-store-elimination/cycle.rs | 22 + ...s.pointer_to_int.DeadStoreElimination.diff | 35 + ...soundness.retags.DeadStoreElimination.diff | 14 + .../provenance_soundness.rs | 18 + .../derefer_inline_test.main.Derefer.diff | 69 + src/test/mir-opt/derefer_inline_test.rs | 11 + .../branch.main.DestinationPropagation.diff | 24 +- ...on_arg.arg_src.DestinationPropagation.diff | 4 +- ...gation_arg.bar.DestinationPropagation.diff | 4 +- ...gation_arg.baz.DestinationPropagation.diff | 12 +- ...gation_arg.foo.DestinationPropagation.diff | 12 +- .../cycle.main.DestinationPropagation.diff | 51 +- .../union.main.DestinationPropagation.diff | 22 +- ...ness.no_downcast.EarlyOtherwiseBranch.diff | 18 +- ...float_to_exponential_common.ConstProp.diff | 64 +- .../inline/dyn_trait.get_query.Inline.diff | 4 + .../dyn_trait.try_execute_query.Inline.diff | 4 + .../inline_any_operand.bar.Inline.after.mir | 4 + .../inline_closure.foo.Inline.after.mir | 4 + ...e_closure_borrows_arg.foo.Inline.after.mir | 4 + ...line_closure_captures.foo.Inline.after.mir | 4 + ...patibility.inlined_no_sanitize.Inline.diff | 4 + ...ibility.inlined_target_feature.Inline.diff | 4 + .../inline/inline_cycle.one.Inline.diff | 4 + .../inline/inline_cycle.two.Inline.diff | 4 + .../inline/inline_diverging.f.Inline.diff | 8 +- .../inline/inline_diverging.g.Inline.diff | 12 +- .../inline/inline_diverging.h.Inline.diff | 44 +- .../inline/inline_generator.main.Inline.diff | 18 +- ...inline_instruction_set.default.Inline.diff | 4 + .../inline_instruction_set.t32.Inline.diff | 4 + ...line_into_box_place.main.Inline.32bit.diff | 46 +- ...line_into_box_place.main.Inline.64bit.diff | 46 +- .../inline_options.main.Inline.after.mir | 4 + .../inline/inline_retag.bar.Inline.after.mir | 4 + .../inline/inline_shims.clone.Inline.diff | 4 + .../inline/inline_shims.drop.Inline.diff | 4 + .../inline_specialization.main.Inline.diff | 4 + ...line_trait_method_2.test2.Inline.after.mir | 4 + ...67_inline_as_ref_as_mut.a.Inline.after.mir | 4 + ...67_inline_as_ref_as_mut.b.Inline.after.mir | 10 +- ...67_inline_as_ref_as_mut.c.Inline.after.mir | 4 + ...67_inline_as_ref_as_mut.d.Inline.after.mir | 10 +- ...ine_scopes_parenting.main.Inline.after.mir | 4 + ...st_combine_deref.deep_opt.InstCombine.diff | 92 - ...e_deref.do_not_miscompile.InstCombine.diff | 85 - ...st_combine_deref.dont_opt.InstCombine.diff | 53 - ..._combine_deref.opt_struct.InstCombine.diff | 44 - ..._combine_deref.simple_opt.InstCombine.diff | 34 - .../issue_41888.main.ElaborateDrops.after.mir | 14 +- .../mir-opt/issue_72181_1.main.mir_map.0.mir | 8 +- .../issue_73223.main.PreCodegen.32bit.diff | 75 +- .../issue_73223.main.PreCodegen.64bit.diff | 75 +- ..._73223.main.SimplifyArmIdentity.32bit.diff | 2 +- ..._73223.main.SimplifyArmIdentity.64bit.diff | 2 +- ...76432.test.SimplifyComparisonIntegral.diff | 2 +- ...ue_59352.num_to_digit.PreCodegen.after.mir | 17 +- ...e_75439.foo.MatchBranchSimplification.diff | 34 +- ..._array_len.array_bound.SimplifyLocals.diff | 3 - ...ay_len.array_bound_mut.SimplifyLocals.diff | 3 - ...er_array_len.array_len.SimplifyLocals.diff | 3 - ...len.array_len_by_value.SimplifyLocals.diff | 3 - ...ntrinsics.unreachable.LowerIntrinsics.diff | 2 +- ...s.full_tested_match.PromoteTemps.after.mir | 126 +- ...full_tested_match2.PromoteTemps.before.mir | 120 +- ...h_false_edges.main.PromoteTemps.before.mir | 174 +- src/test/mir-opt/match_false_edges.rs | 2 - src/test/mir-opt/nll/named-lifetimes-basic.rs | 4 +- .../mir-opt/nll/region-subtyping-basic.rs | 4 +- ...egion_subtyping_basic.main.nll.0.32bit.mir | 4 +- ...egion_subtyping_basic.main.nll.0.64bit.mir | 4 +- ...wrap.SimplifyCfg-elaborate-drops.after.mir | 2 +- ...receiver_ptr_mutability.main.mir_map.0.mir | 8 +- ...age_markers.main.RemoveStorageMarkers.diff | 4 + ...nneeded_drops.opt.RemoveUnneededDrops.diff | 4 + ....opt_generic_copy.RemoveUnneededDrops.diff | 4 + ...asts.SimplifyCfg-elaborate-drops.after.mir | 2 +- ...st_switch.too_complex.PreCodegen.after.mir | 37 +- src/test/mir-opt/simplify-locals.rs | 9 +- ...mplify_arm.id_try.SimplifyArmIdentity.diff | 4 + ...implify_arm.id_try.SimplifyBranchSame.diff | 4 + .../simplify_locals.c.SimplifyLocals.diff | 3 +- .../simplify_locals.d1.SimplifyLocals.diff | 1 + .../simplify_locals.d2.SimplifyLocals.diff | 11 +- ...ify_locals.expose_addr.SimplifyLocals.diff | 21 + .../simplify_locals.r.SimplifyLocals.diff | 1 + .../simplify_locals.t1.SimplifyLocals.diff | 1 + .../simplify_locals.t2.SimplifyLocals.diff | 1 + .../simplify_locals.t3.SimplifyLocals.diff | 1 + ..._locals_fixedpoint.foo.SimplifyLocals.diff | 50 +- ...ves_unused_consts.main.SimplifyLocals.diff | 4 - ...minant_reads.map.SimplifyLocals.32bit.diff | 3 - ...minant_reads.map.SimplifyLocals.64bit.diff | 3 - ...y.try_identity.DestinationPropagation.diff | 39 +- ..._try.try_identity.SimplifyLocals.after.mir | 16 +- src/test/mir-opt/tls-access.rs | 5 +- ...r => tls_access.main.PreCodegen.after.mir} | 35 +- ...num.process_never.SimplifyLocals.after.mir | 1 - ...enum.process_void.SimplifyLocals.after.mir | 1 - ...reachable.main.UnreachablePropagation.diff | 26 +- ...diverging.main.UnreachablePropagation.diff | 42 +- src/test/mir-opt/unusual-item-types.rs | 2 +- ...oops.change_loop_body.ConstProp.32bit.diff | 24 +- ...oops.change_loop_body.ConstProp.64bit.diff | 24 +- ...hange_loop_body.PreCodegen.after.32bit.mir | 3 +- ...hange_loop_body.PreCodegen.after.64bit.mir | 3 +- src/test/pretty/where-clauses.rs | 3 + .../coverage-llvmir/filecheck.testprog.txt | 12 +- .../obtain-borrowck/driver.rs | 62 +- .../filecheck-patterns.txt | 4 +- .../rustdoc-error-lines/input.rs | 6 +- .../static-nobundle/Makefile | 23 - .../run-make-fulldeps/static-nobundle/bbb.rs | 13 - .../run-make-fulldeps/static-nobundle/ccc.rs | 13 - .../run-make-fulldeps/static-nobundle/ddd.rs | 7 - src/test/run-make-fulldeps/tools.mk | 2 +- .../run-make/libtest-thread-limit/test.rs | 8 +- .../native-link-modifier-bundle/Makefile | 29 + .../native-link-modifier-bundle/bundled.rs | 11 + .../cdylib-bundled.rs | 1 + .../cdylib-non-bundled.rs | 1 + .../native-staticlib.c} | 0 .../non-bundled.rs | 11 + .../Makefile | 23 +- ...irectly_linked_test_minus_whole_archive.rs | 7 + ...directly_linked_test_plus_whole_archive.rs | 7 + .../native_lib_in_src.rs | 2 - .../run-make/remap-path-prefix-dwarf/Makefile | 77 + .../remap-path-prefix-dwarf/src/quux.rs | 5 + .../run-pass-valgrind/cast-enum-with-dtor.rs | 2 +- src/test/rustdoc-gui/README.md | 20 +- .../rustdoc-gui/duplicate-macro-reexport.goml | 6 +- src/test/rustdoc-gui/headings.goml | 4 +- src/test/rustdoc-gui/search-filter.goml | 34 + src/test/rustdoc-gui/settings.goml | 99 +- src/test/rustdoc-gui/shortcuts.goml | 12 - src/test/rustdoc-gui/sidebar-source-code.goml | 10 +- src/test/rustdoc-gui/source-code-page.goml | 41 +- src/test/rustdoc-gui/theme-change.goml | 19 +- src/test/rustdoc-js/generics-impl.js | 57 + src/test/rustdoc-js/generics-impl.rs | 35 + src/test/rustdoc-js/impl-trait.js | 51 + src/test/rustdoc-js/impl-trait.rs | 21 + src/test/rustdoc-js/raw-pointer.js | 55 + src/test/rustdoc-js/raw-pointer.rs | 24 + src/test/rustdoc-json/fn_pointer/generics.rs | 14 + src/test/rustdoc-json/fns/generic_args.rs | 32 +- src/test/rustdoc-json/generic_impl.rs | 24 + src/test/rustdoc-json/keyword.rs | 21 + src/test/rustdoc-json/output_generics.rs | 38 + .../rustdoc-json/primitive_overloading.rs | 17 + .../same_type_reexported_more_than_once.rs | 17 + src/test/rustdoc-ui/display-output.stdout | 2 +- .../rustdoc-ui/doc-comment-multi-line-attr.rs | 11 + .../doc-comment-multi-line-attr.stdout | 6 + .../intra-doc/disambiguator-mismatch.stderr | 6 +- src/test/rustdoc-ui/intra-doc/errors.stderr | 8 +- .../rustdoc-ui/intra-doc/macro-rules-error.rs | 11 +- .../intra-doc/macro-rules-error.stderr | 23 +- .../unresolved-import-recovery.stderr | 2 + src/test/rustdoc-ui/issue-61732.stderr | 2 + src/test/rustdoc-ui/test-compile-fail1.stderr | 2 +- src/test/rustdoc-ui/tuple-variadic-check.rs | 15 + .../rustdoc-ui/tuple-variadic-check.stderr | 8 + src/test/rustdoc/anonymous-lifetime.rs | 28 + src/test/rustdoc/anonymous-reexport.rs | 22 + .../rustdoc/auxiliary/issue-100204-aux.rs | 13 + ...-98697-reexport-with-anonymous-lifetime.rs | 9 + src/test/rustdoc/auxiliary/issue-99221-aux.rs | 20 + src/test/rustdoc/auxiliary/issue-99734-aux.rs | 11 + .../check-source-code-urls-to-def-std.rs | 25 + src/test/rustdoc/doc-auto-cfg.rs | 31 +- src/test/rustdoc/empty-impl-block.rs | 20 + src/test/rustdoc/fn-bound.rs | 21 + src/test/rustdoc/impl-box.rs | 16 + .../auxiliary/implementors_inline.rs | 18 + .../rustdoc/inline_cross/implementors-js.rs | 25 + src/test/rustdoc/intra-doc/email-address.rs | 6 +- ...-100204-inline-impl-through-glob-import.rs | 14 + src/test/rustdoc/issue-75588.rs | 2 +- src/test/rustdoc/issue-98697.rs | 13 + ...tiple-macro-rules-w-same-name-submodule.rs | 19 + ...-99221-multiple-macro-rules-w-same-name.rs | 17 + ...ssue-99221-multiple-structs-w-same-name.rs | 14 + ...sue-99734-multiple-foreigns-w-same-name.rs | 16 + .../issue-99734-multiple-mods-w-same-name.rs | 14 + src/test/rustdoc/nested-modules.rs | 42 + .../rustdoc/primitive-slice-auto-trait.rs | 14 + .../rustdoc/primitive-tuple-auto-trait.rs | 22 + src/test/rustdoc/primitive-tuple-variadic.rs | 18 + src/test/rustdoc/primitive-unit-auto-trait.rs | 14 + src/test/rustdoc/rfc-2632-const-trait-impl.rs | 2 +- .../rustdoc/slice-links.link_box_generic.html | 1 + .../rustdoc/slice-links.link_box_u32.html | 1 + .../slice-links.link_slice_generic.html | 1 + .../rustdoc/slice-links.link_slice_u32.html | 1 + src/test/rustdoc/slice-links.rs | 28 + .../strip-enum-variant.no-not-shown.html | 1 + src/test/rustdoc/strip-enum-variant.rs | 2 + src/test/rustdoc/tuples.link1_i32.html | 1 + src/test/rustdoc/tuples.link1_t.html | 1 + src/test/rustdoc/tuples.link2_i32.html | 1 + src/test/rustdoc/tuples.link2_t.html | 1 + src/test/rustdoc/tuples.link2_tu.html | 1 + src/test/rustdoc/tuples.link_unit.html | 1 + src/test/rustdoc/tuples.rs | 12 + src/test/rustdoc/visibility.rs | 4 +- .../deriving-encodable-decodable-box.rs | 14 +- ...riving-encodable-decodable-cell-refcell.rs | 14 +- src/test/ui-fulldeps/extern-mod-syntax.rs | 4 +- .../fluent-messages/duplicate-a.ftl | 1 + .../fluent-messages/duplicate-b.ftl | 1 + .../fluent-messages/missing-message.ftl | 1 + src/test/ui-fulldeps/fluent-messages/test.rs | 66 + .../ui-fulldeps/fluent-messages/test.stderr | 45 + .../ui-fulldeps/fluent-messages/valid.ftl | 1 + .../ui-fulldeps/internal-lints/diagnostics.rs | 73 + .../internal-lints/diagnostics.stderr | 44 + .../internal-lints/diagnostics_incorrect.rs | 15 + .../diagnostics_incorrect.stderr | 17 + .../internal-lints/ty_tykind_usage.rs | 60 +- .../internal-lints/ty_tykind_usage.stderr | 146 +- src/test/ui-fulldeps/issue-11881.rs | 67 +- src/test/ui-fulldeps/issue-14021.rs | 14 +- src/test/ui-fulldeps/issue-15924.rs | 43 +- src/test/ui-fulldeps/issue-2804.rs | 33 +- src/test/ui-fulldeps/lint-tool-test.stderr | 16 +- .../session-diagnostic/diagnostic-derive.rs | 4 - .../diagnostic-derive.stderr | 32 +- src/test/ui/argument-suggestions/basic.rs | 7 +- src/test/ui/argument-suggestions/basic.stderr | 93 +- src/test/ui/argument-suggestions/complex.rs | 9 +- .../ui/argument-suggestions/complex.stderr | 54 +- .../extra_arguments.stderr | 126 +- .../argument-suggestions/invalid_arguments.rs | 43 +- .../invalid_arguments.stderr | 318 +- .../argument-suggestions/issue-96638.stderr | 8 +- .../argument-suggestions/issue-97197.stderr | 8 +- .../ui/argument-suggestions/issue-97484.rs | 14 + .../argument-suggestions/issue-97484.stderr | 27 + .../ui/argument-suggestions/issue-98894.rs | 4 + .../argument-suggestions/issue-98894.stderr | 19 + .../ui/argument-suggestions/issue-98897.rs | 4 + .../argument-suggestions/issue-98897.stderr | 19 + .../missing_arguments.stderr | 155 +- .../ui/argument-suggestions/mixed_cases.rs | 9 +- .../argument-suggestions/mixed_cases.stderr | 97 +- .../permuted_arguments.rs | 12 +- .../permuted_arguments.stderr | 66 +- .../argument-suggestions/swapped_arguments.rs | 23 +- .../swapped_arguments.stderr | 131 +- .../ui/array-slice-vec/infer_array_len.stderr | 6 +- .../ui/array-slice-vec/vector-no-ann.stderr | 11 +- src/test/ui/asm/aarch64/bad-reg.rs | 2 + src/test/ui/asm/aarch64/bad-reg.stderr | 34 +- src/test/ui/asm/aarch64/type-check-2-2.rs | 37 + src/test/ui/asm/aarch64/type-check-2-2.stderr | 34 + src/test/ui/asm/aarch64/type-check-2.rs | 17 - src/test/ui/asm/aarch64/type-check-2.stderr | 82 +- src/test/ui/asm/aarch64/type-check-3.rs | 18 - src/test/ui/asm/aarch64/type-check-3.stderr | 27 +- src/test/ui/asm/aarch64/type-check-4.rs | 32 + src/test/ui/asm/aarch64/type-check-4.stderr | 27 + .../bad-template.aarch64_mirunsafeck.stderr | 36 +- .../bad-template.aarch64_thirunsafeck.stderr | 36 +- src/test/ui/asm/bad-template.rs | 1 + .../bad-template.x86_64_mirunsafeck.stderr | 36 +- .../bad-template.x86_64_thirunsafeck.stderr | 36 +- src/test/ui/asm/generic-const.rs | 30 + src/test/ui/asm/issue-97490.rs | 12 + src/test/ui/asm/issue-99122-2.rs | 21 + src/test/ui/asm/issue-99122.rs | 13 + src/test/ui/asm/issue-99122.stderr | 11 + src/test/ui/asm/naked-functions.rs | 1 + src/test/ui/asm/naked-functions.stderr | 58 +- src/test/ui/asm/type-check-1.rs | 4 +- src/test/ui/asm/type-check-1.stderr | 59 +- src/test/ui/asm/x86_64/bad-reg.rs | 8 + src/test/ui/asm/x86_64/bad-reg.stderr | 90 +- src/test/ui/asm/x86_64/issue-82869.rs | 1 + src/test/ui/asm/x86_64/issue-82869.stderr | 6 +- src/test/ui/asm/x86_64/type-check-2.rs | 6 +- src/test/ui/asm/x86_64/type-check-2.stderr | 90 +- src/test/ui/asm/x86_64/type-check-3.rs | 18 - src/test/ui/asm/x86_64/type-check-3.stderr | 27 +- src/test/ui/asm/x86_64/type-check-4.rs | 29 + src/test/ui/asm/x86_64/type-check-4.stderr | 27 + src/test/ui/asm/x86_64/type-check-5.rs | 63 + src/test/ui/asm/x86_64/type-check-5.stderr | 34 + .../associated-const-dead-code.rs | 2 +- .../associated-const-dead-code.stderr | 2 +- .../associated-consts/defaults-cyclic-fail.rs | 2 +- .../defaults-cyclic-fail.stderr | 34 +- ...9-assoc-const-static-recursion-impl.stderr | 23 +- ...onst-static-recursion-trait-default.stderr | 23 +- ...-assoc-const-static-recursion-trait.stderr | 23 +- src/test/ui/associated-consts/issue-93775.rs | 29 + .../ui/associated-consts/issue-93835.stderr | 7 +- .../implied-region-constraints.nll.stderr | 28 - .../implied-region-constraints.rs | 4 +- .../implied-region-constraints.stderr | 25 +- .../associated-type-bounds/type-alias.stderr | 24 +- ...ted-type-projection-from-supertrait.stderr | 40 +- .../associated-types-eq-hr.nll.stderr | 47 - .../associated-types-eq-hr.rs | 5 - .../associated-types-eq-hr.stderr | 47 +- .../associated-types-path-2.stderr | 9 +- ...es-project-from-hrtb-in-fn-body.nll.stderr | 30 - ...ated-types-project-from-hrtb-in-fn-body.rs | 3 +- ...-types-project-from-hrtb-in-fn-body.stderr | 32 +- .../associated-types-subtyping-1.nll.stderr | 28 - .../associated-types-subtyping-1.rs | 6 +- .../associated-types-subtyping-1.stderr | 27 +- ...fn-ret-contravariant.krisskross.nll.stderr | 30 - ...ect-fn-ret-contravariant.krisskross.stderr | 31 +- .../project-fn-ret-contravariant.ok.stderr | 8 - ...project-fn-ret-contravariant.oneuse.stderr | 8 - .../cache/project-fn-ret-contravariant.rs | 12 +- ...-fn-ret-contravariant.transmute.nll.stderr | 10 - ...ject-fn-ret-contravariant.transmute.stderr | 9 +- ...ect-fn-ret-invariant.krisskross.nll.stderr | 36 - ...project-fn-ret-invariant.krisskross.stderr | 40 +- .../cache/project-fn-ret-invariant.ok.stderr | 8 - ...project-fn-ret-invariant.oneuse.nll.stderr | 36 - .../project-fn-ret-invariant.oneuse.stderr | 42 +- .../cache/project-fn-ret-invariant.rs | 17 +- ...ject-fn-ret-invariant.transmute.nll.stderr | 15 - .../project-fn-ret-invariant.transmute.stderr | 20 +- .../defaults-specialization.stderr | 6 +- .../higher-ranked-projection.bad.stderr | 6 +- ...> higher-ranked-projection.badbase.stderr} | 2 +- .../higher-ranked-projection.badnll.stderr | 2 + .../higher-ranked-projection.good.stderr | 8 - .../higher-ranked-projection.rs | 6 +- .../hr-associated-type-projection-1.stderr | 14 +- ...mpl-trait-return-missing-constraint.stderr | 3 + .../issue-20825-2.rs | 0 .../issue-20825.rs | 0 .../issue-20825.stderr | 0 .../ui/associated-types/issue-22560.stderr | 2 +- .../ui/associated-types/issue-36499.stderr | 2 +- .../issue-47139-2.rs | 0 src/test/ui/associated-types/issue-82079.rs | 3 + src/test/ui/associated-types/issue-87261.rs | 8 +- .../ui/associated-types/issue-87261.stderr | 24 +- src/test/ui/ast-json/ast-json-ice.rs | 56 - .../ui/ast-json/ast-json-noexpand-output.rs | 10 - .../ast-json/ast-json-noexpand-output.stdout | 1 - src/test/ui/ast-json/ast-json-output.rs | 10 - src/test/ui/ast-json/ast-json-output.stdout | 1 - .../dont-suggest-missing-await.stderr | 9 +- src/test/ui/async-await/generator-desc.stderr | 32 +- .../issue-67765-async-diagnostic.stderr | 2 +- src/test/ui/async-await/issue-68112.stderr | 30 +- src/test/ui/async-await/issue-70594.stderr | 2 +- ...e-70935-complex-spans.drop_tracking.stderr | 40 + ...> issue-70935-complex-spans.normal.stderr} | 8 +- .../async-await/issue-70935-complex-spans.rs | 16 +- .../ui/async-await/issue-76547.nll.stderr | 22 - src/test/ui/async-await/issue-76547.rs | 4 +- src/test/ui/async-await/issue-76547.stderr | 27 +- .../issues/issue-54752-async-block.stderr | 2 +- .../async-await/issues/issue-62009-1.stderr | 2 +- .../async-await/issues/issue-62097.nll.stderr | 36 - src/test/ui/async-await/issues/issue-62097.rs | 4 +- .../ui/async-await/issues/issue-62097.stderr | 41 +- .../issues/issue-63388-1.nll.stderr | 15 - .../ui/async-await/issues/issue-63388-1.rs | 3 +- .../async-await/issues/issue-63388-1.stderr | 21 +- .../async-await/issues/issue-72312.nll.stderr | 21 - src/test/ui/async-await/issues/issue-72312.rs | 14 +- .../ui/async-await/issues/issue-72312.stderr | 36 +- src/test/ui/async-await/issues/issue-95307.rs | 13 + .../ui/async-await/issues/issue-95307.stderr | 30 + .../ret-impl-trait-one.nll.stderr | 35 - .../multiple-lifetimes/ret-impl-trait-one.rs | 2 +- .../ret-impl-trait-one.stderr | 16 +- .../partial-drop-partial-reinit.rs | 8 + .../partial-drop-partial-reinit.stderr | 20 +- .../suggest-missing-await-closure.stderr | 9 +- .../async-await/suggest-missing-await.stderr | 9 +- .../ui/async-await/unnecessary-await.stderr | 2 +- src/test/ui/async-await/unused-lifetime.rs | 16 +- .../ui/async-await/unused-lifetime.stderr | 34 +- src/test/ui/attributes/attrs-on-params.rs | 2 +- src/test/ui/attributes/attrs-on-params.stderr | 2 +- .../field-attributes-vis-unresolved.stderr | 4 + .../auto-traits/suspicious-impls-lint.stderr | 10 +- src/test/ui/binop/issue-77910-1.stderr | 14 +- .../ui/blind/blind-item-item-shadow.stderr | 2 +- src/test/ui/block-result/issue-5500.stderr | 2 +- .../borrow-raw-address-of-borrowed.stderr | 8 +- ...row-raw-address-of-deref-mutability.stderr | 4 +- .../ui/borrowck/borrow-tuple-fields.stderr | 2 +- .../borrowck/borrowck-assign-comp-idx.stderr | 4 +- .../ui/borrowck/borrowck-drop-from-guard.rs | 2 - .../borrowck/borrowck-drop-from-guard.stderr | 2 +- ...ature-nll-overrides-migrate.edition.stderr | 13 - .../borrowck-feature-nll-overrides-migrate.rs | 30 - ...feature-nll-overrides-migrate.zflag.stderr | 13 - .../borrowck-loan-rcvr-overloaded-op.stderr | 4 +- .../ui/borrowck/borrowck-loan-rcvr.stderr | 2 +- src/test/ui/borrowck/borrowck-local-borrow.rs | 3 - ...-move-from-subpath-of-borrowed-path.stderr | 2 +- ...rowck-move-moved-value-into-closure.stderr | 2 +- ...orrowck-overloaded-index-move-index.stderr | 2 +- ...orrow-from-shorter-lived-andmut.nll.stderr | 14 - ...owck-reborrow-from-shorter-lived-andmut.rs | 2 +- ...-reborrow-from-shorter-lived-andmut.stderr | 13 +- ...ck-slice-pattern-element-loan-array.stderr | 4 +- .../ui/borrowck/borrowck-union-borrow.stderr | 2 +- .../copy-suggestion-region-vid.stderr | 2 +- ...-borrowck-migrate-scans-parents.nll.stderr | 54 - ...ue-55492-borrowck-migrate-scans-parents.rs | 26 +- ...492-borrowck-migrate-scans-parents.stderr} | 12 +- ...issue-58776-borrowck-scans-children.stderr | 2 +- src/test/ui/borrowck/issue-71546.rs | 17 + src/test/ui/borrowck/issue-81899.rs | 15 + src/test/ui/borrowck/issue-81899.stderr | 29 + .../borrowck/issue-88434-minimal-example.rs | 2 + .../issue-88434-minimal-example.stderr | 18 +- ...ssue-88434-removal-index-should-be-less.rs | 2 + ...-88434-removal-index-should-be-less.stderr | 18 +- .../ui/borrowck/mut-borrow-of-mut-ref.stderr | 6 +- ...ion-sharing-interference.nll_target.stderr | 8 +- ...o-phase-activation-sharing-interference.rs | 4 +- ...ccess-during-reservation.nll_target.stderr | 6 +- ...o-phase-allow-access-during-reservation.rs | 4 +- .../two-phase-cannot-nest-mut-self-calls.rs | 2 - ...wo-phase-cannot-nest-mut-self-calls.stderr | 2 +- .../ui/borrowck/two-phase-method-receivers.rs | 2 - .../two-phase-multiple-activations.rs | 2 - ... => two-phase-nonrecv-autoref.base.stderr} | 22 +- .../ui/borrowck/two-phase-nonrecv-autoref.rs | 26 +- ...rvation-sharing-interference-2.base.stderr | 25 - ...-sharing-interference-2.migrate2015.stderr | 25 - ...ervation-sharing-interference-2.nll.stderr | 25 - ...tion-sharing-interference-2.nll2015.stderr | 25 - ...tion-sharing-interference-2.nll2018.stderr | 25 - ...hase-reservation-sharing-interference-2.rs | 14 +- ...reservation-sharing-interference-2.stderr} | 6 +- ...ion-sharing-interference.nll_target.stderr | 2 +- ...-phase-reservation-sharing-interference.rs | 4 +- src/test/ui/borrowck/two-phase-sneaky.rs | 2 - src/test/ui/borrowck/two-phase-sneaky.stderr | 4 +- .../builtin-superkinds-self-type.stderr | 7 +- src/test/ui/c-variadic/variadic-ffi-1.stderr | 16 +- src/test/ui/cast/cast-int-to-char.stderr | 46 +- src/test/ui/cast/casts-issue-46365.rs | 3 +- src/test/ui/{issues => cast}/issue-10991.rs | 0 .../ui/{issues => cast}/issue-10991.stderr | 0 src/test/ui/cast/issue-89497.stderr | 2 +- src/test/ui/cenum_impl_drop_cast.stderr | 15 + src/test/ui/cfg/cfg-target-compact-errors.rs | 17 + .../ui/cfg/cfg-target-compact-errors.stderr | 22 + src/test/ui/cfg/cfg-target-compact.rs | 10 + src/test/ui/chalkify/bugs/async.stderr | 8 +- src/test/ui/check-cfg/compact-names.rs | 15 + src/test/ui/check-cfg/compact-names.stderr | 10 + src/test/ui/check-cfg/compact-values.rs | 15 + src/test/ui/check-cfg/compact-values.stderr | 11 + .../ui/check-cfg/well-known-values.stderr | 2 +- .../expect-fn-supply-fn.nll.stderr | 51 - .../expect-fn-supply-fn.rs | 4 +- .../expect-fn-supply-fn.stderr | 69 +- ...er-vars-supply-ty-with-bound-region.stderr | 7 +- .../capture-enum-field.rs | 27 + .../diagnostics/mut_ref.stderr | 2 +- .../2229_closure_analysis/issue-87987.rs | 11 +- .../2229_closure_analysis/issue-87987.stderr | 14 +- .../match/issue-87097.rs | 2 +- .../match/issue-87097.stderr | 5 +- .../migrations/auto_traits.stderr | 14 +- .../migrations/multi_diagnostics.stderr | 7 +- .../add_semicolon_non_block_closure.rs | 11 + .../add_semicolon_non_block_closure.stderr | 16 + ...ds-static-cant-capture-borrowed.nll.stderr | 42 - ...ure-bounds-static-cant-capture-borrowed.rs | 3 +- ...bounds-static-cant-capture-borrowed.stderr | 48 +- .../expect-region-supply-region-2.nll.stderr | 22 - .../expect-region-supply-region-2.rs | 4 +- .../expect-region-supply-region-2.stderr | 61 +- src/test/ui/closures/closure-move-sync.stderr | 16 +- .../ui/closures/closure-reform-bad.stderr | 9 +- src/test/ui/closures/issue-52437.stderr | 7 +- src/test/ui/closures/issue-6801.stderr | 2 +- .../issue-82438-mut-without-upvar.stderr | 2 +- src/test/ui/closures/issue-84128.stderr | 9 +- src/test/ui/closures/issue-87461.stderr | 30 +- .../ui/codegen/auxiliary/issue-97708-aux.rs | 41 + .../ui/{issues => codegen}/issue-28950.rs | 0 src/test/ui/codegen/issue-63787.rs | 36 + src/test/ui/codegen/issue-97708.rs | 9 + src/test/ui/codemap_tests/two_files.stderr | 1 + src/test/ui/codemap_tests/unicode.stderr | 2 +- src/test/ui/coercion/coerce-mut.stderr | 9 +- .../coerce-reborrow-multi-arg-fail.stderr | 9 +- src/test/ui/coercion/coerce-to-bang.stderr | 45 +- ...nce-conflicting-negative-trait-impl.stderr | 2 +- .../coherence-fn-implied-bounds.stderr | 2 +- .../coherence-free-vs-bound-region.stderr | 2 +- .../ui/coherence/coherence-impls-sized.stderr | 12 +- ...oherence-projection-conflict-orphan.stderr | 2 +- ...erence-projection-conflict-ty-param.stderr | 2 +- .../coherence-projection-conflict.stderr | 2 +- .../ui/coherence/coherence-subtyping.stderr | 2 +- .../ui/coherence/coherence-with-closure.rs | 15 + .../coherence/coherence-with-closure.stderr | 24 + .../ui/coherence/coherence-with-generator.rs | 19 + .../coherence/coherence-with-generator.stderr | 24 + .../cfg_accessible-bugs.rs | 18 + .../cfg_accessible-bugs.stderr | 16 + ...cfg_accessible-not_sure.edition2015.stderr | 122 + ...cfg_accessible-not_sure.edition2021.stderr | 122 + .../cfg_accessible-not_sure.rs | 89 + .../cfg_accessible-private.rs | 21 + .../conditional-compilation/cfg_accessible.rs | 38 +- .../cfg_accessible.stderr | 45 +- ...const-argument-cross-crate-mismatch.stderr | 20 +- .../const-argument-if-length.full.stderr | 2 +- .../const-argument-if-length.min.stderr | 2 +- .../defaults/doesnt_infer.stderr | 11 +- .../defaults/rp_impl_trait_fail.rs | 4 +- .../defaults/rp_impl_trait_fail.stderr | 17 +- .../defaults/trait_objects_fail.rs | 2 +- .../defaults/trait_objects_fail.stderr | 6 +- .../different_generic_args_array.stderr | 2 +- .../generic_arg_infer/issue-91614.stderr | 10 +- .../generic_const_exprs/closures.rs | 2 +- .../generic_const_exprs/closures.stderr | 25 +- .../const_eval_resolve_canonical.stderr | 9 +- .../dependence_lint.full.stderr | 39 + .../dependence_lint.gce.stderr | 34 + .../generic_const_exprs/dependence_lint.rs | 25 + .../issue-62504.min.stderr | 23 +- .../generic_const_exprs/issue-94287.stderr | 1 + .../generic_const_exprs/no_dependence.rs | 13 + .../impl-trait-with-const-arguments.stderr | 12 - .../infer/cannot-infer-const-args.stderr | 6 +- .../const-generics/infer/issue-77092.stderr | 8 +- .../const-generics/infer/method-chain.stderr | 6 +- .../infer/one-param-uninferred.stderr | 8 +- .../infer/uninferred-consts.stderr | 8 +- .../ui/const-generics/invariant.nll.stderr | 26 - src/test/ui/const-generics/invariant.stderr | 4 +- src/test/ui/const-generics/issue-97007.rs | 88 + .../issues/issue-63322-forbid-dyn.full.stderr | 4 +- .../issues/issue-67945-3.full.stderr | 16 + .../issues/issue-67945-3.min.stderr | 21 + .../ui/const-generics/issues/issue-67945-3.rs | 17 + .../issues/issue-67945-4.full.stderr | 16 + .../issues/issue-67945-4.min.stderr | 21 + .../ui/const-generics/issues/issue-67945-4.rs | 16 + ...ic-reference-array-const-param.min.stderr} | 2 +- ...3727-static-reference-array-const-param.rs | 14 + .../const-generics/issues/issue-83249.stderr | 11 +- .../const-generics/issues/issue-83765.stderr | 6 +- .../ui/const-generics/issues/issue-88119.rs | 35 + .../ui/const-generics/issues/issue-97278.rs | 14 + .../const-generics/issues/issue-97278.stderr | 9 + .../static-reference-array-const-param.rs | 6 - .../issue-89013-no-assoc.stderr | 2 +- .../parser-error-recovery/issue-89013.stderr | 2 +- .../ui/const-generics/unused_braces.stderr | 2 +- src/test/ui/const-ptr/allowed_slices.rs | 106 + .../const-ptr/forbidden_slices.32bit.stderr | 280 + .../const-ptr/forbidden_slices.64bit.stderr | 280 + src/test/ui/const-ptr/forbidden_slices.rs | 99 + .../ui/const-ptr/out_of_bounds_read.stderr | 6 +- .../ui/consts/const-blocks/migrate-fail.rs | 2 - .../consts/const-blocks/migrate-fail.stderr | 4 +- .../ui/consts/const-blocks/migrate-pass.rs | 2 - src/test/ui/consts/const-blocks/nll-fail.rs | 1 - .../ui/consts/const-blocks/nll-fail.stderr | 4 +- src/test/ui/consts/const-blocks/nll-pass.rs | 1 - src/test/ui/consts/const-err4.32bit.stderr | 2 +- src/test/ui/consts/const-err4.64bit.stderr | 2 +- .../const-eval/const-eval-query-stack.rs | 3 +- .../const-eval/const-eval-query-stack.stderr | 24 +- ...inter-values-in-various-types.64bit.stderr | 18 +- src/test/ui/consts/const-eval/format.rs | 21 + src/test/ui/consts/const-eval/format.stderr | 78 + .../heap/alloc_intrinsic_uninit.32bit.stderr | 2 +- .../heap/alloc_intrinsic_uninit.64bit.stderr | 2 +- .../const-eval/ref_to_int_match.32bit.stderr | 2 +- .../const-eval/ref_to_int_match.64bit.stderr | 2 +- .../const-eval/ub-enum-overwrite.stderr | 2 +- .../ui/consts/const-eval/ub-enum.32bit.stderr | 12 +- .../ui/consts/const-eval/ub-enum.64bit.stderr | 12 +- .../consts/const-eval/ub-nonnull.32bit.stderr | 2 +- .../consts/const-eval/ub-nonnull.64bit.stderr | 2 +- .../consts/const-eval/ub-ref-ptr.32bit.stderr | 2 +- .../consts/const-eval/ub-ref-ptr.64bit.stderr | 2 +- .../const-eval/ub-uninhabit.32bit.stderr | 2 +- .../const-eval/ub-uninhabit.64bit.stderr | 2 +- .../const-eval/union-const-eval-field.stderr | 2 +- .../ui/consts/const-eval/union-ice.stderr | 4 +- .../validate_uninhabited_zsts.32bit.stderr | 24 +- .../validate_uninhabited_zsts.64bit.stderr | 24 +- .../ui/consts/const-float-bits-reject-conv.rs | 16 + .../const-float-bits-reject-conv.stderr | 107 +- src/test/ui/consts/const-fn-ptr.rs | 16 + src/test/ui/consts/const-fn-ptr.stderr | 20 + src/test/ui/consts/const-integer-bool-ops.rs | 10 + .../ui/consts/const-integer-bool-ops.stderr | 95 +- .../const-mut-refs/issue-76510.32bit.stderr | 12 +- .../const-mut-refs/issue-76510.64bit.stderr | 12 +- .../ui/consts/const-mut-refs/issue-76510.rs | 1 + src/test/ui/consts/const-size_of-cycle.stderr | 6 +- src/test/ui/consts/const-tup-index-span.rs | 1 + .../ui/consts/const-tup-index-span.stderr | 11 +- src/test/ui/consts/copy-intrinsic.rs | 6 +- .../ui/consts/intrinsic_without_const_stab.rs | 4 +- .../intrinsic_without_const_stab_fail.rs | 4 +- src/test/ui/consts/issue-36163.stderr | 40 +- src/test/ui/{issues => consts}/issue-39974.rs | 0 .../ui/{issues => consts}/issue-39974.stderr | 0 src/test/ui/consts/issue-44415.rs | 2 +- src/test/ui/consts/issue-44415.stderr | 6 +- src/test/ui/{issues => consts}/issue-54387.rs | 0 src/test/ui/consts/issue-56164.stderr | 2 +- src/test/ui/consts/issue-64662.stderr | 14 +- src/test/ui/consts/issue-91434.rs | 1 - src/test/ui/consts/issue-91434.stderr | 10 +- src/test/ui/consts/nested_erroneous_ctfe.rs | 4 + .../ui/consts/nested_erroneous_ctfe.stderr | 12 + src/test/ui/consts/offset_from_ub.rs | 12 +- src/test/ui/consts/offset_from_ub.stderr | 14 +- .../recursive-zst-static.default.stderr | 14 +- .../recursive-zst-static.unleash.stderr | 14 +- .../ui/consts/rustc-impl-const-stability.rs | 7 +- .../transmute-size-mismatch-before-typeck.rs | 10 +- ...ansmute-size-mismatch-before-typeck.stderr | 28 +- .../consts/validate_never_arrays.32bit.stderr | 2 +- .../consts/validate_never_arrays.64bit.stderr | 2 +- .../write-to-static-mut-in-static.stderr | 16 +- src/test/ui/deprecation/rustc_deprecated.rs | 13 - .../ui/deprecation/rustc_deprecated.stderr | 21 - .../deprecation/try-macro-suggestion.stderr | 2 +- src/test/ui/derive-uninhabited-enum-38885.rs | 2 +- .../ui/derive-uninhabited-enum-38885.stderr | 12 +- ...lone-debug-dead-code-in-the-same-struct.rs | 12 + ...-debug-dead-code-in-the-same-struct.stderr | 24 + src/test/ui/derives/clone-debug-dead-code.rs | 10 +- .../ui/derives/clone-debug-dead-code.stderr | 51 +- src/test/ui/derives/issue-91550.stderr | 6 +- src/test/ui/derives/issue-97343.rs | 8 + src/test/ui/derives/issue-97343.stderr | 21 + .../ui/{issues => deriving}/issue-6341.rs | 0 src/test/ui/destructure-trait-ref.stderr | 12 +- .../did_you_mean/compatible-variants.stderr | 2 +- src/test/ui/did_you_mean/issue-34126.stderr | 2 +- src/test/ui/did_you_mean/issue-42764.stderr | 9 +- ...-identifier-not-instead-of-negation.stderr | 10 +- .../did_you_mean/use_instead_of_import.fixed | 15 + .../ui/did_you_mean/use_instead_of_import.rs | 15 + .../did_you_mean/use_instead_of_import.stderr | 14 + .../ui/disambiguate-identical-names.stderr | 9 +- src/test/ui/drop/repeat-drop-2.rs | 15 + src/test/ui/drop/repeat-drop-2.stderr | 29 + src/test/ui/drop/repeat-drop.rs | 121 + src/test/ui/dropck/issue-38868.stderr | 3 +- .../dropck/reject-specialized-drops-8142.rs | 6 +- .../reject-specialized-drops-8142.stderr | 71 +- .../dst/dst-object-from-unsized-type.stderr | 4 +- .../dyn-keyword/dyn-2018-edition-lint.stderr | 14 +- .../dyn-keyword/dyn-2021-edition-error.stderr | 4 +- .../ui/dyn-keyword/dyn-angle-brackets.stderr | 2 +- ...dition-keywords-2015-2018-expansion.stderr | 1 + ...dition-keywords-2018-2018-expansion.stderr | 1 + src/test/ui/empty/empty-linkname.rs | 2 +- src/test/ui/empty/empty-linkname.stderr | 6 +- .../ui/empty/empty-struct-unit-expr.stderr | 4 +- .../forbidden-discriminant-kind-impl.stderr | 2 +- src/test/ui/enum/enum-discrim-autosizing.rs | 7 +- .../ui/enum/enum-discrim-autosizing.stderr | 18 +- src/test/ui/error-codes/E0057.stderr | 28 +- src/test/ui/error-codes/E0060.stderr | 8 +- src/test/ui/error-codes/E0061.stderr | 16 +- src/test/ui/error-codes/E0081.rs | 23 +- src/test/ui/error-codes/E0081.stderr | 58 +- src/test/ui/error-codes/E0109.stderr | 12 +- src/test/ui/error-codes/E0110.stderr | 12 +- src/test/ui/error-codes/E0138.stderr | 4 +- ...E0161.edition.stderr => E0161.base.stderr} | 2 +- src/test/ui/error-codes/E0161.migrate.stderr | 9 - src/test/ui/error-codes/E0161.nll.stderr | 9 - src/test/ui/error-codes/E0161.rs | 26 +- src/test/ui/error-codes/E0161.zflags.stderr | 9 - src/test/ui/error-codes/E0214.stderr | 10 +- src/test/ui/error-codes/E0255.stderr | 2 +- src/test/ui/error-codes/E0259.stderr | 2 +- src/test/ui/error-codes/E0260.stderr | 2 +- src/test/ui/error-codes/E0263.rs | 2 +- src/test/ui/error-codes/E0263.stderr | 8 +- src/test/ui/error-codes/E0282.stderr | 7 +- src/test/ui/error-codes/E0283.stderr | 11 +- src/test/ui/error-codes/E0308-2.stderr | 2 +- src/test/ui/error-codes/E0393.stderr | 2 +- src/test/ui/error-codes/E0401.stderr | 7 +- src/test/ui/error-codes/E0411.stderr | 2 + src/test/ui/error-codes/E0423.stderr | 2 +- src/test/ui/error-codes/E0429.stderr | 2 +- src/test/ui/error-codes/E0432.stderr | 2 + src/test/ui/error-codes/E0446.stderr | 2 +- src/test/ui/error-codes/E0453.stderr | 4 +- src/test/ui/error-codes/E0454.stderr | 6 +- src/test/ui/error-codes/E0458.stderr | 10 +- src/test/ui/error-codes/E0459.stderr | 2 +- src/test/ui/error-codes/E0490.nll.stderr | 28 - src/test/ui/error-codes/E0490.rs | 8 - src/test/ui/error-codes/E0490.stderr | 76 - src/test/ui/error-codes/E0504.stderr | 2 +- src/test/ui/error-codes/E0506.stderr | 2 +- src/test/ui/error-codes/E0604.stderr | 9 +- src/test/ui/error-codes/E0605.stderr | 2 +- src/test/ui/error-codes/E0618.stderr | 2 +- src/test/ui/error-festival.stderr | 9 +- src/test/ui/expr/if/bad-if-let-suggestion.rs | 24 + .../ui/expr/if/bad-if-let-suggestion.stderr | 69 + .../ui/expr/if/if-no-match-bindings.stderr | 8 +- src/test/ui/expr/if/if-without-block.rs | 4 +- src/test/ui/expr/if/if-without-block.stderr | 15 +- .../auxiliary/debugger-visualizer.natvis | 3 + .../feature-gates/feature-gate-asm_const.rs | 6 + .../feature-gate-asm_const.stderr | 13 +- .../ui/feature-gates/feature-gate-asm_sym.rs | 11 +- .../feature-gates/feature-gate-asm_sym.stderr | 17 +- .../feature-gate-cfg-target-compact.rs | 13 + .../feature-gate-cfg-target-compact.stderr | 39 + .../feature-gate-crate_visibility_modifier.rs | 8 - ...ture-gate-crate_visibility_modifier.stderr | 12 - .../feature-gate-debugger-visualizer.rs | 2 +- .../feature-gate-debugger-visualizer.stderr | 4 +- .../feature-gate-extern_absolute_paths.stderr | 4 + ...gate-infer_static_outlives_requirements.rs | 12 - ...-infer_static_outlives_requirements.stderr | 19 - .../feature-gate-link_cfg.stderr | 6 +- ...re-gate-native_link_modifiers_as_needed.rs | 4 +- ...ate-native_link_modifiers_as_needed.stderr | 8 +- ...ure-gate-native_link_modifiers_bundle-2.rs | 9 - ...ure-gate-native_link_modifiers_bundle-3.rs | 3 - ...gate-native_link_modifiers_bundle-3.stderr | 2 - ...ature-gate-native_link_modifiers_bundle.rs | 5 - ...e-gate-native_link_modifiers_bundle.stderr | 12 - ...ure-gate-native_link_modifiers_verbatim.rs | 2 +- ...gate-native_link_modifiers_verbatim.stderr | 2 +- src/test/ui/feature-gates/feature-gate-nll.rs | 18 - .../ui/feature-gates/feature-gate-nll.stderr | 14 - .../feature-gates/feature-gate-raw-dylib.rs | 2 +- .../feature-gate-raw-dylib.stderr | 6 +- .../feature-gate-rust_cold_cc.rs | 21 + .../feature-gate-rust_cold_cc.stderr | 66 + .../feature-gate-rustdoc_internals.rs | 5 + .../feature-gate-rustdoc_internals.stderr | 11 +- .../feature-gate-static-nobundle-2.rs | 4 - .../feature-gate-static-nobundle-2.stderr | 2 - .../feature-gate-static-nobundle.rs | 6 - .../feature-gate-static-nobundle.stderr | 18 - .../feature-gate-trait_upcasting.stderr | 3 +- ...eature-gate-with_negative_coherence.stderr | 2 +- .../issue-43106-gating-of-builtin-attrs.rs | 5 +- ...issue-43106-gating-of-builtin-attrs.stderr | 372 +- src/test/ui/fmt/format-string-error.stderr | 2 +- src/test/ui/fmt/ifmt-bad-arg.stderr | 20 +- src/test/ui/fn/fn-item-type.stderr | 45 +- ...d-bounds-unnorm-associated-type.nll.stderr | 14 - .../implied-bounds-unnorm-associated-type.rs | 3 +- ...plied-bounds-unnorm-associated-type.stderr | 13 +- .../ui/for-loop-while/label_break_value.rs | 6 +- .../for-loop-while/label_break_value.stderr | 28 - .../label_break_value_invalid.rs | 5 +- .../label_break_value_invalid.stderr | 63 +- ...for-loop-unconstrained-element-type.stderr | 11 +- .../generator/auto-trait-regions.nll.stderr | 47 - src/test/ui/generator/auto-trait-regions.rs | 4 +- .../ui/generator/auto-trait-regions.stderr | 49 +- .../generator/drop-track-addassign-yield.rs | 41 + .../drop-tracking-yielding-in-match-guards.rs | 12 + .../generator-region-requirements.nll.stderr | 11 - .../generator-region-requirements.rs | 2 +- .../generator-region-requirements.stderr | 12 +- src/test/ui/generator/issue-68112.rs | 22 +- src/test/ui/generator/issue-68112.stderr | 41 +- src/test/ui/generator/issue-87142.rs | 32 + src/test/ui/generator/not-send-sync.stderr | 11 +- .../print/generator-print-verbose-1.stderr | 33 +- .../print/generator-print-verbose-2.stderr | 11 +- .../resume-arg-late-bound.nll.stderr | 17 - .../ui/generator/resume-arg-late-bound.rs | 1 - .../ui/generator/resume-arg-late-bound.stderr | 40 +- .../bugs/issue-89352.base.stderr | 22 - .../collectivity-regression.rs | 24 + .../collectivity-regression.stderr | 14 + .../elided-in-expr-position.stderr | 4 +- .../equality-bound.stderr | 4 +- .../extended/lending_iterator.base.nll.stderr | 12 - .../extended/lending_iterator.base.stderr | 16 +- .../extended/lending_iterator.rs | 1 - .../gat-trait-path-parenthesised-args.rs | 5 + .../gat-trait-path-parenthesised-args.stderr | 31 +- .../issue-68648-2.stderr | 9 +- .../generic-associated-types/issue-70304.rs | 2 +- .../issue-70304.stderr | 13 +- .../issue-81862.stderr | 2 +- .../generic-associated-types/issue-86483.rs | 8 +- .../issue-86483.stderr | 50 - .../{bugs => }/issue-89352.rs | 14 +- .../generic-associated-types/issue-91139.rs | 29 +- .../issue-91139.stderr | 62 + .../issue-91762.stderr | 7 +- .../generic-associated-types/issue-92096.rs | 15 +- .../issue-92096.stderr | 8 + .../generic-associated-types/issue-95305.rs | 2 +- .../issue-95305.stderr | 12 +- .../missing-bounds.stderr | 27 +- ...ojection-type-lifetime-mismatch.nll.stderr | 26 - .../projection-type-lifetime-mismatch.rs | 6 +- .../projection-type-lifetime-mismatch.stderr | 31 +- .../generic-associated-types/shadowing.stderr | 32 +- .../trait-objects.extended.nll.stderr | 17 - .../trait-objects.extended.stderr | 15 +- .../generic-associated-types/trait-objects.rs | 2 +- ...alf-open-range-pats-exhaustive-fail.stderr | 340 +- .../hashmap-iter-value-lifetime.stderr | 4 +- .../hrtb-wrong-kind.rs | 7 + .../hrtb-wrong-kind.stderr | 14 + .../issue-59311.nll.stderr | 10 - .../higher-rank-trait-bounds/issue-59311.rs | 4 +- .../issue-59311.stderr | 10 +- ...sue-88586-hr-self-outlives-in-trait-def.rs | 8 +- ...88586-hr-self-outlives-in-trait-def.stderr | 19 - .../normalize-under-binder/issue-56556.rs | 17 + .../issue-71955.migrate.stderr | 77 +- .../normalize-under-binder/issue-71955.rs | 19 +- ...ue-71955.nll.stderr => issue-71955.stderr} | 40 +- .../normalize-under-binder/issue-85455.rs | 4 +- .../normalize-under-binder/issue-85455.stderr | 16 +- .../normalize-under-binder/issue-90875.rs | 31 + ...ound_a_b_ret_a_vs_bound_a_ret_a.nll.stderr | 17 - ...pe.bound_a_b_ret_a_vs_bound_a_ret_a.stderr | 4 +- .../hr-subtype.bound_a_b_vs_bound_a.stderr | 8 - .../hr-subtype.bound_a_vs_bound_a.stderr | 8 - .../hr-subtype.bound_a_vs_bound_b.stderr | 8 - .../hr-subtype.bound_a_vs_free_x.nll.stderr | 17 - .../hr-subtype.bound_a_vs_free_x.stderr | 6 +- ...-subtype.bound_co_a_b_vs_bound_co_a.stderr | 8 - ...ubtype.bound_co_a_co_b_ret_contra_a.stderr | 8 - ...hr-subtype.bound_co_a_vs_bound_co_b.stderr | 8 - ...pe.bound_contra_a_contra_b_ret_co_a.stderr | 8 - ...pe.bound_inv_a_b_vs_bound_inv_a.nll.stderr | 31 - ...ubtype.bound_inv_a_b_vs_bound_inv_a.stderr | 20 +- ...-subtype.bound_inv_a_vs_bound_inv_b.stderr | 8 - ...ubtype.free_inv_x_vs_free_inv_y.nll.stderr | 42 - ...hr-subtype.free_inv_x_vs_free_inv_y.stderr | 69 +- .../hr-subtype.free_x_vs_free_x.stderr | 8 - .../hr-subtype.free_x_vs_free_y.nll.stderr | 19 - .../hr-subtype.free_x_vs_free_y.stderr | 32 +- src/test/ui/hr-subtype/hr-subtype.rs | 29 +- .../ui/hr-subtype/placeholder-pattern-fail.rs | 25 + .../placeholder-pattern-fail.stderr | 12 + src/test/ui/hr-subtype/placeholder-pattern.rs | 18 + .../ui/hrtb/hrtb-conflate-regions.nll.stderr | 20 - src/test/ui/hrtb/hrtb-conflate-regions.rs | 4 +- src/test/ui/hrtb/hrtb-conflate-regions.stderr | 13 +- .../ui/hrtb/hrtb-exists-forall-fn.nll.stderr | 12 - ...ists-forall-trait-contravariant.nll.stderr | 11 - ...b-exists-forall-trait-contravariant.stderr | 2 +- ...b-exists-forall-trait-invariant.nll.stderr | 11 - .../hrtb-exists-forall-trait-invariant.stderr | 2 +- .../ui/hrtb/hrtb-just-for-static.nll.stderr | 28 - src/test/ui/hrtb/hrtb-just-for-static.rs | 6 +- src/test/ui/hrtb/hrtb-just-for-static.stderr | 12 +- .../hrtb/hrtb-perfect-forwarding.nll.stderr | 83 - src/test/ui/hrtb/hrtb-perfect-forwarding.rs | 10 +- .../ui/hrtb/hrtb-perfect-forwarding.stderr | 79 +- src/test/ui/hrtb/issue-30786.migrate.stderr | 53 - src/test/ui/hrtb/issue-30786.rs | 15 +- ...ue-30786.nll.stderr => issue-30786.stderr} | 28 +- src/test/ui/hrtb/issue-46989.nll.stderr | 11 - src/test/ui/hrtb/issue-46989.stderr | 2 +- src/test/ui/hrtb/issue-58451.stderr | 8 +- src/test/ui/hygiene/duplicate_lifetimes.rs | 4 +- .../ui/hygiene/duplicate_lifetimes.stderr | 14 +- src/test/ui/hygiene/hygienic-labels-in-let.rs | 46 +- .../ui/hygiene/hygienic-labels-in-let.stderr | 334 - src/test/ui/hygiene/hygienic-labels.rs | 49 +- src/test/ui/hygiene/hygienic-labels.stderr | 334 - .../ui/{issues => hygiene}/issue-32922.rs | 0 .../dyn-trait.nll.stderr | 16 - .../impl-header-lifetime-elision/dyn-trait.rs | 7 +- .../dyn-trait.stderr | 21 +- src/test/ui/impl-trait/auto-trait-leak2.rs | 18 +- .../ui/impl-trait/auto-trait-leak2.stderr | 32 +- .../bound-normalization-fail.stderr | 6 + .../impl-trait/cross-return-site-inference.rs | 8 +- .../cross-return-site-inference.stderr | 33 +- .../fully-qualified-path-impl-trait.rs | 15 + .../fully-qualified-path-impl-trait.stderr | 9 + .../const-args.rs} | 3 +- .../explicit-generic-args-for-impl.rs | 2 - .../explicit-generic-args-for-impl.stderr | 4 +- .../explicit-generic-args.rs | 2 - .../feature-gate.rs | 7 - .../feature-gate.stderr | 12 - .../issue-87718.rs | 2 - .../not-enough-args.rs | 2 - .../not-enough-args.stderr | 4 +- src/test/ui/impl-trait/fallback_inference.rs | 2 +- .../ui/impl-trait/fallback_inference.stderr | 11 +- .../ui/impl-trait/hidden-type-is-opaque-2.rs | 8 +- .../impl-trait/hidden-type-is-opaque-2.stderr | 12 +- .../impl-trait/impl-generic-mismatch.stderr | 2 +- .../ui/{issues => impl-trait}/issue-46959.rs | 0 .../ui/{issues => impl-trait}/issue-54966.rs | 0 .../{issues => impl-trait}/issue-54966.stderr | 0 .../ui/impl-trait/issues/issue-74282.stderr | 9 +- .../ui/impl-trait/issues/issue-84073.stderr | 7 +- .../ui/impl-trait/issues/issue-86719.stderr | 7 +- .../ui/impl-trait/issues/issue-92305.stderr | 7 +- .../issues/universal-issue-48703.rs | 7 - .../issues/universal-issue-48703.stderr | 12 - ...iversal-turbofish-in-method-issue-50950.rs | 17 - ...sal-turbofish-in-method-issue-50950.stderr | 14 - .../multiple-lifetimes/inverse-bounds.rs | 2 - .../ordinary-bounds-pick-original-elided.rs | 4 +- ...nds-pick-original-type-alias-impl-trait.rs | 2 - .../ordinary-bounds-pick-original.rs | 2 - .../ordinary-bounds-pick-other.rs | 2 - ...t_outlive_least_region_or_bound.nll.stderr | 126 - .../must_outlive_least_region_or_bound.rs | 22 +- .../must_outlive_least_region_or_bound.stderr | 147 +- ...pl-trait-type-through-non-recursive.stderr | 4 +- .../suggest-calling-rpit-closure.rs | 12 + .../suggest-calling-rpit-closure.stderr | 21 + .../ui/impl-trait/type_parameters_captured.rs | 2 +- .../type_parameters_captured.stderr | 6 +- .../ui/impl-trait/universal_wrong_hrtb.stderr | 6 + src/test/ui/imports/import3.stderr | 2 + src/test/ui/imports/issue-1697.stderr | 2 + .../ui/{issues => imports}/issue-24883.rs | 0 .../issue-26873-multifile/A/B.rs | 0 .../issue-26873-multifile/A/C.rs | 0 .../issue-26873-multifile/A/mod.rs | 0 .../compiletest-ignore-dir | 0 .../issue-26873-multifile.rs | 0 .../issue-26873-onefile.rs | 0 .../issue-26873-multifile/mod.rs | 0 src/test/ui/imports/issue-33464.stderr | 6 + src/test/ui/imports/issue-36881.stderr | 2 + src/test/ui/imports/issue-37887.stderr | 2 + .../ui/imports/issue-45829/import-self.stderr | 2 +- src/test/ui/imports/issue-53269.stderr | 2 + src/test/ui/imports/issue-55457.stderr | 2 + src/test/ui/imports/issue-59764.stderr | 15 +- .../ui/{issues => imports}/issue-68103.rs | 0 src/test/ui/imports/tool-mod-child.stderr | 8 + .../ui/imports/unresolved-imports-used.stderr | 8 + .../ui/imports/unused-imports-in-test-mode.rs | 84 + .../unused-imports-in-test-mode.stderr | 122 + src/test/ui/indexing-requires-a-uint.stderr | 9 +- .../ui/inference/ambiguous_type_parameter.rs | 17 + .../inference/ambiguous_type_parameter.stderr | 9 + .../ui/inference/cannot-infer-async.stderr | 10 +- .../cannot-infer-closure-circular.rs | 3 +- .../cannot-infer-closure-circular.stderr | 7 +- src/test/ui/inference/cannot-infer-closure.rs | 2 +- .../ui/inference/cannot-infer-closure.stderr | 10 +- .../cannot-infer-partial-try-return.rs | 3 +- .../cannot-infer-partial-try-return.stderr | 10 +- src/test/ui/inference/deref-suggestion.stderr | 53 +- .../erase-type-params-in-label.stderr | 20 +- src/test/ui/inference/issue-71732.stderr | 8 +- src/test/ui/inference/issue-72616.stderr | 10 +- .../ui/{issues => inference}/issue-72690.rs | 0 .../{issues => inference}/issue-72690.stderr | 89 +- src/test/ui/inference/issue-83606.rs | 2 +- src/test/ui/inference/issue-83606.stderr | 13 +- src/test/ui/inference/issue-86162-1.stderr | 8 +- src/test/ui/inference/issue-86162-2.stderr | 8 +- .../inference/need_type_info/concrete-impl.rs | 16 + .../need_type_info/concrete-impl.stderr | 33 + .../need_type_info/self-ty-in-path.rs | 13 + .../need_type_info/self-ty-in-path.stderr | 14 + .../need_type_info/type-alias-indirect.rs | 18 + .../need_type_info/type-alias-indirect.stderr | 9 + .../ui/inference/need_type_info/type-alias.rs | 36 + .../need_type_info/type-alias.stderr | 15 + .../tutorial-suffix-inference-test.stderr | 27 +- .../inline-const/const-match-pat-generic.rs | 3 +- .../const-match-pat-generic.stderr | 15 +- .../interior-mutability.stderr | 6 +- .../intrinsics/panic-uninitialized-zeroed.rs | 44 +- .../invalid-debugger-visualizer-option.rs | 5 +- .../invalid-debugger-visualizer-option.stderr | 14 +- .../invalid-debugger-visualizer-target.rs | 1 - src/test/ui/issue-94866.rs | 14 + src/test/ui/issue-94866.stderr | 21 + src/test/ui/issues-71798.stderr | 3 + src/test/ui/issues/issue-10291.nll.stderr | 11 - src/test/ui/issues/issue-10291.rs | 3 +- src/test/ui/issues/issue-10291.stderr | 22 +- src/test/ui/issues/issue-10764.stderr | 9 +- src/test/ui/issues/issue-11374.stderr | 14 +- src/test/ui/issues/issue-11515.stderr | 3 +- src/test/ui/issues/issue-11873.stderr | 2 +- src/test/ui/issues/issue-12187-1.stderr | 12 +- src/test/ui/issues/issue-12187-2.stderr | 12 +- src/test/ui/issues/issue-12997-2.stderr | 10 +- src/test/ui/issues/issue-13058.nll.stderr | 12 - src/test/ui/issues/issue-13058.stderr | 4 +- src/test/ui/issues/issue-13359.stderr | 18 +- src/test/ui/issues/issue-1448-2.stderr | 9 +- src/test/ui/issues/issue-15034.nll.stderr | 11 - src/test/ui/issues/issue-15034.stderr | 4 +- src/test/ui/issues/issue-15524.rs | 6 +- src/test/ui/issues/issue-15524.stderr | 65 +- src/test/ui/issues/issue-15783.stderr | 9 +- src/test/ui/issues/issue-16683.nll.stderr | 13 - src/test/ui/issues/issue-16683.rs | 3 +- src/test/ui/issues/issue-16683.stderr | 31 +- src/test/ui/issues/issue-16922.nll.stderr | 15 - src/test/ui/issues/issue-16922.rs | 3 +- src/test/ui/issues/issue-16922.stderr | 9 +- src/test/ui/issues/issue-16939.stderr | 8 +- src/test/ui/issues/issue-16966.stderr | 7 +- src/test/ui/issues/issue-17033.stderr | 9 +- src/test/ui/issues/issue-17252.stderr | 15 +- src/test/ui/issues/issue-17551.stderr | 11 +- src/test/ui/issues/issue-17728.stderr | 39 - src/test/ui/issues/issue-17758.nll.stderr | 13 - src/test/ui/issues/issue-17758.rs | 2 +- src/test/ui/issues/issue-17758.stderr | 31 +- src/test/ui/issues/issue-17905-2.stderr | 4 +- src/test/ui/issues/issue-18159.stderr | 7 +- src/test/ui/issues/issue-18819.stderr | 17 +- src/test/ui/issues/issue-20261.stderr | 4 +- src/test/ui/issues/issue-2151.rs | 4 +- src/test/ui/issues/issue-2151.stderr | 10 +- src/test/ui/issues/issue-22370.stderr | 2 +- src/test/ui/issues/issue-22644.stderr | 7 +- src/test/ui/issues/issue-22706.rs | 2 +- src/test/ui/issues/issue-22706.stderr | 6 +- src/test/ui/issues/issue-23046.stderr | 7 +- src/test/ui/issues/issue-23302-1.stderr | 17 +- src/test/ui/issues/issue-23302-2.stderr | 17 +- src/test/ui/issues/issue-23302-3.stderr | 30 +- src/test/ui/issues/issue-23589.stderr | 10 +- src/test/ui/issues/issue-24036.stderr | 7 +- src/test/ui/issues/issue-24819.stderr | 9 +- src/test/ui/issues/issue-25368.rs | 7 +- src/test/ui/issues/issue-25368.stderr | 14 +- src/test/ui/issues/issue-26094.rs | 4 +- src/test/ui/issues/issue-26094.stderr | 8 +- src/test/ui/issues/issue-26217.nll.stderr | 10 - src/test/ui/issues/issue-26217.rs | 2 +- src/test/ui/issues/issue-26217.stderr | 7 +- src/test/ui/issues/issue-27942.stderr | 8 +- src/test/ui/issues/issue-28472.stderr | 2 +- src/test/ui/issues/issue-2995.stderr | 2 +- src/test/ui/issues/issue-3044.stderr | 11 +- src/test/ui/issues/issue-3099-a.stderr | 2 +- src/test/ui/issues/issue-3099-b.stderr | 2 +- src/test/ui/issues/issue-35241.stderr | 2 +- src/test/ui/issues/issue-35668.stderr | 2 +- src/test/ui/issues/issue-37515.rs | 2 +- src/test/ui/issues/issue-37515.stderr | 2 +- src/test/ui/issues/issue-39848.stderr | 12 +- src/test/ui/issues/issue-40000.nll.stderr | 21 - src/test/ui/issues/issue-40000.rs | 4 +- src/test/ui/issues/issue-40000.stderr | 11 +- src/test/ui/issues/issue-40510-1.stderr | 2 +- src/test/ui/issues/issue-40510-3.stderr | 2 +- src/test/ui/issues/issue-41394.rs | 1 + src/test/ui/issues/issue-41394.stderr | 11 +- src/test/ui/issues/issue-4265.stderr | 2 +- .../issues/issue-43420-no-over-suggest.stderr | 9 +- src/test/ui/issues/issue-43925.rs | 2 +- src/test/ui/issues/issue-43925.stderr | 6 +- src/test/ui/issues/issue-43926.rs | 2 +- src/test/ui/issues/issue-43926.stderr | 2 +- src/test/ui/issues/issue-4517.stderr | 10 +- ...-consider-borrowing-cast-or-binexpr.stderr | 30 +- src/test/ui/issues/issue-46983.nll.stderr | 10 - src/test/ui/issues/issue-46983.rs | 2 +- src/test/ui/issues/issue-46983.stderr | 7 +- src/test/ui/issues/issue-47486.stderr | 9 +- src/test/ui/issues/issue-47646.stderr | 2 +- src/test/ui/issues/issue-48364.stderr | 9 +- src/test/ui/issues/issue-49257.stderr | 4 +- src/test/ui/issues/issue-4935.stderr | 8 +- src/test/ui/issues/issue-5062.stderr | 7 +- src/test/ui/issues/issue-51116.rs | 1 - src/test/ui/issues/issue-51116.stderr | 5 +- src/test/ui/issues/issue-51154.stderr | 9 +- ...1632-try-desugar-incompatible-types.stderr | 2 +- src/test/ui/issues/issue-5216.stderr | 9 +- src/test/ui/issues/issue-5239-1.stderr | 5 - src/test/ui/issues/issue-52533.nll.stderr | 11 - src/test/ui/issues/issue-52533.rs | 2 +- src/test/ui/issues/issue-52533.stderr | 19 +- .../ui/issues/issue-54302-cases.nll.stderr | 38 - src/test/ui/issues/issue-54302-cases.stderr | 8 +- src/test/ui/issues/issue-54943.nll.stderr | 11 - src/test/ui/issues/issue-54943.stderr | 14 +- src/test/ui/issues/issue-54954.rs | 2 + src/test/ui/issues/issue-54954.stderr | 18 +- src/test/ui/issues/issue-55731.nll.stderr | 14 - src/test/ui/issues/issue-55731.stderr | 7 +- src/test/ui/issues/issue-55796.stderr | 53 - src/test/ui/issues/issue-57924.rs | 2 +- src/test/ui/issues/issue-57924.stderr | 6 +- src/test/ui/issues/issue-60989.rs | 4 +- src/test/ui/issues/issue-60989.stderr | 12 +- src/test/ui/issues/issue-61106.stderr | 15 +- src/test/ui/issues/issue-6458-2.stderr | 7 +- src/test/ui/issues/issue-6458-3.stderr | 7 +- src/test/ui/issues/issue-6458.stderr | 9 +- .../issue-64792-bad-unicode-ctor.stderr | 2 +- src/test/ui/issues/issue-65230.stderr | 2 +- src/test/ui/issues/issue-66706.stderr | 2 +- .../issue-68091-unicode-ident-after-if.rs | 9 - .../issue-68091-unicode-ident-after-if.stderr | 20 - src/test/ui/issues/issue-69306.stderr | 45 +- src/test/ui/issues/issue-69455.stderr | 18 +- ...issue-69602-type-err-during-codegen-ice.rs | 1 + ...e-69602-type-err-during-codegen-ice.stderr | 10 +- src/test/ui/issues/issue-69683.stderr | 6 +- ...70724-add_type_neq_err_label-unwrap.stderr | 1 + src/test/ui/issues/issue-75777.nll.stderr | 11 - src/test/ui/issues/issue-75777.rs | 2 +- src/test/ui/issues/issue-75777.stderr | 29 +- src/test/ui/issues/issue-76077.rs | 2 +- src/test/ui/issues/issue-76077.stderr | 4 +- src/test/ui/issues/issue-7813.stderr | 11 +- src/test/ui/issues/issue-86756.stderr | 2 +- src/test/ui/issues/issue-98299.rs | 18 + src/test/ui/issues/issue-98299.stderr | 9 + .../iterators/into-iter-on-arrays-2018.stderr | 2 +- .../ui/{issues => iterators}/issue-28098.rs | 0 .../{issues => iterators}/issue-28098.stderr | 0 src/test/ui/iterators/vec-on-unimplemented.rs | 4 + .../ui/iterators/vec-on-unimplemented.stderr | 20 + src/test/ui/json-multiple.nll.stderr | 1 - src/test/ui/json-options.nll.stderr | 1 - .../keyword-extern-as-identifier-use.stderr | 2 + .../kindck/kindck-impl-type-params.nll.stderr | 103 - src/test/ui/kindck/kindck-impl-type-params.rs | 3 - .../ui/kindck/kindck-impl-type-params.stderr | 37 +- .../ui/kindck/kindck-nonsendable-1.stderr | 6 +- .../ui/kindck/kindck-send-object1.nll.stderr | 32 - src/test/ui/kindck/kindck-send-object1.rs | 1 - src/test/ui/kindck/kindck-send-object1.stderr | 19 +- src/test/ui/let-else/let-else-if.stderr | 3 +- .../lifetimes/bare-trait-object-borrowck.rs | 24 + src/test/ui/lifetimes/bare-trait-object.rs | 25 + src/test/ui/lifetimes/copy_modulo_regions.rs | 2 - .../ui/lifetimes/copy_modulo_regions.stderr | 2 +- .../elided-lifetime-in-path-in-pat.rs | 13 + .../ui/{issues => lifetimes}/issue-17728.rs | 1 - .../issue-17728.stderr} | 2 +- src/test/ui/lifetimes/issue-54378.rs | 26 + .../ui/{issues => lifetimes}/issue-55796.rs | 4 +- .../issue-55796.stderr} | 0 src/test/ui/lifetimes/issue-67498.rs | 21 + .../ui/lifetimes/issue-79187-2.nll.stderr | 77 - src/test/ui/lifetimes/issue-79187-2.rs | 12 +- src/test/ui/lifetimes/issue-79187-2.stderr | 53 +- src/test/ui/lifetimes/issue-79187.nll.stderr | 31 - src/test/ui/lifetimes/issue-79187.rs | 4 +- src/test/ui/lifetimes/issue-79187.stderr | 24 +- .../issue-90170-elision-mismatch.fixed | 6 +- .../issue-90170-elision-mismatch.nll.stderr | 44 - .../lifetimes/issue-90170-elision-mismatch.rs | 6 +- .../issue-90170-elision-mismatch.stderr | 37 +- ...expected-return-static-indirect.nll.stderr | 24 - ...e-90600-expected-return-static-indirect.rs | 3 +- ...600-expected-return-static-indirect.stderr | 26 +- src/test/ui/lifetimes/issue-97193.rs | 9 + src/test/ui/lifetimes/issue-97193.stderr | 28 + src/test/ui/lifetimes/issue-97194.rs | 10 + src/test/ui/lifetimes/issue-97194.stderr | 36 + ...etime-bound-will-change-warning.nll.stderr | 31 - .../lifetime-bound-will-change-warning.rs | 6 +- .../lifetime-bound-will-change-warning.stderr | 48 +- ...-existing-name-if-else-using-impl-3.stderr | 2 +- ...xisting-name-if-else-using-impl.nll.stderr | 13 - ...rn-one-existing-name-if-else-using-impl.rs | 3 +- ...ne-existing-name-if-else-using-impl.stderr | 13 +- ...isting-name-return-type-is-anon.nll.stderr | 13 - ...n-one-existing-name-return-type-is-anon.rs | 3 +- ...e-existing-name-return-type-is-anon.stderr | 13 +- ...-one-existing-name-self-is-anon.nll.stderr | 13 - ...1-return-one-existing-name-self-is-anon.rs | 3 +- ...turn-one-existing-name-self-is-anon.stderr | 13 +- .../ex2a-push-one-existing-name-2.nll.stderr | 11 - .../ex2a-push-one-existing-name-2.stderr | 4 +- ...h-one-existing-name-early-bound.nll.stderr | 12 - ...-push-one-existing-name-early-bound.stderr | 4 +- .../ex2a-push-one-existing-name.nll.stderr | 11 - .../ex2a-push-one-existing-name.stderr | 4 +- .../ex2b-push-no-existing-names.nll.stderr | 12 - .../ex2b-push-no-existing-names.rs | 3 +- .../ex2b-push-no-existing-names.stderr | 11 +- .../ex2c-push-inference-variable.nll.stderr | 15 - .../ex2c-push-inference-variable.rs | 3 +- .../ex2c-push-inference-variable.stderr | 13 +- .../ex2d-push-inference-variable-2.nll.stderr | 15 - .../ex2d-push-inference-variable-2.rs | 3 +- .../ex2d-push-inference-variable-2.stderr | 16 +- .../ex2e-push-inference-variable-3.nll.stderr | 15 - .../ex2e-push-inference-variable-3.rs | 3 +- .../ex2e-push-inference-variable-3.stderr | 16 +- .../ex3-both-anon-regions-2.nll.stderr | 17 - .../ex3-both-anon-regions-2.rs | 3 +- .../ex3-both-anon-regions-2.stderr | 12 +- .../ex3-both-anon-regions-3.nll.stderr | 32 - .../ex3-both-anon-regions-3.rs | 5 +- .../ex3-both-anon-regions-3.stderr | 23 +- ...anon-regions-both-are-structs-2.nll.stderr | 12 - ...x3-both-anon-regions-both-are-structs-2.rs | 3 +- ...oth-anon-regions-both-are-structs-2.stderr | 11 +- ...anon-regions-both-are-structs-3.nll.stderr | 13 - ...x3-both-anon-regions-both-are-structs-3.rs | 3 +- ...oth-anon-regions-both-are-structs-3.stderr | 12 +- ...-are-structs-earlybound-regions.nll.stderr | 15 - ...ons-both-are-structs-earlybound-regions.rs | 3 +- ...both-are-structs-earlybound-regions.stderr | 13 +- ...h-are-structs-latebound-regions.nll.stderr | 14 - ...ions-both-are-structs-latebound-regions.rs | 3 +- ...-both-are-structs-latebound-regions.stderr | 13 +- ...h-anon-regions-both-are-structs.nll.stderr | 12 - .../ex3-both-anon-regions-both-are-structs.rs | 3 +- ...-both-anon-regions-both-are-structs.stderr | 11 +- ...-anon-regions-latebound-regions.nll.stderr | 14 - ...ex3-both-anon-regions-latebound-regions.rs | 3 +- ...both-anon-regions-latebound-regions.stderr | 13 +- ...th-anon-regions-one-is-struct-2.nll.stderr | 21 - .../ex3-both-anon-regions-one-is-struct-2.rs | 4 +- ...3-both-anon-regions-one-is-struct-2.stderr | 24 +- ...th-anon-regions-one-is-struct-3.nll.stderr | 12 - .../ex3-both-anon-regions-one-is-struct-3.rs | 3 +- ...3-both-anon-regions-one-is-struct-3.stderr | 11 +- ...th-anon-regions-one-is-struct-4.nll.stderr | 12 - .../ex3-both-anon-regions-one-is-struct-4.rs | 3 +- ...3-both-anon-regions-one-is-struct-4.stderr | 11 +- ...both-anon-regions-one-is-struct.nll.stderr | 12 - .../ex3-both-anon-regions-one-is-struct.rs | 3 +- ...ex3-both-anon-regions-one-is-struct.stderr | 11 +- ...non-regions-return-type-is-anon.nll.stderr | 17 - ...3-both-anon-regions-return-type-is-anon.rs | 3 +- ...th-anon-regions-return-type-is-anon.stderr | 12 +- ...-both-anon-regions-self-is-anon.nll.stderr | 17 - .../ex3-both-anon-regions-self-is-anon.rs | 3 +- .../ex3-both-anon-regions-self-is-anon.stderr | 12 +- ...oth-anon-regions-using-fn-items.nll.stderr | 26 - .../ex3-both-anon-regions-using-fn-items.rs | 4 +- ...x3-both-anon-regions-using-fn-items.stderr | 23 +- ...h-anon-regions-using-impl-items.nll.stderr | 17 - .../ex3-both-anon-regions-using-impl-items.rs | 3 +- ...-both-anon-regions-using-impl-items.stderr | 12 +- ...non-regions-using-trait-objects.nll.stderr | 26 - ...3-both-anon-regions-using-trait-objects.rs | 4 +- ...th-anon-regions-using-trait-objects.stderr | 27 +- .../ex3-both-anon-regions.nll.stderr | 17 - .../lifetime-errors/ex3-both-anon-regions.rs | 3 +- .../ex3-both-anon-regions.stderr | 12 +- .../lifetime-errors/issue_74400.nll.stderr | 38 - .../lifetimes/lifetime-errors/issue_74400.rs | 5 +- .../lifetime-errors/issue_74400.stderr | 31 +- src/test/ui/lifetimes/re-empty-in-error.rs | 10 + .../ui/lifetimes/re-empty-in-error.stderr | 10 + .../ui/linkage-attr/bad-extern-link-attrs.rs | 7 - .../linkage-attr/bad-extern-link-attrs.stderr | 24 - .../link-attr-validation-early.rs | 8 + .../link-attr-validation-early.stderr | 21 + .../linkage-attr/link-attr-validation-late.rs | 40 + .../link-attr-validation-late.stderr | 147 + src/test/ui/lint/dead-code/basic.rs | 2 +- src/test/ui/lint/dead-code/basic.stderr | 2 +- src/test/ui/lint/dead-code/const-and-self.rs | 4 +- .../ui/lint/dead-code/const-and-self.stderr | 15 +- .../ui/lint/dead-code/empty-unused-enum.rs | 2 +- .../lint/dead-code/empty-unused-enum.stderr | 2 +- src/test/ui/lint/dead-code/impl-trait.rs | 2 +- src/test/ui/lint/dead-code/impl-trait.stderr | 2 +- src/test/ui/lint/dead-code/issue-85255.rs | 29 +- src/test/ui/lint/dead-code/issue-85255.stderr | 60 +- .../ui/lint/dead-code/lint-dead-code-1.rs | 20 +- .../ui/lint/dead-code/lint-dead-code-1.stderr | 23 +- .../ui/lint/dead-code/lint-dead-code-2.rs | 6 +- .../ui/lint/dead-code/lint-dead-code-2.stderr | 6 +- .../ui/lint/dead-code/lint-dead-code-3.rs | 10 +- .../ui/lint/dead-code/lint-dead-code-3.stderr | 10 +- .../ui/lint/dead-code/lint-dead-code-4.rs | 20 +- .../ui/lint/dead-code/lint-dead-code-4.stderr | 54 +- .../ui/lint/dead-code/lint-dead-code-5.rs | 8 +- .../ui/lint/dead-code/lint-dead-code-5.stderr | 18 +- .../ui/lint/dead-code/lint-dead-code-6.rs | 8 +- .../ui/lint/dead-code/lint-dead-code-6.stderr | 8 +- .../multiple-dead-codes-in-the-same-struct.rs | 29 + ...tiple-dead-codes-in-the-same-struct.stderr | 55 + src/test/ui/lint/dead-code/newline-span.rs | 6 +- .../ui/lint/dead-code/newline-span.stderr | 6 +- src/test/ui/lint/dead-code/type-alias.rs | 2 +- src/test/ui/lint/dead-code/type-alias.stderr | 2 +- src/test/ui/lint/dead-code/unused-enum.rs | 7 +- src/test/ui/lint/dead-code/unused-enum.stderr | 6 +- .../lint/dead-code/unused-struct-variant.rs | 2 +- .../dead-code/unused-struct-variant.stderr | 5 +- src/test/ui/lint/dead-code/unused-variant.rs | 2 +- .../ui/lint/dead-code/unused-variant.stderr | 11 +- src/test/ui/lint/dead-code/with-core-crate.rs | 2 +- .../ui/lint/dead-code/with-core-crate.stderr | 2 +- src/test/ui/lint/forbid-group-member.stderr | 6 +- src/test/ui/lint/forbid-member-group.stderr | 4 +- src/test/ui/lint/force-warn/allow-warnings.rs | 2 +- .../ui/lint/force-warn/allow-warnings.stderr | 2 +- .../allowed-group-warn-by-default-lint.stderr | 6 +- .../allowed-warn-by-default-lint.rs | 2 +- .../allowed-warn-by-default-lint.stderr | 2 +- .../ui/lint/force-warn/cap-lints-allow.stderr | 6 +- ...up-allowed-cli-warn-by-default-lint.stderr | 6 +- .../lint-group-allowed-lint-group.stderr | 6 +- ...-group-allowed-warn-by-default-lint.stderr | 6 +- .../warn-by-default-lint-two-modules.rs | 4 +- .../warn-by-default-lint-two-modules.stderr | 4 +- src/test/ui/lint/issue-17718-const-naming.rs | 2 +- .../ui/lint/issue-17718-const-naming.stderr | 2 +- src/test/ui/{issues => lint}/issue-35075.rs | 0 .../ui/{issues => lint}/issue-35075.stderr | 0 src/test/ui/lint/issue-80988.stderr | 6 +- .../ui/lint/issue-97094.interleaved.stderr | 53 + .../ui/lint/issue-97094.nointerleaved.stderr | 53 + src/test/ui/lint/issue-97094.rs | 59 + src/test/ui/lint/lint-forbid-attr.stderr | 4 +- .../lint-incoherent-auto-trait-objects.stderr | 4 +- .../ui/lint/lint-unknown-feature-default.rs | 7 +- src/test/ui/lint/lint-unknown-feature.rs | 5 +- .../ui/lint/lint-unnecessary-parens.stderr | 34 +- src/test/ui/lint/lint-unsafe-code.rs | 3 + src/test/ui/lint/lint-unsafe-code.stderr | 48 +- src/test/ui/lint/must_not_suspend/ref.stderr | 2 +- .../ui/lint/must_not_suspend/trait.stderr | 2 +- src/test/ui/lint/no-coverage.rs | 55 + src/test/ui/lint/no-coverage.stderr | 101 + src/test/ui/lint/reasons-erroneous.stderr | 16 +- .../ui/lint/renamed-lints-still-apply.stderr | 2 +- .../avoid_delayed_good_path_ice.rs | 8 + .../expect_on_fn_params.rs | 15 + .../expect_on_fn_params.stderr | 10 + .../force_warn_expected_lints_fulfilled.rs | 48 + ...force_warn_expected_lints_fulfilled.stderr | 40 + .../force_warn_expected_lints_unfulfilled.rs | 49 + ...rce_warn_expected_lints_unfulfilled.stderr | 38 + src/test/ui/lint/suggestions.stderr | 2 +- src/test/ui/lint/unnecessary-extern-crate.rs | 4 +- src/test/ui/lint/unreachable_pub-pub_crate.rs | 72 - .../ui/lint/unreachable_pub-pub_crate.stderr | 148 - src/test/ui/lint/unreachable_pub.rs | 10 +- src/test/ui/lint/unreachable_pub.stderr | 58 +- .../issue-54538-unused-parens-lint.stderr | 48 +- ...ssue-74883-unused-paren-baren-yield.stderr | 12 +- .../issue-90807-unused-paren-error.stderr | 4 +- .../unused-macro-rules-compile-error.rs | 27 + .../unused-macro-rules-compile-error.stderr | 26 + .../unused-macro-rules-malformed-rule.rs | 11 + .../unused-macro-rules-malformed-rule.stderr | 8 + .../unused/unused-macros-malformed-rule.rs | 15 + .../unused-macros-malformed-rule.stderr | 26 + src/test/ui/lint/unused_braces.stderr | 10 +- src/test/ui/lint/unused_braces_borrow.stderr | 2 +- src/test/ui/lint/unused_labels.stderr | 18 +- .../lint/unused_parens_json_suggestion.stderr | 2 +- ...nused_parens_remove_json_suggestion.stderr | 18 +- .../liveness/liveness-use-after-move.stderr | 2 +- .../loops/loops-reject-duplicate-labels-2.rs | 36 - .../loops-reject-duplicate-labels-2.stderr | 74 - .../ui/loops/loops-reject-duplicate-labels.rs | 49 - .../loops-reject-duplicate-labels.stderr | 74 - ...loops-reject-labels-shadowing-lifetimes.rs | 109 - ...s-reject-labels-shadowing-lifetimes.stderr | 104 - .../loops-reject-lifetime-shadowing-label.rs | 36 - ...ops-reject-lifetime-shadowing-label.stderr | 18 - src/test/ui/{issues => lto}/issue-11154.rs | 0 .../ui/{issues => lto}/issue-11154.stderr | 0 .../ui/lub-glb/empty-binder-future-compat.rs | 22 + src/test/ui/lub-glb/empty-binders-err.rs | 55 + src/test/ui/lub-glb/empty-binders-err.stderr | 59 + src/test/ui/lub-glb/empty-binders.rs | 45 + .../old-lub-glb-hr-noteq1.baseleak.stderr | 21 + ...> old-lub-glb-hr-noteq1.basenoleak.stderr} | 2 +- ...derr => old-lub-glb-hr-noteq1.leak.stderr} | 4 +- .../old-lub-glb-hr-noteq1.nllleak.stderr | 2 + .../old-lub-glb-hr-noteq1.nllnoleak.stderr | 2 + .../old-lub-glb-hr-noteq1.noleak.stderr | 12 + src/test/ui/lub-glb/old-lub-glb-hr-noteq1.rs | 7 +- ...derr => old-lub-glb-hr-noteq2.leak.stderr} | 3 +- src/test/ui/lub-glb/old-lub-glb-hr-noteq2.rs | 19 +- .../ui/lub-glb/old-lub-glb-object.nll.stderr | 21 - src/test/ui/lub-glb/old-lub-glb-object.rs | 3 +- src/test/ui/lub-glb/old-lub-glb-object.stderr | 22 +- src/test/ui/macros/assert-trailing-junk.rs | 3 + ...t-trailing-junk.with-generic-asset.stderr} | 14 +- ...trailing-junk.without-generic-asset.stderr | 54 + src/test/ui/macros/assert.rs | 3 + ...tderr => assert.with-generic-asset.stderr} | 8 +- .../assert.without-generic-asset.stderr | 28 + src/test/ui/macros/cfg.rs | 1 + src/test/ui/macros/cfg.stderr | 10 +- .../macros/format-args-temporaries-async.rs | 37 + .../format-args-temporaries-in-write.rs | 50 + .../format-args-temporaries-in-write.stderr | 43 + src/test/ui/macros/format-args-temporaries.rs | 54 + src/test/ui/macros/issue-29084.stderr | 12 +- src/test/ui/{issues => macros}/issue-33185.rs | 0 src/test/ui/{issues => macros}/issue-8851.rs | 0 .../macros/macro-lifetime-used-with-labels.rs | 2 +- .../macro-lifetime-used-with-labels.stderr | 15 - .../ui/macros/macro-outer-attributes.stderr | 2 +- src/test/ui/macros/macro-pub-matcher.rs | 19 +- .../all-expr-kinds.rs | 185 + .../all-not-available-cases.rs | 43 + ...errors-does-not-create-unnecessary-code.rs | 13 + ...ptures-does-not-create-unnecessary-code.rs | 14 + .../auxiliary/common.rs | 25 + .../rfc-2011-nicer-assert-messages/codegen.rs | 9 + .../codegen.stdout | 29 + .../feature-gate-generic_assert.rs | 26 + src/test/ui/macros/stringify.rs | 4 +- src/test/ui/main-wrong-location.stderr | 2 +- src/test/ui/manual/manual-link-bad-form.rs | 2 +- .../ui/manual/manual-link-bad-form.stderr | 4 +- src/test/ui/manual/manual-link-bad-kind.rs | 2 +- .../ui/manual/manual-link-bad-kind.stderr | 2 +- src/test/ui/manual/manual-link-framework.rs | 2 +- .../ui/manual/manual-link-framework.stderr | 2 +- .../ui/manual/manual-link-unsupported-kind.rs | 2 +- .../manual-link-unsupported-kind.stderr | 2 +- src/test/ui/{issues => match}/issue-11319.rs | 0 .../ui/{issues => match}/issue-11319.stderr | 0 src/test/ui/{issues => match}/issue-27021.rs | 0 .../issue-46920-byte-array-patterns.rs | 0 .../match/match-ref-mut-invariance.nll.stderr | 17 - src/test/ui/match/match-ref-mut-invariance.rs | 3 +- .../ui/match/match-ref-mut-invariance.stderr | 27 +- .../match-ref-mut-let-invariance.nll.stderr | 18 - .../ui/match/match-ref-mut-let-invariance.rs | 3 +- .../match/match-ref-mut-let-invariance.stderr | 26 +- src/test/ui/match/match-tag-nullary.stderr | 2 +- .../ui/match/match-unresolved-one-arm.stderr | 7 +- .../meta-expected-error-wrong-rev.a.stderr | 2 +- .../ui/meta/meta-expected-error-wrong-rev.rs | 1 - ...od-ambig-one-trait-unknown-int-type.stderr | 11 +- .../ui/methods/method-call-err-msg.stderr | 32 +- .../method-on-ambiguous-numeric-type.stderr | 1 + src/test/ui/methods/method-self-arg-1.stderr | 24 +- .../ui/mir/ssa-analysis-regression-50041.rs | 18 +- .../ui/mismatched_types/cast-rfc0401.stderr | 11 +- .../closure-arg-type-mismatch.nll.stderr | 45 - .../closure-arg-type-mismatch.rs | 4 - .../closure-arg-type-mismatch.stderr | 61 +- .../closure-mismatch.nll.stderr | 31 - .../ui/mismatched_types/closure-mismatch.rs | 4 +- .../mismatched_types/closure-mismatch.stderr | 17 +- .../ui/mismatched_types/issue-26480.stderr | 7 + .../ui/mismatched_types/issue-35030.stderr | 9 +- .../mismatched_types/issue-38371-unfixable.rs | 5 + .../issue-38371-unfixable.stderr | 21 + .../ui/mismatched_types/issue-38371.fixed | 18 + src/test/ui/mismatched_types/issue-38371.rs | 29 +- .../ui/mismatched_types/issue-38371.stderr | 45 +- .../numeric-literal-cast.stderr | 27 +- .../mismatched_types/overloaded-calls-bad.rs | 8 +- .../overloaded-calls-bad.stderr | 40 +- .../ref-pat-suggestions.fixed | 24 + .../mismatched_types/ref-pat-suggestions.rs | 24 + .../ref-pat-suggestions.stderr | 297 + .../trait-bounds-cant-coerce.stderr | 9 +- src/test/ui/missing/missing-block-hint.stderr | 17 +- .../missing-type-parameter.stderr | 7 +- .../missing-type-parameter2.stderr | 2 +- src/test/ui/mod-subitem-as-enum-variant.rs | 2 +- .../ui/mod-subitem-as-enum-variant.stderr | 6 +- .../use_of_moved_value_copy_suggestions.fixed | 10 +- ...use_of_moved_value_copy_suggestions.stderr | 10 +- src/test/ui/mut/mut-cross-borrowing.stderr | 14 +- src/test/ui/namespace/namespace-mix.stderr | 8 +- .../native-library-link-flags/empty-kind-1.rs | 2 +- .../empty-kind-1.stderr | 2 +- .../native-library-link-flags/empty-kind-2.rs | 2 +- .../empty-kind-2.stderr | 2 +- .../mix-bundle-and-whole-archive-link-attr.rs | 2 - .../modifiers-override-2.stderr | 2 +- .../modifiers-override.rs | 7 +- .../modifiers-override.stderr | 24 +- .../call-fn-never-arg-wrong-type.stderr | 9 +- .../diverging-tuple-parts-39485.stderr | 2 +- src/test/ui/never_type/issue-52443.stderr | 2 +- src/test/ui/never_type/issue-96335.stderr | 10 +- src/test/ui/nll/capture-ref-in-struct.stderr | 2 +- .../escape-argument-callee.rs | 2 +- .../closure-requirements/escape-argument.rs | 2 +- .../escape-argument.stderr | 2 +- .../escape-upvar-nested.rs | 2 +- .../escape-upvar-nested.stderr | 2 +- .../closure-requirements/escape-upvar-ref.rs | 2 +- .../escape-upvar-ref.stderr | 2 +- .../propagate-approximated-fail-no-postdom.rs | 2 +- .../propagate-approximated-ref.rs | 2 +- ...horter-to-static-comparing-against-free.rs | 2 +- ...er-to-static-comparing-against-free.stderr | 15 +- ...approximated-shorter-to-static-no-bound.rs | 2 +- ...roximated-shorter-to-static-wrong-bound.rs | 2 +- .../propagate-approximated-val.rs | 2 +- .../propagate-despite-same-free-region.rs | 2 +- ...te-fail-to-approximate-longer-no-bounds.rs | 2 +- ...fail-to-approximate-longer-wrong-bounds.rs | 2 +- .../propagate-from-trait-match.rs | 2 +- ...region-lbr-anon-does-not-outlive-static.rs | 2 +- ...egion-lbr-named-does-not-outlive-static.rs | 2 +- .../region-lbr1-does-not-outlive-ebr2.rs | 2 +- ...does-outlive-lbr2-because-implied-bound.rs | 2 +- .../return-wrong-bound-region.rs | 2 +- src/test/ui/nll/constant.rs | 1 - .../continue-after-missing-main.nll.stderr | 9 - .../ui/nll/continue-after-missing-main.rs | 1 - .../ui/nll/continue-after-missing-main.stderr | 16 +- src/test/ui/nll/drop-may-dangle.rs | 1 - src/test/ui/nll/drop-no-may-dangle.rs | 2 - src/test/ui/nll/drop-no-may-dangle.stderr | 4 +- src/test/ui/nll/extra-unused-mut.rs | 2 +- .../ui/nll/generator-distinct-lifetime.rs | 2 +- src/test/ui/nll/generator-upvar-mutability.rs | 2 +- src/test/ui/nll/guarantor-issue-46974.rs | 2 - src/test/ui/nll/guarantor-issue-46974.stderr | 4 +- ...issue-27282-move-match-input-into-guard.rs | 0 ...e-27282-move-match-input-into-guard.stderr | 0 .../issue-27282-move-ref-mut-into-guard.rs | 0 ...issue-27282-move-ref-mut-into-guard.stderr | 0 ...sue-27282-mutate-before-diverging-arm-1.rs | 0 ...27282-mutate-before-diverging-arm-1.stderr | 0 ...sue-27282-mutate-before-diverging-arm-2.rs | 0 ...27282-mutate-before-diverging-arm-2.stderr | 0 ...sue-27282-mutate-before-diverging-arm-3.rs | 0 ...27282-mutate-before-diverging-arm-3.stderr | 0 .../issue-27282-mutation-in-guard.rs | 0 .../issue-27282-mutation-in-guard.stderr | 0 .../issue-27282-reborrow-ref-mut-in-guard.rs | 0 ...sue-27282-reborrow-ref-mut-in-guard.stderr | 0 ...ssue-42574-diagnostic-in-nested-closure.rs | 2 - ...-42574-diagnostic-in-nested-closure.stderr | 4 +- .../nll/issue-45696-no-variant-box-recur.rs | 3 - src/test/ui/{issues => nll}/issue-46023.rs | 0 .../ui/{issues => nll}/issue-46023.stderr | 0 src/test/ui/nll/issue-48070.rs | 1 - src/test/ui/nll/issue-50716.base.stderr | 18 - src/test/ui/nll/issue-50716.rs | 4 - ...ue-50716.nll.stderr => issue-50716.stderr} | 2 +- src/test/ui/nll/issue-51770.rs | 1 - src/test/ui/{issues => nll}/issue-52057.rs | 0 src/test/ui/nll/issue-52113.rs | 2 - src/test/ui/nll/issue-52113.stderr | 2 +- src/test/ui/nll/issue-52213.nll.stderr | 15 - src/test/ui/nll/issue-52213.rs | 3 +- src/test/ui/nll/issue-52213.stderr | 33 +- src/test/ui/nll/issue-52533-1.nll.stderr | 11 - src/test/ui/nll/issue-52533-1.rs | 2 +- src/test/ui/nll/issue-52533-1.stderr | 21 +- src/test/ui/nll/issue-52534-2.stderr | 2 +- src/test/ui/nll/issue-52742.base.stderr | 20 - src/test/ui/nll/issue-52742.rs | 5 - ...ue-52742.nll.stderr => issue-52742.stderr} | 4 +- ...sue-54382-use-span-of-tail-of-block.stderr | 2 +- ...ssue-54556-temps-in-tail-diagnostic.stderr | 2 +- .../nll/issue-54779-anon-static-lifetime.rs | 2 - .../issue-54779-anon-static-lifetime.stderr | 2 +- src/test/ui/nll/issue-54943-3.rs | 1 - src/test/ui/nll/issue-55394.base.stderr | 32 - src/test/ui/nll/issue-55394.rs | 4 - ...ue-55394.nll.stderr => issue-55394.stderr} | 2 +- src/test/ui/nll/issue-55401.base.stderr | 16 - src/test/ui/nll/issue-55401.rs | 4 - ...ue-55401.nll.stderr => issue-55401.stderr} | 2 +- src/test/ui/nll/issue-55825-const-fn.rs | 2 - src/test/ui/nll/issue-57280-1-flipped.rs | 23 + src/test/ui/nll/issue-57280-1-flipped.stderr | 11 + .../nll/issue-57642-higher-ranked-subtype.rs | 3 - .../issue-57642-higher-ranked-subtype.stderr | 8 +- src/test/ui/nll/issue-58053.rs | 2 - src/test/ui/nll/issue-58053.stderr | 4 +- src/test/ui/nll/issue-58299.rs | 2 - src/test/ui/nll/issue-58299.stderr | 4 +- src/test/ui/nll/issue-67007-escaping-data.rs | 2 - .../ui/nll/issue-67007-escaping-data.stderr | 2 +- src/test/ui/nll/issue-73159-rpit-static.rs | 2 - .../ui/nll/issue-73159-rpit-static.stderr | 2 +- src/test/ui/nll/issue-95272.rs | 2 - src/test/ui/nll/issue-95272.stderr | 2 +- src/test/ui/nll/issue-97997.rs | 16 + src/test/ui/nll/issue-97997.stderr | 20 + src/test/ui/nll/issue-98170.rs | 25 + src/test/ui/nll/issue-98170.stderr | 44 + src/test/ui/nll/issue-98693.rs | 21 + .../issue-98693.stderr} | 13 +- src/test/ui/nll/lint-no-err.rs | 5 - src/test/ui/nll/lub-if.base.stderr | 29 - src/test/ui/nll/lub-if.rs | 10 +- .../nll/{lub-if.nll.stderr => lub-if.stderr} | 4 +- src/test/ui/nll/lub-match.base.stderr | 29 - src/test/ui/nll/lub-match.rs | 10 +- ...{lub-match.nll.stderr => lub-match.stderr} | 4 +- src/test/ui/nll/match-cfg-fake-edges2.rs | 2 - src/test/ui/nll/match-cfg-fake-edges2.stderr | 2 +- .../maybe-initialized-drop-uninitialized.rs | 1 - .../maybe-initialized-drop-with-fragment.rs | 2 - ...aybe-initialized-drop-with-fragment.stderr | 2 +- ...lized-drop-with-uninitialized-fragments.rs | 2 - ...d-drop-with-uninitialized-fragments.stderr | 2 +- src/test/ui/nll/maybe-initialized-drop.rs | 2 - src/test/ui/nll/maybe-initialized-drop.stderr | 2 +- src/test/ui/nll/mir_check_cast_closure.rs | 2 - src/test/ui/nll/mir_check_cast_closure.stderr | 2 +- src/test/ui/nll/mir_check_cast_reify.rs | 2 - src/test/ui/nll/mir_check_cast_reify.stderr | 2 +- src/test/ui/nll/mir_check_cast_unsafe_fn.rs | 2 - .../ui/nll/mir_check_cast_unsafe_fn.stderr | 2 +- src/test/ui/nll/mir_check_cast_unsize.rs | 2 - src/test/ui/nll/mir_check_cast_unsize.stderr | 2 +- src/test/ui/nll/outlives-suggestion-more.rs | 2 - .../ui/nll/outlives-suggestion-more.stderr | 14 +- src/test/ui/nll/outlives-suggestion-simple.rs | 2 - .../ui/nll/outlives-suggestion-simple.stderr | 18 +- .../ui/nll/polonius/assignment-kills-loans.rs | 3 +- .../polonius/assignment-to-differing-field.rs | 3 +- .../assignment-to-differing-field.stderr | 8 +- src/test/ui/nll/polonius/call-kills-loans.rs | 3 +- src/test/ui/nll/polonius/issue-46589.rs | 3 +- .../ui/nll/polonius/polonius-smoke-test.rs | 3 +- .../nll/polonius/polonius-smoke-test.stderr | 8 +- .../nll/polonius/storagedead-kills-loans.rs | 3 +- src/test/ui/nll/polonius/subset-relations.rs | 3 +- .../ui/nll/polonius/subset-relations.stderr | 2 +- src/test/ui/nll/projection-return.rs | 1 - src/test/ui/nll/relate_tys/fn-subtype.rs | 2 - src/test/ui/nll/relate_tys/fn-subtype.stderr | 2 +- .../ui/nll/relate_tys/hr-fn-aaa-as-aba.rs | 2 - .../ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr | 4 +- .../ui/nll/relate_tys/hr-fn-aau-eq-abu.rs | 2 - .../ui/nll/relate_tys/hr-fn-aba-as-aaa.rs | 2 - .../impl-fn-ignore-binder-via-bottom.rs | 6 +- .../impl-fn-ignore-binder-via-bottom.stderr | 4 +- src/test/ui/nll/relate_tys/opaque-hrtb.rs | 2 - src/test/ui/nll/relate_tys/opaque-hrtb.stderr | 2 +- src/test/ui/nll/relate_tys/trait-hrtb.rs | 2 - src/test/ui/nll/relate_tys/trait-hrtb.stderr | 2 +- .../ui/nll/relate_tys/universe-violation.rs | 2 - .../nll/relate_tys/universe-violation.stderr | 2 +- src/test/ui/nll/snocat-regression.rs | 16 + src/test/ui/nll/snocat-regression.stderr | 14 + .../ui/nll/ty-outlives/impl-trait-captures.rs | 2 +- .../ui/nll/ty-outlives/impl-trait-outlives.rs | 2 +- .../ty-outlives/projection-implied-bounds.rs | 2 +- .../projection-no-regions-closure.rs | 2 +- .../ty-outlives/projection-no-regions-fn.rs | 2 +- .../projection-one-region-closure.rs | 2 +- ...ojection-one-region-trait-bound-closure.rs | 2 +- ...n-one-region-trait-bound-static-closure.rs | 2 +- ...ojection-two-region-trait-bound-closure.rs | 2 +- ...on-where-clause-env-wrong-bound.nll.stderr | 12 - ...ection-where-clause-env-wrong-bound.stderr | 11 +- ...where-clause-env-wrong-lifetime.nll.stderr | 12 - ...jection-where-clause-env-wrong-lifetime.rs | 2 +- ...ion-where-clause-env-wrong-lifetime.stderr | 11 +- .../projection-where-clause-none.rs | 2 - .../projection-where-clause-none.stderr | 2 +- .../projection-where-clause-trait.rs | 2 - ...y-param-closure-approximate-lower-bound.rs | 2 +- ...param-closure-outlives-from-return-type.rs | 2 +- ...aram-closure-outlives-from-where-clause.rs | 2 +- .../ui/nll/ty-outlives/ty-param-fn-body.rs | 2 - .../nll/ty-outlives/ty-param-fn-body.stderr | 2 +- src/test/ui/nll/ty-outlives/ty-param-fn.rs | 2 - .../ui/nll/ty-outlives/ty-param-fn.stderr | 4 +- .../ty-outlives/ty-param-implied-bounds.rs | 2 +- src/test/ui/nll/ty-outlives/wf-unreachable.rs | 2 - .../ui/nll/ty-outlives/wf-unreachable.stderr | 16 +- .../nll/type-alias-free-regions.base.stderr | 65 - src/test/ui/nll/type-alias-free-regions.rs | 4 - ....stderr => type-alias-free-regions.stderr} | 4 +- .../ui/nll/type-check-pointer-coercions.rs | 2 - .../nll/type-check-pointer-coercions.stderr | 16 +- .../ui/nll/type-check-pointer-comparisons.rs | 2 - .../nll/type-check-pointer-comparisons.stderr | 12 +- src/test/ui/nll/type-test-universe.rs | 21 + src/test/ui/nll/type-test-universe.stderr | 16 + .../user-annotations/adt-nullary-enums.stderr | 16 +- .../ui/nll/user-annotations/closure-substs.rs | 2 - .../user-annotations/closure-substs.stderr | 8 +- .../constant-in-expr-inherent-1.base.stderr | 11 - .../constant-in-expr-inherent-1.rs | 4 - ...err => constant-in-expr-inherent-1.stderr} | 2 +- .../constant-in-expr-normalize.base.stderr | 16 - .../constant-in-expr-normalize.rs | 4 - ...derr => constant-in-expr-normalize.stderr} | 2 +- .../constant-in-expr-trait-item-1.base.stderr | 16 - .../constant-in-expr-trait-item-1.rs | 4 - ...r => constant-in-expr-trait-item-1.stderr} | 2 +- .../constant-in-expr-trait-item-2.base.stderr | 16 - .../constant-in-expr-trait-item-2.rs | 4 - ...r => constant-in-expr-trait-item-2.stderr} | 2 +- .../constant-in-expr-trait-item-3.base.stderr | 28 - .../constant-in-expr-trait-item-3.rs | 4 - ...r => constant-in-expr-trait-item-3.stderr} | 2 +- .../user-annotations/dump-adt-brace-struct.rs | 1 - .../dump-adt-brace-struct.stderr | 2 +- .../ui/nll/user-annotations/dump-fn-method.rs | 1 - .../user-annotations/dump-fn-method.stderr | 8 +- .../inherent-associated-constants.rs | 2 - .../inherent-associated-constants.stderr | 2 +- .../ui/nll/user-annotations/issue-54124.rs | 2 - .../nll/user-annotations/issue-54124.stderr | 4 +- ...ssue-55748-pat-types-constrain-bindings.rs | 2 - ...-55748-pat-types-constrain-bindings.stderr | 6 +- .../issue-57731-ascibed-coupled-types.rs | 2 +- .../method-ufcs-inherent-1.rs | 2 - .../method-ufcs-inherent-1.stderr | 2 +- .../method-ufcs-inherent-3.rs | 2 - .../method-ufcs-inherent-3.stderr | 2 +- src/test/ui/nll/user-annotations/patterns.rs | 2 - .../ui/nll/user-annotations/patterns.stderr | 38 +- .../ui/nll/user-annotations/wf-self-type.rs | 2 - .../nll/user-annotations/wf-self-type.stderr | 2 +- src/test/ui/nll/vimwiki-core-regression.rs | 37 + src/test/ui/nll/where_clauses_in_functions.rs | 2 - .../ui/nll/where_clauses_in_functions.stderr | 2 +- src/test/ui/nll/where_clauses_in_structs.rs | 2 - .../ui/nll/where_clauses_in_structs.stderr | 2 +- src/test/ui/no-capture-arc.stderr | 2 +- src/test/ui/no-reuse-move-arc.stderr | 2 +- src/test/ui/no-send-res-ports.stderr | 11 +- src/test/ui/non-fmt-panic.stderr | 8 +- src/test/ui/not-clone-closure.stderr | 11 +- src/test/ui/not-enough-arguments.stderr | 16 +- .../integer-literal-suffix-inference.stderr | 468 +- src/test/ui/numeric/len.stderr | 9 +- .../numeric-cast-without-suggestion.stderr | 210 +- src/test/ui/numeric/numeric-cast.stderr | 1017 ++- .../numeric-suffix/numeric-suffix-i32.fixed | 33 + .../numeric-suffix/numeric-suffix-i32.rs | 33 + .../numeric-suffix/numeric-suffix-i32.stderr | 121 +- .../numeric-suffix/numeric-suffix-i64.fixed | 33 + .../numeric-suffix/numeric-suffix-i64.rs | 33 + .../numeric-suffix/numeric-suffix-i64.stderr | 121 +- .../numeric-suffix/numeric-suffix-isize.fixed | 33 + .../numeric-suffix/numeric-suffix-isize.rs | 33 + .../numeric-suffix-isize.stderr | 121 +- .../numeric-suffix/numeric-suffix-u32.fixed | 33 + .../numeric-suffix/numeric-suffix-u32.rs | 33 + .../numeric-suffix/numeric-suffix-u32.stderr | 121 +- .../numeric-suffix/numeric-suffix-u64.fixed | 33 + .../numeric-suffix/numeric-suffix-u64.rs | 33 + .../numeric-suffix/numeric-suffix-u64.stderr | 121 +- .../numeric-suffix/numeric-suffix-usize.fixed | 33 + .../numeric-suffix/numeric-suffix-usize.rs | 33 + .../numeric-suffix-usize.stderr | 121 +- .../numeric-suffix/numeric-suffix.fixed | 204 + .../numeric/numeric-suffix/numeric-suffix.rs | 204 + .../numeric-suffix/numeric-suffix.stderr | 748 ++- ...object-lifetime-default-elision.nll.stderr | 15 - .../object-lifetime-default-elision.rs | 3 +- .../object-lifetime-default-elision.stderr | 62 +- ...lifetime-default-from-box-error.nll.stderr | 33 - .../object-lifetime-default-from-box-error.rs | 4 +- ...ect-lifetime-default-from-box-error.stderr | 30 +- ...ime-default-from-rptr-box-error.nll.stderr | 10 - ...ct-lifetime-default-from-rptr-box-error.rs | 3 +- ...ifetime-default-from-rptr-box-error.stderr | 18 +- ...-default-from-rptr-struct-error.nll.stderr | 10 - ...lifetime-default-from-rptr-struct-error.rs | 3 +- ...time-default-from-rptr-struct-error.stderr | 18 +- .../object-lifetime-default-mybox.nll.stderr | 29 - .../object-lifetime-default-mybox.rs | 6 +- .../object-lifetime-default-mybox.stderr | 40 +- .../object-lifetime-default.rs | 2 - .../object-lifetime-default.stderr | 14 +- src/test/ui/osx-frameworks.rs | 2 +- src/test/ui/osx-frameworks.stderr | 6 +- .../ui/{issues => overloaded}/issue-14958.rs | 0 src/test/ui/packed/issue-27060-2.stderr | 2 +- .../ui/parser/attr-stmt-expr-attr-bad.stderr | 6 +- .../ui/parser/attr-with-a-semicolon.stderr | 2 +- src/test/ui/parser/attr.stderr | 2 +- src/test/ui/parser/bad-if-statements.rs | 38 + src/test/ui/parser/bad-if-statements.stderr | 86 + src/test/ui/parser/bounds-obj-parens.rs | 2 +- src/test/ui/parser/can-begin-expr-check.rs | 2 +- .../ui/parser/can-begin-expr-check.stderr | 4 +- .../ui/parser/circular_modules_main.stderr | 2 +- .../parser/doc-comment-in-if-statement.stderr | 2 +- src/test/ui/parser/duplicate-visibility.rs | 4 +- .../ui/parser/duplicate-visibility.stderr | 4 +- src/test/ui/parser/else-no-if.rs | 32 + src/test/ui/parser/else-no-if.stderr | 50 + src/test/ui/parser/expr-as-stmt-2.stderr | 2 +- src/test/ui/parser/expr-as-stmt.stderr | 6 +- src/test/ui/parser/fn-arg-doc-comment.rs | 10 +- src/test/ui/parser/fn-arg-doc-comment.stderr | 48 +- .../ui/parser/if-block-unreachable-expr.rs | 8 + src/test/ui/parser/impl-qpath.rs | 2 +- src/test/ui/parser/increment-autofix.stderr | 4 +- src/test/ui/parser/increment-notfixed.stderr | 14 +- .../inner-attr-after-doc-comment.stderr | 4 +- src/test/ui/parser/inner-attr.stderr | 4 +- src/test/ui/parser/issue-61858.stderr | 10 +- .../issue-68091-unicode-ident-after-if.rs | 10 + .../issue-68091-unicode-ident-after-if.stderr | 10 + ...092-unicode-ident-after-incomplete-expr.rs | 0 ...unicode-ident-after-incomplete-expr.stderr | 0 src/test/ui/parser/issue-81804.rs | 9 + src/test/ui/parser/issue-81804.stderr | 41 + src/test/ui/parser/issue-81827.rs | 11 + src/test/ui/parser/issue-81827.stderr | 35 + src/test/ui/parser/issue-91421.rs | 5 +- src/test/ui/parser/issue-91421.stderr | 17 +- src/test/ui/parser/issues/issue-13483.rs | 8 +- src/test/ui/parser/issues/issue-13483.stderr | 29 +- .../issues/issue-14303-fncall.full.stderr | 2 +- .../issue-14303-fncall.generic_arg.stderr | 2 +- .../ui/parser/issues/issue-14303-fncall.rs | 1 - src/test/ui/parser/issues/issue-19398.stderr | 7 +- src/test/ui/parser/issues/issue-20616-2.rs | 2 +- .../ui/parser/issues/issue-20616-2.stderr | 4 +- src/test/ui/parser/issues/issue-30318.stderr | 6 +- .../ui/parser/issues/issue-34255-1.stderr | 2 +- .../issue-35813-postfix-after-cast.stderr | 32 +- src/test/ui/parser/issues/issue-44406.stderr | 2 +- src/test/ui/parser/issues/issue-45296.stderr | 2 +- src/test/ui/parser/issues/issue-51602.stderr | 10 +- src/test/ui/parser/issues/issue-56031.stderr | 2 +- src/test/ui/parser/issues/issue-62554.stderr | 9 +- src/test/ui/parser/issues/issue-62660.rs | 2 +- src/test/ui/parser/issues/issue-62660.stderr | 4 +- src/test/ui/parser/issues/issue-62894.stderr | 8 +- src/test/ui/parser/issues/issue-62973.stderr | 12 +- ...invalid-syntax-in-enum-discriminant.stderr | 7 +- src/test/ui/parser/issues/issue-84117.rs | 2 +- src/test/ui/parser/issues/issue-84117.stderr | 4 +- src/test/ui/parser/issues/issue-8537.stderr | 2 +- .../issues/issue-88276-unary-plus.stderr | 8 +- src/test/ui/parser/issues/issue-88818.stderr | 2 +- ...outer-attr-following-inner-attr-ice.stderr | 2 +- src/test/ui/parser/issues/issue-93282.stderr | 4 +- src/test/ui/parser/issues/issue-93867.rs | 10 + src/test/ui/parser/issues/issue-93867.stderr | 13 + .../ui/parser/keyword-box-as-identifier.rs | 9 +- .../parser/keyword-box-as-identifier.stderr | 64 +- .../ui/parser/labeled-no-colon-expr.stderr | 6 + src/test/ui/parser/lifetime-semicolon.fixed | 2 +- src/test/ui/parser/lifetime-semicolon.rs | 2 +- src/test/ui/parser/lifetime-semicolon.stderr | 4 +- .../ui/parser/match-arm-without-braces.rs | 6 +- .../ui/parser/match-arm-without-braces.stderr | 10 +- .../mismatched-delim-brace-empty-block.stderr | 2 +- ...closing-angle-bracket-eq-constraint.stderr | 22 +- .../recover-assoc-eq-missing-term.stderr | 2 +- ...recover-for-loop-parens-around-head.stderr | 2 +- .../ui/parser/recover-from-bad-variant.stderr | 2 +- .../recover-labeled-non-block-expr.fixed | 27 + .../parser/recover-labeled-non-block-expr.rs | 26 +- .../recover-labeled-non-block-expr.stderr | 79 +- ...quire-parens-for-chained-comparison.stderr | 4 +- ...truct-literal-restrictions-in-lamda.stderr | 6 + src/test/ui/parser/trailing-plus-in-bounds.rs | 2 +- .../ui/parser/trait-object-delimiters.stderr | 2 +- .../parser/trait-object-trait-parens.stderr | 6 +- .../ui/parser/trait-plusequal-splitting.rs | 2 +- .../ui/parser/type-alias-where-fixable.stderr | 6 +- src/test/ui/parser/unsafe-foreign-mod-2.rs | 8 + .../ui/parser/unsafe-foreign-mod-2.stderr | 28 + src/test/ui/partialeq_help.rs | 5 + src/test/ui/partialeq_help.stderr | 16 +- src/test/ui/path-lookahead.stderr | 2 +- src/test/ui/pattern/for-loop-bad-item.rs | 20 + src/test/ui/pattern/for-loop-bad-item.stderr | 27 + .../ui/{issues => pattern}/issue-27320.rs | 0 src/test/ui/pattern/pat-tuple-bad-type.rs | 4 +- src/test/ui/pattern/pat-tuple-bad-type.stderr | 11 +- .../pat-tuple-field-count-cross.stderr | 176 +- .../ui/pattern/pattern-error-continue.stderr | 10 +- .../rest-pat-semantic-disallowed.stderr | 7 +- .../integer-ranges/exhaustiveness.stderr | 50 +- .../pointer-sized-int.deny.stderr | 40 +- .../usefulness/non-exhaustive-match.stderr | 4 +- .../tuple-struct-nonexhaustive.stderr | 2 +- src/test/ui/privacy/auxiliary/ctor_aux.rs | 25 + src/test/ui/privacy/ctor.rs | 16 + ...sue-46209-private-enum-variant-reexport.rs | 4 +- ...46209-private-enum-variant-reexport.stderr | 16 +- src/test/ui/privacy/issue-79593.rs | 2 +- src/test/ui/privacy/issue-79593.stderr | 4 +- src/test/ui/privacy/macro-private-reexport.rs | 17 + .../ui/privacy/macro-private-reexport.stderr | 29 + .../ui/privacy/private-in-public-warn.stderr | 4 +- .../restricted/auxiliary/pub_restricted.rs | 6 +- .../privacy/restricted/private-in-public.rs | 4 +- .../restricted/private-in-public.stderr | 8 +- src/test/ui/privacy/restricted/test.stderr | 12 +- .../proc-macro/auxiliary/issue-91800-macro.rs | 26 + src/test/ui/proc-macro/issue-66286.stderr | 10 +- src/test/ui/proc-macro/issue-91800.rs | 16 + src/test/ui/proc-macro/issue-91800.stderr | 56 + src/test/ui/proc-macro/signature.rs | 2 +- src/test/ui/proc-macro/signature.stderr | 18 +- .../ui/{issues => process}/issue-13304.rs | 0 src/test/ui/process/nofile-limit.rs | 46 + .../ui/range/issue-54505-no-literals.stderr | 168 +- src/test/ui/range/issue-54505-no-std.stderr | 84 +- src/test/ui/range/issue-54505.stderr | 84 +- ...issue-73553-misinterp-range-literal.stderr | 28 +- src/test/ui/reachable/unreachable-code.stderr | 2 +- .../recursive-static-definition.stderr | 13 +- .../ui/regions/forall-wf-ref-reflexive.rs | 18 + .../ui/regions/forall-wf-ref-reflexive.stderr | 8 + src/test/ui/regions/forall-wf-reflexive.rs | 15 + src/test/ui/regions/issue-28848.base.stderr | 20 - src/test/ui/regions/issue-28848.rs | 7 +- ...ue-28848.nll.stderr => issue-28848.stderr} | 2 +- ...262.nll.stderr => issue-78262.base.stderr} | 2 +- .../ui/regions/issue-78262.default.stderr | 18 - .../ui/regions/issue-78262.polonius.stderr | 2 +- src/test/ui/regions/issue-78262.rs | 10 +- ...variant-static-error-reporting.base.stderr | 25 - ...region-invariant-static-error-reporting.rs | 11 +- ...n-invariant-static-error-reporting.stderr} | 2 +- ...ime-bounds-on-fns-where-clause.base.stderr | 31 - ...time-bounds-on-fns-where-clause.nll.stderr | 50 - ...ion-lifetime-bounds-on-fns-where-clause.rs | 9 - ...lifetime-bounds-on-fns-where-clause.stderr | 12 + ...ime-bounds-on-fns-where-clause.base.stderr | 42 - ...time-bounds-on-fns-where-clause.nll.stderr | 59 - ...ple-lifetime-bounds-on-fns-where-clause.rs | 12 +- ...lifetime-bounds-on-fns-where-clause.stderr | 12 + .../region-object-lifetime-2.base.stderr | 30 - .../ui/regions/region-object-lifetime-2.rs | 7 +- ...stderr => region-object-lifetime-2.stderr} | 2 +- .../region-object-lifetime-4.base.stderr | 30 - .../ui/regions/region-object-lifetime-4.rs | 7 +- ...stderr => region-object-lifetime-4.stderr} | 2 +- ...on-object-lifetime-in-coercion.base.stderr | 98 - .../region-object-lifetime-in-coercion.rs | 16 +- ...region-object-lifetime-in-coercion.stderr} | 8 +- .../regions/regions-addr-of-self.base.stderr | 11 - src/test/ui/regions/regions-addr-of-self.rs | 7 +- ...nll.stderr => regions-addr-of-self.stderr} | 2 +- .../regions-addr-of-upvar-self.base.stderr | 26 - .../ui/regions/regions-addr-of-upvar-self.rs | 11 +- ...derr => regions-addr-of-upvar-self.stderr} | 6 +- ...pertrait-outlives-container.migrate.stderr | 20 - ...c-type-in-supertrait-outlives-container.rs | 11 +- ...e-in-supertrait-outlives-container.stderr} | 2 +- ...nded-by-trait-requiring-static.base.stderr | 75 - ...gions-bounded-by-trait-requiring-static.rs | 22 +- ...-bounded-by-trait-requiring-static.stderr} | 12 +- ...od-type-parameters-cross-crate.base.stderr | 12 - ...nded-method-type-parameters-cross-crate.rs | 6 +- ...method-type-parameters-cross-crate.stderr} | 2 +- ...od-type-parameters-trait-bound.base.stderr | 12 - ...nded-method-type-parameters-trait-bound.rs | 7 +- ...method-type-parameters-trait-bound.stderr} | 2 +- ...bounded-method-type-parameters.base.stderr | 15 - .../regions-bounded-method-type-parameters.rs | 7 +- ...ons-bounded-method-type-parameters.stderr} | 2 +- .../ui/regions/regions-bounds.base.stderr | 41 - src/test/ui/regions/regions-bounds.rs | 10 +- ...ounds.nll.stderr => regions-bounds.stderr} | 4 +- ...se-associated-type-into-object.base.stderr | 40 - ...gions-close-associated-type-into-object.rs | 4 - ...-close-associated-type-into-object.stderr} | 8 +- ...ons-close-object-into-object-2.base.stderr | 27 - .../regions-close-object-into-object-2.rs | 9 +- ...regions-close-object-into-object-2.stderr} | 4 +- ...ons-close-object-into-object-4.base.stderr | 27 - .../regions-close-object-into-object-4.rs | 17 +- ...regions-close-object-into-object-4.stderr} | 12 +- ...ons-close-object-into-object-5.base.stderr | 95 - .../regions-close-object-into-object-5.rs | 9 +- ...regions-close-object-into-object-5.stderr} | 10 +- ...ons-close-over-type-parameter-1.nll.stderr | 26 - .../regions-close-over-type-parameter-1.rs | 4 - ...egions-close-over-type-parameter-1.stderr} | 4 +- ...e-over-type-parameter-multiple.base.stderr | 32 - ...ions-close-over-type-parameter-multiple.rs | 7 +- ...close-over-type-parameter-multiple.stderr} | 2 +- ...egions-close-param-into-object.base.stderr | 48 - .../regions-close-param-into-object.rs | 4 - ...=> regions-close-param-into-object.stderr} | 8 +- .../regions-creating-enums3.base.stderr | 13 - .../ui/regions/regions-creating-enums3.rs | 7 +- ....stderr => regions-creating-enums3.stderr} | 2 +- .../regions-creating-enums4.base.stderr | 34 - .../ui/regions/regions-creating-enums4.rs | 7 +- ....stderr => regions-creating-enums4.stderr} | 2 +- ...gions-early-bound-error-method.base.stderr | 20 - .../regions-early-bound-error-method.rs | 7 +- ...> regions-early-bound-error-method.stderr} | 2 +- .../regions-early-bound-error.base.stderr | 20 - .../ui/regions/regions-early-bound-error.rs | 7 +- ...tderr => regions-early-bound-error.stderr} | 2 +- ...n-subtyping-return-static-fail.base.stderr | 12 - ...fn-subtyping-return-static-fail.nll.stderr | 12 - ...regions-fn-subtyping-return-static-fail.rs | 4 - ...ons-fn-subtyping-return-static-fail.stderr | 19 + ...ns-free-region-ordering-callee.base.stderr | 25 - .../regions-free-region-ordering-callee.rs | 10 +- ...egions-free-region-ordering-callee.stderr} | 4 +- ...free-region-ordering-caller.migrate.stderr | 54 - .../regions-free-region-ordering-caller.rs | 20 +- ...egions-free-region-ordering-caller.stderr} | 6 +- ...free-region-ordering-incorrect.base.stderr | 33 - .../regions-free-region-ordering-incorrect.rs | 8 +- ...ons-free-region-ordering-incorrect.stderr} | 2 +- ...mplied-bounds-projection-gap-1.base.stderr | 14 - ...regions-implied-bounds-projection-gap-1.rs | 4 - ...ns-implied-bounds-projection-gap-1.stderr} | 2 +- ...ns-infer-bound-from-trait-self.base.stderr | 17 - .../regions-infer-bound-from-trait-self.rs | 4 - ...egions-infer-bound-from-trait-self.stderr} | 2 +- ...regions-infer-bound-from-trait.base.stderr | 35 - .../regions/regions-infer-bound-from-trait.rs | 4 - ... => regions-infer-bound-from-trait.stderr} | 4 +- ...fer-contravariance-due-to-decl.base.stderr | 15 - ...egions-infer-contravariance-due-to-decl.rs | 7 +- ...s-infer-contravariance-due-to-decl.stderr} | 2 +- ...s-infer-covariance-due-to-decl.base.stderr | 14 - .../regions-infer-covariance-due-to-decl.rs | 7 +- ...gions-infer-covariance-due-to-decl.stderr} | 2 +- ...s-infer-invariance-due-to-decl.base.stderr | 18 - .../regions-infer-invariance-due-to-decl.rs | 7 +- ...gions-infer-invariance-due-to-decl.stderr} | 2 +- ...invariance-due-to-mutability-3.base.stderr | 18 - ...ns-infer-invariance-due-to-mutability-3.rs | 7 +- ...fer-invariance-due-to-mutability-3.stderr} | 2 +- ...invariance-due-to-mutability-4.base.stderr | 18 - ...ns-infer-invariance-due-to-mutability-4.rs | 7 +- ...fer-invariance-due-to-mutability-4.stderr} | 2 +- .../regions-infer-not-param.base.stderr | 60 - .../ui/regions/regions-infer-not-param.rs | 17 +- ....stderr => regions-infer-not-param.stderr} | 6 +- .../regions-infer-paramd-indirect.base.stderr | 22 - .../regions/regions-infer-paramd-indirect.rs | 10 +- ...r => regions-infer-paramd-indirect.stderr} | 2 +- ...regions-lifetime-bounds-on-fns.base.stderr | 31 - .../regions-lifetime-bounds-on-fns.nll.stderr | 50 - .../regions/regions-lifetime-bounds-on-fns.rs | 9 - .../regions-lifetime-bounds-on-fns.stderr | 12 + .../ui/regions/regions-name-duplicated.rs | 5 +- .../ui/regions/regions-name-duplicated.stderr | 8 +- .../ui/regions/regions-nested-fns.base.stderr | 78 - src/test/ui/regions/regions-nested-fns.rs | 14 +- ...s.nll.stderr => regions-nested-fns.stderr} | 8 +- ...s-projection-container-hrtb.migrate.stderr | 37 - ...ions-outlives-projection-container-hrtb.rs | 14 +- ...outlives-projection-container-hrtb.stderr} | 4 +- ...ves-projection-container-wc.migrate.stderr | 20 - ...egions-outlives-projection-container-wc.rs | 11 +- ...s-outlives-projection-container-wc.stderr} | 2 +- ...-outlives-projection-container.base.stderr | 71 - .../regions-outlives-projection-container.rs | 16 +- ...ions-outlives-projection-container.stderr} | 8 +- .../regions-proc-bound-capture.base.stderr | 29 - .../ui/regions/regions-proc-bound-capture.rs | 7 +- ...derr => regions-proc-bound-capture.stderr} | 2 +- ...w-from-shorter-mut-ref-mut-ref.base.stderr | 13 - ...s-reborrow-from-shorter-mut-ref-mut-ref.rs | 7 +- ...orrow-from-shorter-mut-ref-mut-ref.stderr} | 2 +- ...-reborrow-from-shorter-mut-ref.base.stderr | 13 - .../regions-reborrow-from-shorter-mut-ref.rs | 7 +- ...ions-reborrow-from-shorter-mut-ref.stderr} | 2 +- .../regions-ret-borrowed-1.base.stderr | 32 - src/test/ui/regions/regions-ret-borrowed-1.rs | 7 +- ...l.stderr => regions-ret-borrowed-1.stderr} | 2 +- .../regions/regions-ret-borrowed.base.stderr | 32 - src/test/ui/regions/regions-ret-borrowed.rs | 7 +- ...nll.stderr => regions-ret-borrowed.stderr} | 2 +- .../regions/regions-static-bound.base.stderr | 62 - src/test/ui/regions/regions-static-bound.rs | 13 +- ...nll.stderr => regions-static-bound.stderr} | 10 +- ...regions-trait-object-subtyping.base.stderr | 69 - .../regions/regions-trait-object-subtyping.rs | 11 +- ... => regions-trait-object-subtyping.stderr} | 4 +- ...e-covariant-in-second-position.base.stderr | 12 - ...ariant-use-covariant-in-second-position.rs | 7 +- ...t-use-covariant-in-second-position.stderr} | 2 +- ...ce-contravariant-use-covariant.base.stderr | 15 - ...ns-variance-contravariant-use-covariant.rs | 7 +- ...riance-contravariant-use-covariant.stderr} | 2 +- ...ce-covariant-use-contravariant.base.stderr | 14 - ...ns-variance-covariant-use-contravariant.rs | 7 +- ...riance-covariant-use-contravariant.stderr} | 2 +- ...ce-invariant-use-contravariant.base.stderr | 14 - ...ns-variance-invariant-use-contravariant.rs | 7 +- ...riance-invariant-use-contravariant.stderr} | 2 +- ...riance-invariant-use-covariant.base.stderr | 18 - ...egions-variance-invariant-use-covariant.rs | 7 +- ...s-variance-invariant-use-covariant.stderr} | 2 +- src/test/ui/reify-intrinsic.stderr | 4 - src/test/ui/resolve/crate-in-paths.rs | 4 +- src/test/ui/resolve/crate-in-paths.stderr | 2 +- .../resolve/editions-crate-root-2015.stderr | 4 + .../ui/resolve/enums-are-namespaced-xc.stderr | 6 +- .../ui/resolve/extern-prelude-fail.stderr | 4 + src/test/ui/resolve/filter-intrinsics.rs | 10 + src/test/ui/resolve/filter-intrinsics.stderr | 25 + src/test/ui/resolve/issue-23716.stderr | 4 +- src/test/ui/resolve/issue-24968.rs | 25 + src/test/ui/resolve/issue-24968.stderr | 56 +- src/test/ui/resolve/issue-50599.rs | 1 + src/test/ui/resolve/issue-50599.stderr | 13 +- src/test/ui/resolve/issue-81508.stderr | 2 +- src/test/ui/resolve/issue-82865.stderr | 2 + src/test/ui/resolve/issue-85348.stderr | 7 +- src/test/ui/resolve/levenshtein.stderr | 2 +- .../ui/resolve/missing-in-namespace.stderr | 2 +- src/test/ui/resolve/privacy-enum-ctor.stderr | 8 +- .../ui/resolve/resolve-bad-visibility.stderr | 4 + .../resolve-conflict-item-vs-import.stderr | 2 +- .../resolve-conflict-type-vs-import.stderr | 2 +- .../resolve/resolve-primitive-fallback.stderr | 10 +- ...iable-with-name-similar-to-struct-field.rs | 46 + ...e-with-name-similar-to-struct-field.stderr | 109 + .../ui/rfc-1717-dllimport/rename-modifiers.rs | 9 + .../rename-modifiers.stderr | 8 + .../termination-trait-test-wrong-type.stderr | 9 +- .../rfc-2091-track-caller/error-with-naked.rs | 2 + .../error-with-naked.stderr | 19 +- .../dont-infer-static.rs | 4 +- .../dont-infer-static.stderr | 4 +- .../rfc-2093-infer-outlives/infer-static.rs | 12 - .../infer-static.stderr | 12 - .../ui/rfc-2294-if-let-guard/typeck.stderr | 8 +- .../disallowed-positions.stderr | 16 +- ...-else-does-not-interact-with-let-chains.rs | 6 +- ...e-does-not-interact-with-let-chains.stderr | 36 +- .../param-attrs-builtin-attrs.rs | 40 +- .../param-attrs-builtin-attrs.stderr | 40 +- .../raw-dylib-windows-only.rs | 2 +- .../raw-dylib-windows-only.stderr | 7 +- .../assoc-type.stderr | 2 +- .../rfc-2632-const-trait-impl/attr-misuse.rs | 11 +- .../attr-misuse.stderr | 34 +- .../auxiliary/cross-crate.rs | 2 +- .../auxiliary/staged-api.rs | 7 +- .../const-and-non-const-impl.rs | 6 +- .../const-and-non-const-impl.stderr | 47 +- .../const-default-method-bodies.rs | 2 +- .../const-impl-recovery.stderr | 4 +- ...ross-crate-default-method-body-is-const.rs | 2 +- ...ault-method-body-is-const-body-checking.rs | 2 +- ...-method-body-is-const-body-checking.stderr | 2 +- ...ault-method-body-is-const-same-trait-ck.rs | 3 +- ...-method-body-is-const-same-trait-ck.stderr | 6 +- ...lt-method-body-is-const-with-staged-api.rs | 2 +- .../impl-with-default-fn-fail.rs | 19 +- .../impl-with-default-fn-fail.stderr | 25 +- .../impl-with-default-fn-pass.rs | 9 +- .../ui/rfc-2632-const-trait-impl/stability.rs | 45 - .../stability.stderr | 19 - .../staged-api-user-crate.rs | 16 + .../staged-api-user-crate.stderr | 11 + .../rfc-2632-const-trait-impl/staged-api.rs | 52 +- .../staged-api.stable.stderr | 25 + .../staged-api.staged.stderr | 10 - .../staged-api.stock.stderr | 18 - .../staged-api.unstable.stderr | 42 + .../trait-default-body-stability.rs | 2 +- .../trait-where-clause-run.rs | 2 +- src/test/ui/rfc1623.base.stderr | 11 - src/test/ui/rfc1623.rs | 13 +- .../ui/{rfc1623.nll.stderr => rfc1623.stderr} | 16 +- .../coerce-in-base-expr.rs | 28 + .../issue-96878.rs | 31 + .../type-generic-update.rs | 1 - .../type-generic-update.stderr | 23 +- .../emit-artifact-notifications.nll.stderr | 1 - .../edition-lint-fully-qualified-paths.fixed | 6 +- .../edition-lint-fully-qualified-paths.rs | 6 +- ...ition-lint-infer-outlives-multispan.stderr | 136 +- .../edition-lint-nested-empty-paths.fixed | 12 +- .../edition-lint-nested-empty-paths.rs | 12 +- .../rust-2018/edition-lint-nested-paths.fixed | 8 +- .../ui/rust-2018/edition-lint-nested-paths.rs | 8 +- .../uniform-paths/macro-rules.stderr | 8 +- .../reserved-prefixes-migration.stderr | 10 +- .../ui/rust-2021/reserved-prefixes.stderr | 18 +- .../check-doc-alias-attr-location.stderr | 2 +- .../emit-notifications.nll.stderr | 2 - .../{issues => save-analysis}/issue-26459.rs | 0 .../issue-26459.stderr | 0 ...types_pin_lifetime_impl_trait-async.stderr | 4 +- ...es_pin_lifetime_mismatch-async.base.stderr | 27 - ..._self_types_pin_lifetime_mismatch-async.rs | 12 +- ..._types_pin_lifetime_mismatch-async.stderr} | 16 +- ...lf_types_pin_lifetime_mismatch.base.stderr | 39 - ...itrary_self_types_pin_lifetime_mismatch.rs | 13 +- ...y_self_types_pin_lifetime_mismatch.stderr} | 6 +- .../elision/lt-ref-self-async.base.stderr | 63 - src/test/ui/self/elision/lt-ref-self-async.rs | 21 +- ...nc.nll.stderr => lt-ref-self-async.stderr} | 42 +- .../ui/self/elision/lt-ref-self.base.stderr | 99 - src/test/ui/self/elision/lt-ref-self.rs | 22 +- ...ref-self.nll.stderr => lt-ref-self.stderr} | 12 +- .../elision/ref-mut-self-async.base.stderr | 63 - .../ui/self/elision/ref-mut-self-async.rs | 21 +- ...c.nll.stderr => ref-mut-self-async.stderr} | 42 +- .../ui/self/elision/ref-mut-self.base.stderr | 99 - src/test/ui/self/elision/ref-mut-self.rs | 22 +- ...ut-self.nll.stderr => ref-mut-self.stderr} | 12 +- .../elision/ref-mut-struct-async.base.stderr | 53 - .../ui/self/elision/ref-mut-struct-async.rs | 18 +- ...nll.stderr => ref-mut-struct-async.stderr} | 35 +- .../self/elision/ref-mut-struct.base.stderr | 83 - src/test/ui/self/elision/ref-mut-struct.rs | 19 +- ...truct.nll.stderr => ref-mut-struct.stderr} | 10 +- .../self/elision/ref-self-async.base.stderr | 73 - src/test/ui/self/elision/ref-self-async.rs | 24 +- ...async.nll.stderr => ref-self-async.stderr} | 49 +- src/test/ui/self/elision/ref-self.base.stderr | 115 - src/test/ui/self/elision/ref-self.rs | 25 +- .../{ref-self.nll.stderr => ref-self.stderr} | 14 +- .../self/elision/ref-struct-async.base.stderr | 53 - src/test/ui/self/elision/ref-struct-async.rs | 18 +- ...ync.nll.stderr => ref-struct-async.stderr} | 35 +- .../ui/self/elision/ref-struct.base.stderr | 83 - src/test/ui/self/elision/ref-struct.rs | 19 +- ...ef-struct.nll.stderr => ref-struct.stderr} | 10 +- src/test/ui/self/issue-61882.stderr | 10 +- .../portable-intrinsics-arent-exposed.stderr | 2 + .../ui/single-use-lifetime/fn-types.stderr | 5 + .../one-use-in-fn-argument.rs | 13 +- .../one-use-in-fn-argument.stderr | 8 +- .../one-use-in-fn-return.rs | 6 + .../one-use-in-inherent-impl-header.stderr | 5 + .../one-use-in-inherent-method-argument.rs | 1 + ...one-use-in-inherent-method-argument.stderr | 34 +- .../one-use-in-inherent-method-return.stderr | 5 + .../single-use-lifetime/one-use-in-struct.rs | 3 +- .../one-use-in-trait-method-argument.rs | 7 +- .../one-use-in-trait-method-argument.stderr | 2 +- ...inherent-method-argument-and-return.stderr | 5 + src/test/ui/span/coerce-suggestions.stderr | 18 +- src/test/ui/span/issue-34264.stderr | 26 +- src/test/ui/span/issue-39018.stderr | 4 +- ...ue-42234-unknown-receiver-type.full.stderr | 20 +- ...4-unknown-receiver-type.generic_arg.stderr | 20 +- .../span/issue-42234-unknown-receiver-type.rs | 3 +- src/test/ui/span/issue-71363.rs | 19 + src/test/ui/span/issue-71363.stderr | 27 + src/test/ui/span/macro-span-replacement.rs | 2 +- .../ui/span/macro-span-replacement.stderr | 2 +- .../span/method-and-field-eager-resolution.rs | 4 +- .../method-and-field-eager-resolution.stderr | 20 +- src/test/ui/span/missing-unit-argument.stderr | 54 +- src/test/ui/span/move-closure.stderr | 4 + .../span/type-annotations-needed-expr.stderr | 4 +- .../unused-warning-point-at-identifier.rs | 8 +- .../unused-warning-point-at-identifier.stderr | 8 +- .../default-associated-type-bound-2.stderr | 2 +- src/test/ui/specialization/issue-52050.stderr | 2 +- .../allow-unstable-reexport.rs | 30 + .../allow-unstable-reexport.stderr | 27 + .../auxiliary/lint-stability-reexport.rs | 9 + .../missing-const-stability.rs | 14 +- .../missing-const-stability.stderr | 11 +- src/test/ui/statics/uninhabited-static.stderr | 12 +- src/test/ui/str/str-lit-type-mismatch.stderr | 2 +- .../ui/structs/struct-path-associated-type.rs | 4 +- .../struct-path-associated-type.stderr | 12 +- src/test/ui/structs/struct-path-self.rs | 6 +- src/test/ui/structs/struct-path-self.stderr | 52 +- ...adt-param-with-implicit-sized-bound.stderr | 2 +- .../args-instead-of-tuple-errors.stderr | 62 +- .../suggestions/args-instead-of-tuple.fixed | 33 + .../ui/suggestions/args-instead-of-tuple.rs | 2 + .../suggestions/args-instead-of-tuple.stderr | 74 +- src/test/ui/suggestions/as-ref.stderr | 44 +- .../ui/suggestions/boxed-variant-field.stderr | 9 +- .../derive-macro-missing-bounds.stderr | 2 +- .../ui/suggestions/enum-method-probe.fixed | 59 + src/test/ui/suggestions/enum-method-probe.rs | 59 + .../ui/suggestions/enum-method-probe.stderr | 99 + .../expected-boxed-future-isnt-pinned.stderr | 6 + .../fn-needing-specified-return-type-param.rs | 4 +- ...needing-specified-return-type-param.stderr | 11 +- .../fn-or-tuple-struct-without-args.stderr | 14 +- src/test/ui/suggestions/format-borrow.stderr | 8 +- ...-trait-object-literal-bound-regions.stderr | 1 + ...-bound-needing-more-suggestions.nll.stderr | 21 - ...t-static-bound-needing-more-suggestions.rs | 2 +- ...atic-bound-needing-more-suggestions.stderr | 25 +- ...dyn-trait-with-implicit-static-bound.fixed | 112 - ...rait-with-implicit-static-bound.nll.stderr | 55 - ...on-dyn-trait-with-implicit-static-bound.rs | 16 +- ...yn-trait-with-implicit-static-bound.stderr | 114 +- src/test/ui/suggestions/invalid-bin-op.stderr | 2 +- src/test/ui/suggestions/issue-61963.stderr | 14 +- src/test/ui/suggestions/issue-82361.stderr | 4 +- .../issue-86100-tuple-paren-comma.stderr | 9 +- ...e-90213-expected-boxfuture-self-ice.stderr | 9 +- src/test/ui/suggestions/issue-96555.stderr | 6 +- src/test/ui/suggestions/issue-97677.rs | 6 + src/test/ui/suggestions/issue-97677.stderr | 16 + src/test/ui/suggestions/issue-97704.fixed | 19 + src/test/ui/suggestions/issue-97704.rs | 19 + src/test/ui/suggestions/issue-97704.stderr | 15 + src/test/ui/suggestions/issue-97760.rs | 9 + src/test/ui/suggestions/issue-97760.stderr | 18 + .../let-binding-init-expr-as-ty.stderr | 10 +- ...issing-lifetimes-in-signature-2.nll.stderr | 29 - .../missing-lifetimes-in-signature-2.stderr | 25 +- .../missing-lifetimes-in-signature.nll.stderr | 153 - .../missing-lifetimes-in-signature.rs | 11 +- .../missing-lifetimes-in-signature.stderr | 136 +- ...ait-object-nested-in-impl-trait.nll.stderr | 74 - .../trait-object-nested-in-impl-trait.rs | 12 +- .../trait-object-nested-in-impl-trait.stderr | 105 +- .../ui/suggestions/match-ergonomics.stderr | 26 +- .../match-prev-arm-needing-semi.stderr | 2 +- .../missing-bound-in-derive-copy-impl-2.fixed | 16 + .../missing-bound-in-derive-copy-impl-2.rs | 16 + ...missing-bound-in-derive-copy-impl-2.stderr | 19 + .../missing-bound-in-derive-copy-impl-3.fixed | 16 + .../missing-bound-in-derive-copy-impl-3.rs | 16 + ...missing-bound-in-derive-copy-impl-3.stderr | 27 + .../missing-bound-in-derive-copy-impl.rs | 15 + .../missing-bound-in-derive-copy-impl.stderr | 27 + .../missing-lifetime-specifier.stderr | 16 +- .../suggestions/mut-ref-reassignment.stderr | 4 +- ...ecover-from-semicolon-trailing-item.stderr | 10 +- ...ltiline-trait-bound-in-where-clause.stderr | 6 +- src/test/ui/suggestions/suggest-change-mut.rs | 2 +- .../ui/suggestions/suggest-change-mut.stderr | 4 +- .../suggest-closure-return-type-1.rs | 6 +- .../suggest-closure-return-type-1.stderr | 14 +- .../suggest-closure-return-type-2.rs | 6 +- .../suggest-closure-return-type-2.stderr | 14 +- .../suggest-closure-return-type-3.rs | 6 +- .../suggest-closure-return-type-3.stderr | 14 +- .../suggest-impl-trait-lifetime.fixed | 2 +- .../suggest-impl-trait-lifetime.nll.stderr | 14 - .../suggest-impl-trait-lifetime.rs | 2 +- .../suggest-impl-trait-lifetime.stderr | 7 +- .../ui/suggestions/suggest-ref-macro.stderr | 39 +- .../suggest-std-when-using-type.fixed | 8 + .../suggest-std-when-using-type.rs | 7 +- .../suggest-std-when-using-type.stderr | 14 +- ...swapping-self-ty-and-trait-edition-2021.rs | 22 + ...ping-self-ty-and-trait-edition-2021.stderr | 49 + .../suggest-swapping-self-ty-and-trait.rs | 21 + .../suggest-swapping-self-ty-and-trait.stderr | 51 + .../ui/suggestions/suggest-trait-items.stderr | 2 +- ...associated-type-restriction-fixable.stderr | 63 +- ...missing-associated-type-restriction.stderr | 73 +- src/test/ui/tag-variant-disr-dup.rs | 3 +- src/test/ui/tag-variant-disr-dup.stderr | 19 +- src/test/ui/terr-in-field.stderr | 10 +- src/test/ui/terr-sorts.stderr | 9 +- .../issue-16597-empty.rs | 0 .../ui/{issues => test-attrs}/issue-16597.rs | 0 .../ui/test-attrs/test-warns-dead-code.rs | 2 +- .../ui/test-attrs/test-warns-dead-code.stderr | 2 +- src/test/ui/trait-bounds/issue-93008.rs | 17 +- src/test/ui/trait-bounds/issue-93008.stderr | 12 - src/test/ui/trait-bounds/issue-94680.rs | 14 + src/test/ui/trait-bounds/issue-94999.rs | 34 + src/test/ui/trait-bounds/issue-95640.rs | 31 + .../select-param-env-instead-of-blanket.rs | 43 + ...select-param-env-instead-of-blanket.stderr | 18 + ...owed-path-in-trait-bound-suggestion.stderr | 2 +- src/test/ui/trait-bounds/unsized-bound.stderr | 26 +- src/test/ui/traits/alias/no-duplicates.stderr | 6 +- .../ui/traits/alias/no-extra-traits.stderr | 4 +- .../ui/traits/alias/only-maybe-bound.stderr | 2 +- .../ui/traits/assoc-type-in-superbad.stderr | 8 +- .../ui/traits/bound/not-on-bare-trait.stderr | 2 +- src/test/ui/traits/bound/not-on-struct.stderr | 14 +- src/test/ui/traits/bound/sugar.stderr | 9 +- ...s-by-name-in-suggestion-issue-96292.stderr | 23 +- src/test/ui/{issues => traits}/issue-18400.rs | 0 .../ui/{issues => traits}/issue-18400.stderr | 0 src/test/ui/{issues => traits}/issue-18412.rs | 0 src/test/ui/{issues => traits}/issue-35869.rs | 0 .../ui/{issues => traits}/issue-35869.stderr | 0 src/test/ui/{issues => traits}/issue-38033.rs | 0 src/test/ui/traits/issue-52893.stderr | 9 +- src/test/ui/traits/issue-77982.stderr | 60 +- src/test/ui/{issues => traits}/issue-8153.rs | 0 .../ui/{issues => traits}/issue-8153.stderr | 0 src/test/ui/traits/issue-82830.rs | 16 + src/test/ui/traits/issue-82830.stderr | 15 + .../traits/issue-91949-hangs-on-recursion.rs | 30 + .../issue-91949-hangs-on-recursion.stderr | 25 + src/test/ui/traits/issue-97576.rs | 13 + src/test/ui/traits/issue-97576.stderr | 11 + .../issue-97695-double-trivial-bound.rs | 24 + src/test/ui/traits/multidispatch-bad.stderr | 9 +- .../multidispatch-convert-ambig-dest.stderr | 13 +- ...t-non-existing-fully-qualified-path.stderr | 19 +- .../supertrait-lifetime-bound.nll.stderr | 11 - .../object/supertrait-lifetime-bound.rs | 2 +- .../object/supertrait-lifetime-bound.stderr | 14 +- .../traits/resolution-in-overloaded-op.stderr | 2 +- ...st-fully-qualified-path-with-adjustment.rs | 60 + ...ully-qualified-path-with-adjustment.stderr | 186 + ...-qualified-path-with-appropriate-params.rs | 24 - ...lified-path-with-appropriate-params.stderr | 61 - ...fully-qualified-path-without-adjustment.rs | 64 + ...y-qualified-path-without-adjustment.stderr | 224 + .../ui/traits/suggest-where-clause.stderr | 8 +- .../ui/traits/trait-upcasting/lifetime.rs | 1 - .../trait-upcasting/type-checking-test-3.rs | 5 +- .../type-checking-test-3.stderr | 35 +- .../trait-upcasting/type-checking-test-4.rs | 13 +- .../type-checking-test-4.stderr | 123 +- src/test/ui/traits/vtable/issue-97381.rs | 30 + src/test/ui/traits/vtable/issue-97381.stderr | 15 + .../trivial-bounds-inconsistent.stderr | 2 +- .../try-block/try-block-bad-lifetime.stderr | 2 +- .../try-block-unreachable-code-lint.stderr | 4 +- .../try-block/try-block-unused-delims.stderr | 10 +- src/test/ui/tuple/tuple-arity-mismatch.stderr | 18 +- src/test/ui/tuple/wrong_argument_ice-2.stderr | 2 +- src/test/ui/tuple/wrong_argument_ice-3.stderr | 12 +- src/test/ui/tuple/wrong_argument_ice-4.stderr | 14 +- src/test/ui/tuple/wrong_argument_ice.stderr | 2 +- .../enum-variant-generic-args.rs | 54 +- .../enum-variant-generic-args.stderr | 302 +- ...priority-higher-than-other-inherent.stderr | 8 +- ...t-variant-form-through-alias-caught.stderr | 2 +- ...ype-application-on-aliased-enum-variant.rs | 2 +- ...application-on-aliased-enum-variant.stderr | 6 +- .../auto-trait-leakage2.rs | 8 +- .../auto-trait-leakage2.stderr | 10 +- .../closures_in_branches.stderr | 6 +- .../cross_inference_pattern_bug.rs | 20 +- .../cross_inference_pattern_bug.stderr | 34 +- ..._type_does_not_live_long_enough.nll.stderr | 32 - .../generic_type_does_not_live_long_enough.rs | 4 - ...ric_type_does_not_live_long_enough.stderr} | 8 +- .../incomplete-inference.stderr | 7 +- .../ui/type-alias-impl-trait/issue-53092-2.rs | 15 + .../issue-53092-2.stderr | 55 + .../ui/type-alias-impl-trait/issue-53092.rs | 12 +- .../type-alias-impl-trait/issue-53092.stderr | 19 + .../issue-57611-trait-alias.base.stderr | 11 - .../issue-57611-trait-alias.rs | 4 - ....stderr => issue-57611-trait-alias.stderr} | 10 +- .../type-alias-impl-trait/issue-63279.stderr | 6 +- .../type-alias-impl-trait/issue-74280.stderr | 2 +- .../ui/type-alias-impl-trait/issue-90400-1.rs | 30 + .../issue-90400-1.stderr | 19 + .../ui/type-alias-impl-trait/issue-90400-2.rs | 38 + .../issue-90400-2.stderr | 19 + .../multiple-def-uses-in-one-fn.stderr | 2 +- .../nested-tait-inference.stderr | 3 + .../nested-tait-inference2.stderr | 3 + .../no_inferrable_concrete_type.rs | 14 +- .../no_inferrable_concrete_type.stderr | 18 +- .../wf_check_closures.rs | 4 +- .../wf_check_closures.stderr | 19 + .../ui/{issues => type-alias}/issue-14933.rs | 0 .../ui/type-alias/issue-62263-self-in-atb.rs | 2 +- .../type-alias/issue-62263-self-in-atb.stderr | 4 +- .../type-alias/issue-62305-self-assoc-ty.rs | 2 +- .../issue-62305-self-assoc-ty.stderr | 4 +- .../type-alias/issue-62364-self-ty-arg.stderr | 6 +- .../or_else-multiple-type-params.stderr | 12 +- src/test/ui/type-inference/sort_by_key.stderr | 6 +- .../unbounded-associated-type.stderr | 15 +- ...ed-type-param-in-fn-with-assoc-type.stderr | 7 +- .../unbounded-type-param-in-fn.stderr | 7 +- .../ui/type/ascription/issue-34255-1.stderr | 3 +- .../ui/type/ascription/issue-47666.stderr | 2 +- ...0-type-alias-bound-diagnostic-crash.stderr | 2 +- src/test/ui/type/issue-91268.rs | 2 +- src/test/ui/type/issue-91268.stderr | 17 +- src/test/ui/type/type-alias-bounds.stderr | 18 +- .../ui/type/type-annotation-needed.stderr | 6 +- ...e-ascription-instead-of-initializer.stderr | 8 +- .../cannot_infer_local_or_array.stderr | 11 +- .../cannot_infer_local_or_vec.stderr | 11 +- ...cannot_infer_local_or_vec_in_tuples.stderr | 11 +- .../type-check/unknown_type_for_closure.rs | 18 +- .../unknown_type_for_closure.stderr | 36 +- .../ui/type/type-dependent-def-issue-49241.rs | 1 + .../type-dependent-def-issue-49241.stderr | 11 +- .../type/type-mismatch-same-crate-name.stderr | 18 +- src/test/ui/type/type-mismatch.stderr | 437 +- ...parameter-defaults-referencing-Self.stderr | 2 +- .../ui/type/type-path-err-node-types.stderr | 7 +- src/test/ui/type/type-unsatisfiable.rs | 59 + .../ui/type/type-unsatisfiable.usage.stderr | 11 + .../ui/typeck/assign-non-lval-derefmut.fixed | 15 + .../ui/typeck/assign-non-lval-derefmut.rs | 15 + .../ui/typeck/assign-non-lval-derefmut.stderr | 58 + .../ui/typeck/assign-non-lval-mut-ref.fixed | 15 + src/test/ui/typeck/assign-non-lval-mut-ref.rs | 15 + .../ui/typeck/assign-non-lval-mut-ref.stderr | 56 + .../auxiliary/issue-36708.rs | 0 src/test/ui/{issues => typeck}/issue-10401.rs | 0 .../ui/{issues => typeck}/issue-10401.stderr | 0 .../ui/{issues => typeck}/issue-13853-2.rs | 0 .../{issues => typeck}/issue-13853-2.stderr | 0 .../ui/{issues => typeck}/issue-13853-5.rs | 0 .../{issues => typeck}/issue-13853-5.stderr | 0 src/test/ui/{issues => typeck}/issue-13853.rs | 0 .../ui/{issues => typeck}/issue-13853.stderr | 14 +- src/test/ui/{issues => typeck}/issue-29124.rs | 0 .../ui/{issues => typeck}/issue-29124.stderr | 0 src/test/ui/{issues => typeck}/issue-36708.rs | 0 .../ui/{issues => typeck}/issue-36708.stderr | 0 src/test/ui/typeck/issue-46112.stderr | 9 +- src/test/ui/typeck/issue-65611.stderr | 7 +- src/test/ui/typeck/issue-74086.rs | 1 + src/test/ui/typeck/issue-74086.stderr | 8 +- src/test/ui/typeck/issue-81885.rs | 3 +- src/test/ui/typeck/issue-81885.stderr | 16 +- src/test/ui/typeck/issue-84768.stderr | 9 +- ...7872-missing-inaccessible-field-literal.rs | 2 +- ...-missing-inaccessible-field-literal.stderr | 4 +- src/test/ui/typeck/issue-88643.rs | 19 + src/test/ui/typeck/issue-88643.stderr | 21 + .../issue-88803-call-expr-method.stderr | 2 +- src/test/ui/typeck/issue-89856.stderr | 9 +- src/test/ui/typeck/issue-93486.stderr | 5 + ...issing-private-fields-in-struct-literal.rs | 18 + ...ng-private-fields-in-struct-literal.stderr | 15 + src/test/ui/typeck/prim-with-args.fixed | 28 + src/test/ui/typeck/prim-with-args.rs | 45 +- src/test/ui/typeck/prim-with-args.stderr | 342 +- .../ui/typeck/remove-extra-argument.fixed | 9 + src/test/ui/typeck/remove-extra-argument.rs | 2 + .../ui/typeck/remove-extra-argument.stderr | 12 +- .../ui/typeck/struct-enum-wrong-args.stderr | 84 +- .../typeck_type_placeholder_item_help.rs | 1 + .../typeck_type_placeholder_item_help.stderr | 12 +- .../ui/ufcs/ufcs-qpath-self-mismatch.stderr | 18 +- .../unboxed-closures/issue-30906.base.stderr | 11 - src/test/ui/unboxed-closures/issue-30906.rs | 4 - ...ue-30906.nll.stderr => issue-30906.stderr} | 2 +- ...oxed-closure-sugar-lifetime-elision.stderr | 7 +- ...oxed-closure-sugar-used-on-struct-3.stderr | 10 +- ...oxed-closures-failed-recursive-fn-1.stderr | 4 +- .../unboxed-closures-failed-recursive-fn-2.rs | 2 +- ...oxed-closures-failed-recursive-fn-2.stderr | 11 +- ...ment-types-two-region-pointers.base.stderr | 30 - ...nfer-argument-types-two-region-pointers.rs | 7 +- ...argument-types-two-region-pointers.stderr} | 2 +- .../unboxed-closures-type-mismatch.stderr | 9 +- src/test/ui/unconstrained-none.stderr | 7 +- src/test/ui/unconstrained-ref.stderr | 7 +- src/test/ui/underscore-imports/duplicate.rs | 2 +- src/test/ui/underscore-imports/intercrate.rs | 2 +- .../dyn-trait-underscore.base.stderr | 27 - .../dyn-trait-underscore.rs | 7 +- ...nll.stderr => dyn-trait-underscore.stderr} | 2 +- ...score-lifetime-elison-mismatch.base.stderr | 17 - .../underscore-lifetime-elison-mismatch.rs | 7 +- ...nderscore-lifetime-elison-mismatch.stderr} | 2 +- src/test/ui/union/union-copy.stderr | 4 +- .../union/union-fields-1.mirunsafeck.stderr | 20 +- src/test/ui/union/union-fields-1.rs | 8 +- .../union/union-fields-1.thirunsafeck.stderr | 20 +- .../union-lint-dead-code.mirunsafeck.stderr | 5 +- src/test/ui/union/union-lint-dead-code.rs | 2 +- .../union-lint-dead-code.thirunsafeck.stderr | 5 +- src/test/ui/union/union-sized-field.stderr | 6 +- src/test/ui/unop-move-semantics.stderr | 2 +- .../unresolved-asterisk-imports.stderr | 2 + src/test/ui/unresolved/unresolved-import.rs | 1 + .../ui/unresolved/unresolved-import.stderr | 12 +- .../{issues => unsafe}/issue-3080.mir.stderr | 0 src/test/ui/{issues => unsafe}/issue-3080.rs | 0 .../{issues => unsafe}/issue-3080.thir.stderr | 0 .../{issues => unsafe}/issue-47412.mir.stderr | 0 src/test/ui/{issues => unsafe}/issue-47412.rs | 0 .../issue-47412.thir.stderr | 0 .../ui/{issues => unsized}/issue-40231-1.rs | 0 .../ui/{issues => unsized}/issue-40231-2.rs | 0 src/test/ui/unsized/issue-97732.rs | 28 + .../ui/unsized/unsized-bare-typaram.stderr | 2 +- src/test/ui/unsized/unsized-enum.stderr | 2 +- src/test/ui/unsized/unsized-enum2.stderr | 8 +- src/test/ui/unsized/unsized-fn-arg.stderr | 2 +- .../unsized-inherent-impl-self-type.stderr | 2 +- src/test/ui/unsized/unsized-struct.stderr | 4 +- .../unsized-trait-impl-self-type.stderr | 2 +- .../unsized-trait-impl-trait-arg.stderr | 2 +- src/test/ui/unsized/unsized3.stderr | 10 +- src/test/ui/unsized/unsized5.stderr | 8 +- src/test/ui/unsized/unsized6.stderr | 26 +- src/test/ui/unsized/unsized7.stderr | 2 +- ...after-move-implicity-coerced-object.stderr | 2 +- src/test/ui/use/use-mod/use-mod-4.stderr | 4 +- src/test/ui/use/use-mod/use-mod-5.stderr | 2 +- src/test/ui/use/use-mod/use-mod-6.stderr | 2 +- src/test/ui/use/use-self-type.rs | 2 +- src/test/ui/use/use-self-type.stderr | 6 +- src/test/ui/usize-generic-argument-parent.rs | 2 +- .../ui/usize-generic-argument-parent.stderr | 12 +- .../variance-associated-types2.base.stderr | 18 - .../ui/variance/variance-associated-types2.rs | 7 +- ...derr => variance-associated-types2.stderr} | 2 +- ...variance-btree-invariant-types.base.stderr | 243 - .../variance-btree-invariant-types.rs | 52 +- ... => variance-btree-invariant-types.stderr} | 48 +- .../variance-cell-is-invariant.base.stderr | 15 - .../ui/variance/variance-cell-is-invariant.rs | 7 +- ...derr => variance-cell-is-invariant.stderr} | 2 +- ...iance-contravariant-arg-object.base.stderr | 41 - .../variance-contravariant-arg-object.rs | 14 +- ... variance-contravariant-arg-object.stderr} | 6 +- ...-contravariant-arg-trait-match.base.stderr | 41 - .../variance-contravariant-arg-trait-match.rs | 10 +- ...ance-contravariant-arg-trait-match.stderr} | 4 +- ...contravariant-self-trait-match.base.stderr | 41 - ...variance-contravariant-self-trait-match.rs | 10 +- ...nce-contravariant-self-trait-match.stderr} | 4 +- .../variance-covariant-arg-object.base.stderr | 41 - .../variance/variance-covariant-arg-object.rs | 14 +- ...r => variance-covariant-arg-object.stderr} | 6 +- ...ance-covariant-arg-trait-match.base.stderr | 41 - .../variance-covariant-arg-trait-match.rs | 10 +- ...variance-covariant-arg-trait-match.stderr} | 4 +- ...nce-covariant-self-trait-match.base.stderr | 41 - .../variance-covariant-self-trait-match.rs | 10 +- ...ariance-covariant-self-trait-match.stderr} | 4 +- .../variance-invariant-arg-object.base.stderr | 41 - .../variance/variance-invariant-arg-object.rs | 14 +- ...r => variance-invariant-arg-object.stderr} | 6 +- ...ance-invariant-arg-trait-match.base.stderr | 41 - .../variance-invariant-arg-trait-match.rs | 10 +- ...variance-invariant-arg-trait-match.stderr} | 4 +- ...nce-invariant-self-trait-match.base.stderr | 41 - .../variance-invariant-self-trait-match.rs | 10 +- ...ariance-invariant-self-trait-match.stderr} | 4 +- src/test/ui/variance/variance-object-types.rs | 4 - .../ui/variance/variance-object-types.stderr | 2 +- .../variance-trait-matching.base.stderr | 12 - .../ui/variance/variance-trait-matching.rs | 4 - ....stderr => variance-trait-matching.stderr} | 2 +- ...nce-use-contravariant-struct-1.base.stderr | 22 - .../variance-use-contravariant-struct-1.rs | 7 +- ...ariance-use-contravariant-struct-1.stderr} | 2 +- ...ariance-use-covariant-struct-1.base.stderr | 22 - .../variance-use-covariant-struct-1.rs | 7 +- ...=> variance-use-covariant-struct-1.stderr} | 2 +- ...ariance-use-invariant-struct-1.base.stderr | 41 - .../variance-use-invariant-struct-1.rs | 10 +- ...=> variance-use-invariant-struct-1.stderr} | 4 +- src/test/ui/wasm/wasm-import-module.rs | 11 + src/test/ui/wasm/wasm-import-module.stderr | 32 +- src/test/ui/weird-exprs.rs | 28 +- src/test/ui/wf/issue-95665.rs | 18 + src/test/ui/wf/issue-95665.stderr | 15 + src/test/ui/wf/wf-static-method.base.stderr | 136 - src/test/ui/wf/wf-static-method.rs | 22 +- ...hod.nll.stderr => wf-static-method.stderr} | 12 +- .../where-for-self-2.base.stderr | 11 - src/test/ui/where-clauses/where-for-self-2.rs | 4 - ...f-2.nll.stderr => where-for-self-2.stderr} | 2 +- src/tools/bump-stage0/Cargo.toml | 2 +- src/tools/bump-stage0/src/main.rs | 67 +- src/tools/clippy/.github/deploy.sh | 1 + .../clippy/.github/workflows/clippy_bors.yml | 19 + src/tools/clippy/.github/workflows/remark.yml | 9 + src/tools/clippy/CHANGELOG.md | 57 +- src/tools/clippy/CONTRIBUTING.md | 178 +- src/tools/clippy/Cargo.toml | 9 +- src/tools/clippy/book/README.md | 4 + src/tools/clippy/book/book.toml | 28 + src/tools/clippy/book/src/README.md | 34 + src/tools/clippy/book/src/SUMMARY.md | 23 + src/tools/clippy/book/src/configuration.md | 92 + .../book/src/continuous_integration/README.md | 18 + .../continuous_integration/github_actions.md | 21 + .../book/src/continuous_integration/travis.md | 20 + .../clippy/book/src/development/README.md | 43 + .../src/development}/adding_lints.md | 343 +- .../{doc => book/src/development}/basics.md | 72 +- .../common_tools_writing_lints.md | 160 +- .../src/development/infrastructure/README.md | 19 + .../development/infrastructure}/backport.md | 0 .../src/development/infrastructure/book.md | 42 + .../infrastructure}/changelog_update.md | 39 +- .../development/infrastructure}/release.md | 31 +- .../src/development/infrastructure/sync.md | 123 + .../book/src/development/proposals/README.md | 11 + .../development/proposals}/roadmap-2021.md | 0 src/tools/clippy/book/src/installation.md | 24 + src/tools/clippy/book/src/lints.md | 105 + src/tools/clippy/book/src/usage.md | 151 + src/tools/clippy/clippy_dev/Cargo.toml | 2 +- src/tools/clippy/clippy_dev/src/bless.rs | 6 +- src/tools/clippy/clippy_dev/src/lint.rs | 5 +- src/tools/clippy/clippy_dev/src/main.rs | 345 +- src/tools/clippy/clippy_dev/src/new_lint.rs | 11 +- src/tools/clippy/clippy_dev/src/serve.rs | 12 +- .../clippy/clippy_dev/src/update_lints.rs | 25 +- src/tools/clippy/clippy_lints/Cargo.toml | 6 +- .../src/almost_complete_letter_range.rs | 100 + .../clippy/clippy_lints/src/approx_const.rs | 6 +- .../clippy/clippy_lints/src/as_conversions.rs | 9 +- .../clippy/clippy_lints/src/as_underscore.rs | 74 + .../src/assertions_on_constants.rs | 3 - .../clippy/clippy_lints/src/assign_ops.rs | 12 +- .../clippy_lints/src/async_yields_async.rs | 6 +- src/tools/clippy/clippy_lints/src/attrs.rs | 86 +- .../clippy_lints/src/await_holding_invalid.rs | 2 - src/tools/clippy/clippy_lints/src/bit_mask.rs | 40 +- .../src/blocks_in_if_conditions.rs | 16 +- .../src/bool_assert_comparison.rs | 5 +- src/tools/clippy/clippy_lints/src/booleans.rs | 25 +- .../clippy/clippy_lints/src/borrow_as_ptr.rs | 2 +- .../clippy_lints/src/borrow_deref_ref.rs | 121 + .../clippy/clippy_lints/src/bytecount.rs | 12 +- .../src/casts/cast_abs_to_unsigned.rs | 48 +- .../clippy_lints/src/casts/cast_lossless.rs | 8 +- .../src/casts/cast_slice_different_sizes.rs | 6 +- .../clippy/clippy_lints/src/casts/mod.rs | 49 +- .../clippy_lints/src/casts/ptr_as_ptr.rs | 4 +- .../src/casts/unnecessary_cast.rs | 12 +- .../clippy_lints/src/checked_conversions.rs | 24 +- .../clippy_lints/src/cognitive_complexity.rs | 6 +- .../clippy/clippy_lints/src/collapsible_if.rs | 14 +- .../clippy_lints/src/comparison_chain.rs | 3 +- src/tools/clippy/clippy_lints/src/copies.rs | 677 +- .../clippy_lints/src/crate_in_macro_def.rs | 4 +- .../clippy/clippy_lints/src/create_dir.rs | 6 +- .../clippy/clippy_lints/src/dbg_macro.rs | 28 +- src/tools/clippy/clippy_lints/src/default.rs | 13 +- .../src/default_numeric_fallback.rs | 16 +- .../src/default_union_representation.rs | 4 +- .../clippy_lints/src/deprecated_lints.rs | 1 - .../clippy/clippy_lints/src/dereference.rs | 77 +- .../clippy_lints/src/derivable_impls.rs | 6 +- src/tools/clippy/clippy_lints/src/derive.rs | 133 +- .../clippy_lints/src/disallowed_methods.rs | 14 +- src/tools/clippy/clippy_lints/src/doc.rs | 12 +- .../clippy_lints/src/doc_link_with_quotes.rs | 60 + .../clippy_lints/src/double_comparison.rs | 4 +- .../clippy/clippy_lints/src/double_parens.rs | 14 +- .../clippy/clippy_lints/src/duplicate_mod.rs | 102 + .../clippy_lints/src/duration_subsec.rs | 18 +- .../clippy_lints/src/else_if_without_else.rs | 2 +- .../clippy/clippy_lints/src/empty_enum.rs | 3 +- .../src/empty_structs_with_brackets.rs | 2 +- src/tools/clippy/clippy_lints/src/entry.rs | 10 +- .../clippy/clippy_lints/src/enum_clike.rs | 7 +- .../clippy/clippy_lints/src/enum_variants.rs | 7 +- src/tools/clippy/clippy_lints/src/eq_op.rs | 19 +- .../clippy_lints/src/equatable_if_let.rs | 2 +- src/tools/clippy/clippy_lints/src/escape.rs | 8 +- .../clippy/clippy_lints/src/eta_reduction.rs | 10 +- .../clippy_lints/src/excessive_bools.rs | 8 +- .../clippy/clippy_lints/src/explicit_write.rs | 46 +- .../clippy_lints/src/fallible_impl_from.rs | 4 +- .../clippy/clippy_lints/src/float_literal.rs | 10 +- .../src/floating_point_arithmetic.rs | 5 +- src/tools/clippy/clippy_lints/src/format.rs | 7 +- .../clippy/clippy_lints/src/formatting.rs | 16 +- .../clippy/clippy_lints/src/from_over_into.rs | 2 +- .../clippy/clippy_lints/src/functions/mod.rs | 5 +- .../clippy/clippy_lints/src/get_first.rs | 68 + .../clippy_lints/src/get_last_with_len.rs | 107 - .../clippy/clippy_lints/src/identity_op.rs | 125 +- .../src/if_then_some_else_none.rs | 2 +- .../clippy_lints/src/implicit_hasher.rs | 2 +- .../clippy_lints/src/implicit_return.rs | 4 +- .../src/implicit_saturating_sub.rs | 16 +- .../clippy_lints/src/index_refutable_slice.rs | 5 +- .../clippy_lints/src/indexing_slicing.rs | 43 +- .../clippy/clippy_lints/src/infinite_iter.rs | 5 +- .../clippy_lints/src/inherent_to_string.rs | 12 +- .../clippy/clippy_lints/src/int_plus_one.rs | 5 +- .../clippy_lints/src/integer_division.rs | 5 +- .../src/items_after_statements.rs | 3 +- .../clippy_lints/src/large_const_arrays.rs | 12 +- .../clippy_lints/src/large_enum_variant.rs | 92 +- .../clippy_lints/src/large_include_file.rs | 3 +- .../clippy_lints/src/large_stack_arrays.rs | 5 +- src/tools/clippy/clippy_lints/src/len_zero.rs | 12 +- .../clippy/clippy_lints/src/let_if_seq.rs | 2 +- .../clippy/clippy_lints/src/let_underscore.rs | 24 +- .../clippy_lints/src/lib.register_all.rs | 24 +- .../src/lib.register_complexity.rs | 8 +- .../src/lib.register_correctness.rs | 3 +- .../clippy_lints/src/lib.register_lints.rs | 38 +- .../clippy_lints/src/lib.register_nursery.rs | 4 +- .../clippy_lints/src/lib.register_pedantic.rs | 4 +- .../src/lib.register_restriction.rs | 8 +- .../clippy_lints/src/lib.register_style.rs | 7 +- .../src/lib.register_suspicious.rs | 6 +- src/tools/clippy/clippy_lints/src/lib.rs | 76 +- .../clippy/clippy_lints/src/lifetimes.rs | 14 +- .../src/literal_representation.rs | 32 +- .../src/loops/for_loops_over_fallibles.rs | 40 +- .../clippy/clippy_lints/src/loops/mod.rs | 50 +- .../clippy_lints/src/loops/mut_range_bound.rs | 2 +- .../src/loops/needless_range_loop.rs | 16 +- .../clippy_lints/src/loops/never_loop.rs | 16 +- .../clippy/clippy_lints/src/loops/utils.rs | 2 +- .../src/loops/while_let_on_iterator.rs | 8 +- .../clippy/clippy_lints/src/macro_use.rs | 3 +- .../clippy/clippy_lints/src/main_recursion.rs | 2 +- .../clippy_lints/src/manual_async_fn.rs | 6 +- .../clippy/clippy_lints/src/manual_bits.rs | 2 +- .../clippy/clippy_lints/src/manual_map.rs | 316 - .../clippy_lints/src/manual_non_exhaustive.rs | 14 +- .../clippy/clippy_lints/src/manual_ok_or.rs | 4 +- .../clippy/clippy_lints/src/manual_strip.rs | 2 +- .../clippy_lints/src/manual_unwrap_or.rs | 123 - .../clippy/clippy_lints/src/map_clone.rs | 6 +- .../clippy/clippy_lints/src/map_err_ignore.rs | 17 +- .../clippy/clippy_lints/src/map_unit_fn.rs | 8 +- .../clippy_lints/src/match_on_vec_items.rs | 104 - .../src/{ => matches}/collapsible_match.rs | 77 +- .../clippy_lints/src/matches/manual_map.rs | 306 + .../src/matches/manual_unwrap_or.rs | 83 + .../clippy_lints/src/matches/match_bool.rs | 4 +- .../src/matches/match_like_matches.rs | 34 +- .../src/matches/match_on_vec_items.rs | 61 + .../src/matches/match_same_arms.rs | 17 +- .../src/matches/match_single_binding.rs | 175 +- .../{ => matches}/match_str_case_mismatch.rs | 75 +- .../src/matches/match_wild_enum.rs | 3 +- .../clippy/clippy_lints/src/matches/mod.rs | 417 +- .../src/matches/needless_match.rs | 30 +- .../src/matches/overlapping_arms.rs | 19 +- .../src/matches/redundant_pattern_match.rs | 24 +- .../significant_drop_in_scrutinee.rs | 238 +- .../clippy_lints/src/matches/try_err.rs | 145 + .../clippy/clippy_lints/src/mem_replace.rs | 2 +- .../src/methods/bind_instead_of_map.rs | 6 +- .../src/methods/cloned_instead_of_copied.rs | 6 +- .../clippy_lints/src/methods/err_expect.rs | 4 +- .../clippy_lints/src/methods/expect_used.rs | 7 +- .../clippy_lints/src/methods/filter_map.rs | 35 +- .../src/methods/filter_map_next.rs | 4 +- .../src/methods/get_last_with_len.rs | 55 + .../src/methods/is_digit_ascii_radix.rs | 4 +- .../src/methods/iter_next_slice.rs | 9 +- .../src/methods/iter_overeager_cloned.rs | 97 +- .../clippy_lints/src/methods/map_unwrap_or.rs | 4 +- .../clippy/clippy_lints/src/methods/mod.rs | 737 ++- .../src/methods/no_effect_replace.rs | 47 + .../src/methods/option_as_ref_deref.rs | 8 +- .../src/methods/option_map_or_none.rs | 45 +- .../src/methods/search_is_some.rs | 4 +- .../clippy_lints/src/methods/str_splitn.rs | 10 +- .../src/methods/unnecessary_filter_map.rs | 4 +- .../src/methods/unnecessary_fold.rs | 4 +- .../src/methods/unnecessary_iter_cloned.rs | 2 +- .../src/methods/unnecessary_lazy_eval.rs | 4 +- .../src/methods/unnecessary_to_owned.rs | 44 +- .../clippy_lints/src/methods/unwrap_used.rs | 7 +- src/tools/clippy/clippy_lints/src/minmax.rs | 8 +- src/tools/clippy/clippy_lints/src/misc.rs | 98 +- .../clippy/clippy_lints/src/misc_early/mod.rs | 71 +- .../src/mismatching_type_param_order.rs | 116 + .../clippy_lints/src/missing_const_for_fn.rs | 4 +- ...e.rs => mixed_read_write_in_expression.rs} | 22 +- src/tools/clippy/clippy_lints/src/mut_key.rs | 2 +- .../clippy/clippy_lints/src/mut_reference.rs | 15 +- .../src/mutable_debug_assertion.rs | 9 +- .../clippy/clippy_lints/src/mutex_atomic.rs | 11 +- .../clippy_lints/src/needless_bitwise_bool.rs | 4 +- .../clippy/clippy_lints/src/needless_bool.rs | 11 +- .../clippy_lints/src/needless_borrowed_ref.rs | 9 +- .../clippy_lints/src/needless_for_each.rs | 4 +- .../clippy_lints/src/needless_late_init.rs | 37 +- .../src/needless_parens_on_range_literals.rs | 87 + .../src/needless_pass_by_value.rs | 6 +- .../clippy_lints/src/needless_update.rs | 7 +- .../src/neg_cmp_op_on_partial_ord.rs | 14 +- .../clippy/clippy_lints/src/neg_multiply.rs | 10 +- .../clippy_lints/src/new_without_default.rs | 1 - .../clippy/clippy_lints/src/no_effect.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 24 +- .../clippy_lints/src/non_expressive_names.rs | 2 +- .../{arithmetic.rs => numeric_arithmetic.rs} | 6 +- .../clippy/clippy_lints/src/octal_escapes.rs | 7 +- .../src/only_used_in_recursion.rs | 8 +- .../clippy_lints/src/panic_in_result_fn.rs | 2 +- .../clippy_lints/src/pass_by_ref_or_value.rs | 18 +- .../clippy_lints/src/pattern_type_mismatch.rs | 1 - src/tools/clippy/clippy_lints/src/ptr.rs | 32 +- src/tools/clippy/clippy_lints/src/ranges.rs | 136 +- .../clippy_lints/src/rc_clone_in_vec_init.rs | 139 + .../clippy_lints/src/read_zero_byte_vec.rs | 142 + .../clippy_lints/src/redundant_clone.rs | 21 +- .../src/redundant_closure_call.rs | 13 +- .../clippy_lints/src/redundant_field_names.rs | 2 +- .../clippy_lints/src/redundant_slicing.rs | 2 +- .../src/redundant_static_lifetimes.rs | 11 +- .../clippy/clippy_lints/src/reference.rs | 10 +- src/tools/clippy/clippy_lints/src/regex.rs | 2 - .../clippy/clippy_lints/src/renamed_lints.rs | 1 + .../src/return_self_not_must_use.rs | 14 +- src/tools/clippy/clippy_lints/src/returns.rs | 14 +- .../clippy_lints/src/same_name_method.rs | 18 +- src/tools/clippy/clippy_lints/src/shadow.rs | 25 +- .../src/single_char_lifetime_names.rs | 2 +- .../src/size_of_in_element_count.rs | 2 +- .../src/slow_vector_initialization.rs | 7 +- src/tools/clippy/clippy_lints/src/strings.rs | 16 +- .../clippy_lints/src/swap_ptr_to_ref.rs | 80 + .../clippy_lints/src/tabs_in_doc_comments.rs | 1 - .../clippy/clippy_lints/src/trait_bounds.rs | 13 +- .../clippy/clippy_lints/src/transmute/mod.rs | 6 +- .../src/transmute/transmute_float_to_int.rs | 2 +- .../src/transmute/transmute_ptr_to_ptr.rs | 2 +- .../src/transmute/transmute_ref_to_ref.rs | 2 +- .../src/transmute/transmute_undefined_repr.rs | 2 +- .../src/transmute/useless_transmute.rs | 54 +- src/tools/clippy/clippy_lints/src/try_err.rs | 186 - .../src/types/redundant_allocation.rs | 7 +- .../src/undocumented_unsafe_blocks.rs | 212 +- src/tools/clippy/clippy_lints/src/unicode.rs | 3 +- .../clippy/clippy_lints/src/uninit_vec.rs | 2 +- .../src/unit_return_expecting_ord.rs | 8 +- .../src/unit_types/let_unit_value.rs | 19 +- .../clippy_lints/src/unnecessary_sort_by.rs | 2 +- .../clippy_lints/src/unnested_or_patterns.rs | 8 +- .../clippy/clippy_lints/src/unused_async.rs | 5 +- .../clippy_lints/src/unused_rounding.rs | 69 + .../clippy/clippy_lints/src/unused_unit.rs | 2 +- src/tools/clippy/clippy_lints/src/use_self.rs | 24 +- .../clippy_lints/src/useless_conversion.rs | 7 +- .../clippy/clippy_lints/src/utils/author.rs | 20 +- .../clippy/clippy_lints/src/utils/conf.rs | 215 +- .../clippy_lints/src/utils/internal_lints.rs | 34 +- .../internal_lints/metadata_collector.rs | 286 +- src/tools/clippy/clippy_lints/src/vec.rs | 13 +- .../clippy_lints/src/vec_init_then_push.rs | 190 +- .../clippy_lints/src/wildcard_imports.rs | 14 +- src/tools/clippy/clippy_lints/src/write.rs | 30 +- .../clippy/clippy_lints/src/zero_div_zero.rs | 5 +- src/tools/clippy/clippy_utils/Cargo.toml | 2 +- .../clippy/clippy_utils/src/ast_utils.rs | 4 +- src/tools/clippy/clippy_utils/src/attrs.rs | 6 +- src/tools/clippy/clippy_utils/src/consts.rs | 42 +- .../clippy/clippy_utils/src/diagnostics.rs | 6 +- .../clippy/clippy_utils/src/eager_or_lazy.rs | 4 +- src/tools/clippy/clippy_utils/src/higher.rs | 21 +- .../clippy/clippy_utils/src/hir_utils.rs | 50 +- src/tools/clippy/clippy_utils/src/lib.rs | 131 +- src/tools/clippy/clippy_utils/src/msrvs.rs | 1 + .../clippy_utils/src/numeric_literal.rs | 2 +- src/tools/clippy/clippy_utils/src/paths.rs | 24 +- .../clippy_utils/src/qualify_min_const_fn.rs | 39 +- src/tools/clippy/clippy_utils/src/source.rs | 25 +- src/tools/clippy/clippy_utils/src/sugg.rs | 17 +- src/tools/clippy/clippy_utils/src/ty.rs | 32 +- src/tools/clippy/clippy_utils/src/usage.rs | 5 +- src/tools/clippy/clippy_utils/src/visitors.rs | 60 +- src/tools/clippy/lintcheck/Cargo.toml | 7 +- .../clippy/lintcheck/lintcheck_crates.toml | 2 +- src/tools/clippy/lintcheck/src/config.rs | 124 + src/tools/clippy/lintcheck/src/main.rs | 468 +- src/tools/clippy/rust-toolchain | 2 +- src/tools/clippy/src/driver.rs | 6 +- src/tools/clippy/src/main.rs | 4 + src/tools/clippy/tests/compile-test.rs | 96 +- src/tools/clippy/tests/dogfood.rs | 11 +- src/tools/clippy/tests/test_utils/mod.rs | 4 +- .../ui-cargo/duplicate_mod/fail}/Cargo.toml | 7 +- .../ui-cargo/duplicate_mod/fail/src/a.rs | 1 + .../ui-cargo/duplicate_mod/fail/src/b.rs | 1 + .../ui-cargo/duplicate_mod/fail/src/c.rs | 1 + .../fail/src/from_other_module.rs | 1 + .../ui-cargo/duplicate_mod/fail/src/main.rs | 16 + .../duplicate_mod/fail/src/main.stderr | 42 + .../fail/src/other_module/mod.rs | 2 + .../ui-internal/unnecessary_symbol_str.fixed | 1 + .../ui-internal/unnecessary_symbol_str.rs | 1 + .../ui-internal/unnecessary_symbol_str.stderr | 10 +- .../tests/ui-toml/bad_toml/conf_bad_toml.rs | 2 - .../ui-toml/bad_toml_type/conf_bad_type.rs | 3 - .../blacklisted_names.rs | 10 + .../blacklisted_names.stderr | 16 + .../blacklisted_names_append/clippy.toml | 1 + .../blacklisted_names.rs | 10 + .../blacklisted_names.stderr | 10 + .../blacklisted_names_replace/clippy.toml | 1 + .../conf_deprecated_key.rs | 3 - .../tests/ui-toml/dbg_macro/clippy.toml | 1 + .../tests/ui-toml/dbg_macro/dbg_macro.rs | 39 + .../tests/ui-toml/dbg_macro/dbg_macro.stderr | 102 + .../doc_valid_idents_append/clippy.toml | 1 + .../doc_valid_idents_append/doc_markdown.rs | 12 + .../doc_markdown.stderr | 14 + .../doc_valid_idents_replace/clippy.toml | 1 + .../doc_valid_idents_replace/doc_markdown.rs | 12 + .../doc_markdown.stderr | 36 + .../tests/ui-toml/expect_used/clippy.toml | 1 + .../tests/ui-toml/expect_used/expect_used.rs | 29 + .../ui-toml/expect_used/expect_used.stderr | 19 + .../conf_no_false_negatives.rs | 2 - .../conf_disallowed_methods.rs | 6 + .../conf_disallowed_methods.stderr | 20 +- .../toml_unknown_key/conf_unknown_key.rs | 2 - .../toml_unknown_key/conf_unknown_key.stderr | 42 +- .../tests/ui-toml/unwrap_used/clippy.toml | 1 + .../tests/ui-toml/unwrap_used/unwrap_used.rs | 73 + .../ui-toml/unwrap_used/unwrap_used.stderr | 197 + .../tests/ui/absurd-extreme-comparisons.rs | 2 +- .../ui/almost_complete_letter_range.fixed | 67 + .../tests/ui/almost_complete_letter_range.rs | 67 + .../ui/almost_complete_letter_range.stderr | 100 + src/tools/clippy/tests/ui/as_underscore.fixed | 13 + src/tools/clippy/tests/ui/as_underscore.rs | 13 + .../clippy/tests/ui/as_underscore.stderr | 20 + src/tools/clippy/tests/ui/assign_ops2.rs | 2 +- .../clippy/tests/ui/async_yields_async.fixed | 13 +- .../clippy/tests/ui/async_yields_async.rs | 13 +- .../tests/ui/auxiliary/proc_macro_attr.rs | 5 + .../proc_macro_suspicious_else_formatting.rs | 1 - .../ui/bind_instead_of_map_multipart.fixed | 62 + .../tests/ui/bind_instead_of_map_multipart.rs | 1 + .../ui/bind_instead_of_map_multipart.stderr | 30 +- src/tools/clippy/tests/ui/blacklisted_name.rs | 4 +- .../clippy/tests/ui/borrow_deref_ref.fixed | 59 + src/tools/clippy/tests/ui/borrow_deref_ref.rs | 59 + .../clippy/tests/ui/borrow_deref_ref.stderr | 22 + .../tests/ui/borrow_deref_ref_unfixable.rs | 10 + .../ui/borrow_deref_ref_unfixable.stderr | 18 + .../branches_sharing_code/false_positives.rs | 15 +- .../shared_at_bottom.stderr | 28 +- .../ui/branches_sharing_code/shared_at_top.rs | 2 +- .../shared_at_top.stderr | 18 +- .../shared_at_top_and_bottom.stderr | 51 +- .../branches_sharing_code/valid_if_blocks.rs | 2 +- .../tests/ui/cast_abs_to_unsigned.fixed | 21 + .../clippy/tests/ui/cast_abs_to_unsigned.rs | 21 + .../tests/ui/cast_abs_to_unsigned.stderr | 92 +- .../clippy/tests/ui/cast_size_32bit.stderr | 14 - .../clippy/tests/ui/checked_conversions.fixed | 7 +- .../clippy/tests/ui/checked_conversions.rs | 7 +- .../tests/ui/checked_conversions.stderr | 32 +- .../ui/cmp_owned/asymmetric_partial_eq.fixed | 2 +- .../ui/cmp_owned/asymmetric_partial_eq.rs | 2 +- .../tests/ui/cmp_owned/with_suggestion.fixed | 4 +- .../tests/ui/cmp_owned/with_suggestion.rs | 4 +- .../tests/ui/cmp_owned/without_suggestion.rs | 26 +- .../ui/cmp_owned/without_suggestion.stderr | 2 +- .../clippy/tests/ui/collapsible_match2.rs | 2 +- .../clippy/tests/ui/collapsible_match2.stderr | 4 +- .../ui/crashes/auxiliary/proc_macro_crash.rs | 1 - src/tools/clippy/tests/ui/crashes/ice-6254.rs | 1 + .../clippy/tests/ui/crashes/ice-6254.stderr | 2 +- .../clippy/tests/ui/crashes/ice-6256.stderr | 22 +- src/tools/clippy/tests/ui/crashes/ice-8821.rs | 8 + .../clippy/tests/ui/crashes/ice-8821.stderr | 10 + src/tools/clippy/tests/ui/crashes/ice-8850.rs | 27 + .../clippy/tests/ui/crashes/ice-8850.stderr | 45 + src/tools/clippy/tests/ui/dbg_macro.rs | 12 + src/tools/clippy/tests/ui/dbg_macro.stderr | 35 +- .../tests/ui/debug_assert_with_mut_call.rs | 2 +- .../ui/default_numeric_fallback_i32.fixed | 6 + .../tests/ui/default_numeric_fallback_i32.rs | 6 + .../ui/default_numeric_fallback_i32.stderr | 50 +- .../clippy/tests/ui/deref_by_slicing.fixed | 1 + src/tools/clippy/tests/ui/deref_by_slicing.rs | 1 + .../clippy/tests/ui/deref_by_slicing.stderr | 18 +- .../clippy/tests/ui/derive_hash_xor_eq.rs | 2 + .../clippy/tests/ui/derive_hash_xor_eq.stderr | 16 +- .../ui/derive_partial_eq_without_eq.fixed | 126 + .../tests/ui/derive_partial_eq_without_eq.rs | 126 + .../ui/derive_partial_eq_without_eq.stderr | 70 + .../clippy/tests/ui/doc_link_with_quotes.rs | 12 + .../tests/ui/doc_link_with_quotes.stderr | 10 + .../ui/empty_line_after_outer_attribute.rs | 7 + src/tools/clippy/tests/ui/entry.stderr | 41 +- .../clippy/tests/ui/entry_with_else.stderr | 17 +- .../tests/ui/eprint_with_newline.stderr | 16 +- .../clippy/tests/ui/equatable_if_let.fixed | 2 +- src/tools/clippy/tests/ui/equatable_if_let.rs | 2 +- src/tools/clippy/tests/ui/eta.fixed | 12 + src/tools/clippy/tests/ui/eta.rs | 12 + .../tests/ui/explicit_deref_methods.fixed | 7 +- .../clippy/tests/ui/explicit_deref_methods.rs | 7 +- .../tests/ui/explicit_deref_methods.stderr | 24 +- .../tests/ui/for_loops_over_fallibles.rs | 17 +- .../tests/ui/for_loops_over_fallibles.stderr | 40 +- src/tools/clippy/tests/ui/forget_ref.rs | 1 + src/tools/clippy/tests/ui/forget_ref.stderr | 36 +- .../ui/from_iter_instead_of_collect.fixed | 1 - .../tests/ui/from_iter_instead_of_collect.rs | 1 - .../ui/from_iter_instead_of_collect.stderr | 30 +- src/tools/clippy/tests/ui/get_first.fixed | 42 + src/tools/clippy/tests/ui/get_first.rs | 42 + src/tools/clippy/tests/ui/get_first.stderr | 22 + .../clippy/tests/ui/get_last_with_len.fixed | 28 +- .../clippy/tests/ui/get_last_with_len.rs | 28 +- .../clippy/tests/ui/get_last_with_len.stderr | 36 +- src/tools/clippy/tests/ui/get_unwrap.fixed | 3 +- src/tools/clippy/tests/ui/get_unwrap.rs | 3 +- src/tools/clippy/tests/ui/get_unwrap.stderr | 52 +- src/tools/clippy/tests/ui/identity_op.fixed | 119 + src/tools/clippy/tests/ui/identity_op.rs | 63 +- src/tools/clippy/tests/ui/identity_op.stderr | 260 +- .../clippy/tests/ui/implicit_clone.fixed | 118 + src/tools/clippy/tests/ui/implicit_clone.rs | 3 +- .../clippy/tests/ui/implicit_clone.stderr | 24 +- src/tools/clippy/tests/ui/infinite_iter.rs | 1 - .../clippy/tests/ui/infinite_iter.stderr | 2 +- src/tools/clippy/tests/ui/issue_2356.fixed | 26 + src/tools/clippy/tests/ui/issue_2356.rs | 2 + src/tools/clippy/tests/ui/issue_2356.stderr | 4 +- .../clippy/tests/ui/iter_next_slice.fixed | 8 +- src/tools/clippy/tests/ui/iter_next_slice.rs | 4 +- .../clippy/tests/ui/iter_next_slice.stderr | 4 +- .../tests/ui/iter_overeager_cloned.fixed | 6 +- .../clippy/tests/ui/iter_overeager_cloned.rs | 3 + .../tests/ui/iter_overeager_cloned.stderr | 42 +- .../clippy/tests/ui/large_enum_variant.rs | 32 + .../clippy/tests/ui/large_enum_variant.stderr | 68 +- src/tools/clippy/tests/ui/let_unit.stderr | 3 +- .../clippy/tests/ui/manual_async_fn.stderr | 9 +- .../clippy/tests/ui/manual_filter_map.fixed | 50 + .../clippy/tests/ui/manual_filter_map.rs | 59 + .../clippy/tests/ui/manual_filter_map.stderr | 74 +- .../clippy/tests/ui/manual_find_map.fixed | 50 + src/tools/clippy/tests/ui/manual_find_map.rs | 59 + .../clippy/tests/ui/manual_find_map.stderr | 74 +- .../clippy/tests/ui/manual_map_option.fixed | 1 + .../clippy/tests/ui/manual_map_option.rs | 1 + .../clippy/tests/ui/manual_map_option.stderr | 42 +- .../clippy/tests/ui/manual_split_once.stderr | 20 +- .../clippy/tests/ui/manual_str_repeat.fixed | 2 +- .../clippy/tests/ui/manual_str_repeat.rs | 2 +- src/tools/clippy/tests/ui/map_err.rs | 1 - src/tools/clippy/tests/ui/map_err.stderr | 2 +- .../clippy/tests/ui/map_flatten_fixable.fixed | 37 + .../clippy/tests/ui/map_flatten_fixable.rs | 36 + .../tests/ui/map_flatten_fixable.stderr | 28 +- .../clippy/tests/ui/map_unwrap_or.stderr | 8 +- .../clippy/tests/ui/match_ref_pats.fixed | 118 + src/tools/clippy/tests/ui/match_ref_pats.rs | 3 +- .../clippy/tests/ui/match_ref_pats.stderr | 10 +- .../tests/ui/match_single_binding.fixed | 13 + .../clippy/tests/ui/match_single_binding.rs | 14 + .../tests/ui/match_single_binding.stderr | 38 +- .../tests/ui/match_single_binding2.stderr | 4 +- .../tests/ui/match_str_case_mismatch.fixed | 186 + .../tests/ui/match_str_case_mismatch.rs | 2 + .../tests/ui/match_str_case_mismatch.stderr | 14 +- src/tools/clippy/tests/ui/methods.rs | 1 - src/tools/clippy/tests/ui/methods.stderr | 4 +- .../tests/ui/mismatching_type_param_order.rs | 60 + .../ui/mismatching_type_param_order.stderr | 83 + ...e.rs => mixed_read_write_in_expression.rs} | 2 +- ... => mixed_read_write_in_expression.stderr} | 18 +- src/tools/clippy/tests/ui/modulo_one.rs | 2 +- src/tools/clippy/tests/ui/modulo_one.stderr | 10 +- .../clippy/tests/ui/needless_borrow.fixed | 9 + src/tools/clippy/tests/ui/needless_borrow.rs | 9 + .../clippy/tests/ui/needless_borrow.stderr | 32 +- .../ui/needless_for_each_unfixable.stderr | 3 +- .../clippy/tests/ui/needless_late_init.fixed | 273 + .../clippy/tests/ui/needless_late_init.rs | 44 +- .../clippy/tests/ui/needless_late_init.stderr | 97 +- .../tests/ui/needless_late_init_fixable.fixed | 19 - .../tests/ui/needless_late_init_fixable.rs | 19 - .../ui/needless_late_init_fixable.stderr | 70 - .../clippy/tests/ui/needless_lifetimes.rs | 3 +- .../clippy/tests/ui/needless_lifetimes.stderr | 62 +- .../needless_parens_on_range_literals.fixed | 14 + .../ui/needless_parens_on_range_literals.rs | 14 + .../needless_parens_on_range_literals.stderr | 40 + .../clippy/tests/ui/needless_return.fixed | 10 +- src/tools/clippy/tests/ui/needless_return.rs | 6 + .../clippy/tests/ui/needless_return.stderr | 20 +- src/tools/clippy/tests/ui/never_loop.rs | 17 + .../tests/ui/new_without_default.stderr | 3 +- .../clippy/tests/ui/no_effect_replace.rs | 51 + .../clippy/tests/ui/no_effect_replace.stderr | 52 + .../tests/ui/nonminimal_bool_methods.fixed | 111 + .../tests/ui/nonminimal_bool_methods.rs | 1 + .../tests/ui/nonminimal_bool_methods.stderr | 26 +- .../clippy/tests/ui/print_literal.stderr | 22 +- .../clippy/tests/ui/print_with_newline.stderr | 16 +- src/tools/clippy/tests/ui/ptr_arg.stderr | 3 +- .../clippy/tests/ui/range_contains.fixed | 15 +- src/tools/clippy/tests/ui/range_contains.rs | 15 +- .../clippy/tests/ui/range_contains.stderr | 38 +- src/tools/clippy/tests/ui/rc_buffer.fixed | 28 + src/tools/clippy/tests/ui/rc_buffer.rs | 2 + src/tools/clippy/tests/ui/rc_buffer.stderr | 16 +- src/tools/clippy/tests/ui/rc_buffer_arc.fixed | 27 + src/tools/clippy/tests/ui/rc_buffer_arc.rs | 2 + .../clippy/tests/ui/rc_buffer_arc.stderr | 16 +- .../tests/ui/rc_clone_in_vec_init/arc.rs | 68 + .../tests/ui/rc_clone_in_vec_init/arc.stderr | 109 + .../tests/ui/rc_clone_in_vec_init/rc.rs | 69 + .../tests/ui/rc_clone_in_vec_init/rc.stderr | 109 + .../tests/ui/rc_clone_in_vec_init/weak.rs | 83 + .../tests/ui/rc_clone_in_vec_init/weak.stderr | 201 + .../clippy/tests/ui/read_zero_byte_vec.rs | 87 + .../clippy/tests/ui/read_zero_byte_vec.stderr | 64 + .../clippy/tests/ui/recursive_format_impl.rs | 3 +- .../tests/ui/recursive_format_impl.stderr | 31 +- .../clippy/tests/ui/redundant_allocation.rs | 35 + .../tests/ui/redundant_allocation.stderr | 38 +- .../tests/ui/ref_binding_to_reference.rs | 10 + .../tests/ui/ref_binding_to_reference.stderr | 14 +- src/tools/clippy/tests/ui/rename.fixed | 2 + src/tools/clippy/tests/ui/rename.rs | 2 + src/tools/clippy/tests/ui/rename.stderr | 76 +- src/tools/clippy/tests/ui/same_name_method.rs | 16 + .../clippy/tests/ui/same_name_method.stderr | 20 +- src/tools/clippy/tests/ui/self_assignment.rs | 2 +- src/tools/clippy/tests/ui/shadow.rs | 7 + .../tests/ui/significant_drop_in_scrutinee.rs | 198 +- .../ui/significant_drop_in_scrutinee.stderr | 107 +- .../ui/suspicious_operation_groupings.fixed | 209 + .../ui/suspicious_operation_groupings.rs | 3 +- .../ui/suspicious_operation_groupings.stderr | 52 +- .../clippy/tests/ui/swap_ptr_to_ref.fixed | 24 + src/tools/clippy/tests/ui/swap_ptr_to_ref.rs | 24 + .../clippy/tests/ui/swap_ptr_to_ref.stderr | 28 + .../tests/ui/swap_ptr_to_ref_unfixable.rs | 18 + .../tests/ui/swap_ptr_to_ref_unfixable.stderr | 22 + src/tools/clippy/tests/ui/transmute.rs | 19 +- src/tools/clippy/tests/ui/transmute.stderr | 88 +- .../tests/ui/transmute_undefined_repr.rs | 2 +- .../tests/ui/undocumented_unsafe_blocks.rs | 153 +- .../ui/undocumented_unsafe_blocks.stderr | 118 +- src/tools/clippy/tests/ui/unicode.fixed | 36 + src/tools/clippy/tests/ui/unicode.rs | 1 + src/tools/clippy/tests/ui/unicode.stderr | 14 +- src/tools/clippy/tests/ui/unit_arg.stderr | 8 +- .../tests/ui/unit_arg_empty_blocks.fixed | 30 + .../clippy/tests/ui/unit_arg_empty_blocks.rs | 1 + .../tests/ui/unit_arg_empty_blocks.stderr | 8 +- src/tools/clippy/tests/ui/unit_cmp.rs | 6 +- src/tools/clippy/tests/ui/unit_cmp.stderr | 12 +- .../clippy/tests/ui/unnecessary_cast.fixed | 91 + src/tools/clippy/tests/ui/unnecessary_cast.rs | 54 +- .../clippy/tests/ui/unnecessary_cast.stderr | 120 +- .../tests/ui/unnecessary_cast_fixable.fixed | 50 - .../tests/ui/unnecessary_cast_fixable.rs | 50 - .../tests/ui/unnecessary_cast_fixable.stderr | 106 - .../tests/ui/unnecessary_iter_cloned.stderr | 4 +- .../tests/ui/unnecessary_to_owned.fixed | 61 +- .../clippy/tests/ui/unnecessary_to_owned.rs | 61 +- .../tests/ui/unnecessary_to_owned.stderr | 36 +- .../clippy/tests/ui/unnecessary_wraps.stderr | 6 +- .../clippy/tests/ui/unused_rounding.fixed | 9 + src/tools/clippy/tests/ui/unused_rounding.rs | 9 + .../clippy/tests/ui/unused_rounding.stderr | 22 + src/tools/clippy/tests/ui/use_self.fixed | 66 + src/tools/clippy/tests/ui/use_self.rs | 66 + src/tools/clippy/tests/ui/use_self.stderr | 62 +- .../clippy/tests/ui/useless_conversion_try.rs | 2 - .../tests/ui/useless_conversion_try.stderr | 18 +- .../clippy/tests/ui/vec_init_then_push.rs | 60 + .../clippy/tests/ui/vec_init_then_push.stderr | 36 +- .../clippy/tests/ui/write_literal.stderr | 22 +- .../clippy/tests/ui/write_literal_2.stderr | 10 +- .../clippy/tests/ui/write_with_newline.stderr | 16 +- src/tools/compiletest/src/common.rs | 3 - src/tools/compiletest/src/header.rs | 1 - src/tools/compiletest/src/raise_fd_limit.rs | 2 +- src/tools/compiletest/src/read2.rs | 157 +- src/tools/compiletest/src/read2/tests.rs | 123 + src/tools/compiletest/src/runtest.rs | 114 +- src/tools/compiletest/src/util.rs | 1 + src/tools/lint-docs/src/lib.rs | 6 +- src/tools/lld-wrapper/Cargo.toml | 6 - src/tools/lld-wrapper/src/main.rs | 95 +- src/tools/rustc-workspace-hack/Cargo.toml | 2 + src/tools/rustdoc-gui/tester.js | 19 +- src/tools/rustdoc-js/tester.js | 305 +- .../rustfmt/.github/workflows/integration.yml | 2 +- src/tools/rustfmt/.github/workflows/linux.yml | 16 +- src/tools/rustfmt/.github/workflows/mac.yml | 12 +- .../.github/workflows/rustdoc_check.yml | 2 +- .../.github/workflows/upload-assets.yml | 2 +- .../rustfmt/.github/workflows/windows.yml | 13 +- src/tools/rustfmt/CHANGELOG.md | 97 +- src/tools/rustfmt/Cargo.lock | 415 +- src/tools/rustfmt/Cargo.toml | 49 +- src/tools/rustfmt/Configurations.md | 69 +- src/tools/rustfmt/ci/build_and_test.bat | 14 + src/tools/rustfmt/ci/build_and_test.sh | 18 + src/tools/rustfmt/ci/integration.sh | 2 +- .../rustfmt/config_proc_macro/Cargo.lock | 44 +- .../rustfmt/config_proc_macro/src/lib.rs | 4 + src/tools/rustfmt/rust-toolchain | 2 +- src/tools/rustfmt/src/cargo-fmt/main.rs | 35 +- src/tools/rustfmt/src/cargo-fmt/test/mod.rs | 42 +- src/tools/rustfmt/src/comment.rs | 6 +- src/tools/rustfmt/src/config/config_type.rs | 22 - src/tools/rustfmt/src/config/license.rs | 265 - src/tools/rustfmt/src/config/mod.rs | 41 +- src/tools/rustfmt/src/format-diff/main.rs | 45 +- .../rustfmt/src/format_report_formatter.rs | 3 +- src/tools/rustfmt/src/formatting.rs | 62 +- src/tools/rustfmt/src/imports.rs | 428 +- src/tools/rustfmt/src/issues.rs | 309 - src/tools/rustfmt/src/items.rs | 4 +- src/tools/rustfmt/src/lib.rs | 14 +- src/tools/rustfmt/src/macros.rs | 4 +- src/tools/rustfmt/src/overflow.rs | 12 +- src/tools/rustfmt/src/parse/session.rs | 10 +- src/tools/rustfmt/src/reorder.rs | 25 +- src/tools/rustfmt/src/string.rs | 45 +- src/tools/rustfmt/src/test/mod.rs | 39 +- src/tools/rustfmt/src/utils.rs | 16 +- .../rustfmt/tests/config/issue-3802.toml | 2 - .../rustfmt/tests/config/small_tabs.toml | 2 - .../rustfmt/tests/license-template/lt.txt | 2 - src/tools/rustfmt/tests/rustfmt/main.rs | 2 +- .../tests/source/cfg_if/detect/arch/x86.rs | 2 +- .../doc_comment_code_block_width/100.rs | 16 + .../100_greater_max_width.rs | 17 + .../doc_comment_code_block_width/50.rs | 16 + .../StdExternalCrate-non_consecutive.rs | 27 + src/tools/rustfmt/tests/source/fn-simple.rs | 2 +- .../{ => imports}/imports-impl-only-use.rs | 0 .../imports-reorder-lines-and-items.rs | 0 .../{ => imports}/imports-reorder-lines.rs | 0 .../source/{ => imports}/imports-reorder.rs | 0 .../tests/source/{ => imports}/imports.rs | 0 .../{ => imports}/imports_block_indent.rs | 0 .../imports_granularity_crate.rs | 28 + .../imports_granularity_default-with-dups.rs | 6 + ...m-with-dups-StdExternalCrate-no-reorder.rs | 13 + .../imports_granularity_item-with-dups.rs | 11 + .../imports/imports_granularity_item.rs | 34 + .../imports/imports_granularity_module.rs | 47 + .../tests/source/imports_granularity_item.rs | 6 - .../source/imports_granularity_module.rs | 19 - .../tests/source/imports_granularity_one.rs | 28 + .../imports_raw_identifiers/version_One.rs | 5 + .../imports_raw_identifiers/version_Two.rs | 5 + src/tools/rustfmt/tests/source/issue-5030.rs | 22 + src/tools/rustfmt/tests/source/issue-5260.rs | 14 + .../license-templates/empty_license_path.rs | 5 - .../tests/source/license-templates/license.rs | 6 - .../rustfmt/tests/source/pub-restricted.rs | 13 - .../tests/source/struct_field_doc_comment.rs | 72 + .../tests/target/cfg_if/detect/arch/x86.rs | 2 +- .../doc_comment_code_block_width/100.rs | 16 + .../100_greater_max_width.rs | 29 + .../doc_comment_code_block_width/50.rs | 22 + .../StdExternalCrate-non_consecutive.rs | 18 + src/tools/rustfmt/tests/target/fn-simple.rs | 2 +- .../{ => imports}/import-fencepost-length.rs | 0 .../{ => imports}/imports-impl-only-use.rs | 0 .../imports-reorder-lines-and-items.rs | 0 .../{ => imports}/imports-reorder-lines.rs | 0 .../target/{ => imports}/imports-reorder.rs | 0 .../tests/target/{ => imports}/imports.rs | 0 .../{ => imports}/imports_2021_edition.rs | 0 .../{ => imports}/imports_block_indent.rs | 0 .../imports_granularity_crate.rs | 31 + .../imports_granularity_default-with-dups.rs | 6 + ...m-with-dups-StdExternalCrate-no-reorder.rs | 7 + .../imports_granularity_item-with-dups.rs | 5 + .../imports/imports_granularity_item.rs | 45 + .../imports/imports_granularity_module.rs | 55 + .../tests/target/imports_granularity_item.rs | 13 - .../target/imports_granularity_module.rs | 22 - .../tests/target/imports_granularity_one.rs | 46 +- .../imports_raw_identifiers/version_One.rs | 5 + .../imports_raw_identifiers/version_Two.rs | 5 + src/tools/rustfmt/tests/target/issue-5030.rs | 21 + src/tools/rustfmt/tests/target/issue-5260.rs | 13 + src/tools/rustfmt/tests/target/issue_3937.rs | 13 + src/tools/rustfmt/tests/target/issue_4573.rs | 245 + src/tools/rustfmt/tests/target/issue_5399.rs | 48 + .../license-templates/empty_license_path.rs | 5 - .../tests/target/license-templates/license.rs | 6 - .../rustfmt/tests/target/pub-restricted.rs | 13 - .../tests/target/struct_field_doc_comment.rs | 69 + src/tools/tidy/src/deps.rs | 1 + src/tools/tidy/src/error_codes_check.rs | 4 +- src/tools/tidy/src/ui_tests.rs | 4 +- src/version | 2 +- .../.cargo-checksum.json | 1 + vendor/annotate-snippets-0.8.0/CHANGELOG.md | 29 + vendor/annotate-snippets-0.8.0/Cargo.lock | 630 ++ vendor/annotate-snippets-0.8.0/Cargo.toml | 62 + .../LICENSE-APACHE | 0 vendor/annotate-snippets-0.8.0/LICENSE-MIT | 19 + vendor/annotate-snippets-0.8.0/README.md | 92 + .../annotate-snippets-0.8.0/benches/simple.rs | 74 + .../examples/expected_type.rs | 43 + .../examples/footer.rs | 39 + .../examples/format.rs | 61 + .../examples/multislice.rs | 38 + .../src/display_list/from_snippet.rs | 517 ++ .../src/display_list/mod.rs | 37 + .../src/display_list/structs.rs | 191 + .../src/formatter/mod.rs | 397 ++ .../src/formatter/style.rs | 52 + vendor/annotate-snippets-0.8.0/src/lib.rs | 54 + vendor/annotate-snippets-0.8.0/src/snippet.rs | 88 + .../src/stylesheets/color.rs | 50 + .../src/stylesheets/mod.rs | 11 + .../src/stylesheets/no_color.rs | 31 + .../annotate-snippets-0.8.0/tests/diff/mod.rs | 43 + .../tests/dl_from_snippet.rs | 401 ++ .../no-color/multiline_annotation.toml | 40 + .../no-color/multiline_annotation.txt | 14 + .../no-color/multiline_annotation2.toml | 18 + .../no-color/multiline_annotation2.txt | 9 + .../no-color/multiline_annotation3.toml | 18 + .../no-color/multiline_annotation3.txt | 9 + .../no-color/multiple_annotations.toml | 25 + .../no-color/multiple_annotations.txt | 14 + .../tests/fixtures/no-color/simple.toml | 18 + .../tests/fixtures/no-color/simple.txt | 9 + .../tests/fixtures_test.rs | 45 + .../tests/formatter.rs | 552 ++ .../tests/snippet/mod.rs | 167 + vendor/annotate-snippets/.cargo-checksum.json | 2 +- vendor/annotate-snippets/CHANGELOG.md | 10 + vendor/annotate-snippets/Cargo.lock | 391 +- vendor/annotate-snippets/Cargo.toml | 5 +- vendor/annotate-snippets/README.md | 60 +- .../examples/expected_type.rs | 2 +- .../src/display_list/from_snippet.rs | 165 +- .../src/display_list/structs.rs | 121 +- vendor/annotate-snippets/src/formatter/mod.rs | 73 +- .../annotate-snippets/src/formatter/style.rs | 3 +- vendor/annotate-snippets/src/lib.rs | 4 +- .../annotate-snippets/src/stylesheets/mod.rs | 2 +- .../tests/dl_from_snippet.rs | 6 + .../tests/fixtures/no-color/issue_9.toml | 28 + .../tests/fixtures/no-color/issue_9.txt | 12 + .../no-color/multiline_annotation.toml | 2 +- .../no-color/multiline_annotation2.toml | 2 +- .../tests/fixtures/no-color/strip_line.toml | 25 + .../tests/fixtures/no-color/strip_line.txt | 6 + .../fixtures/no-color/strip_line_char.toml | 25 + .../fixtures/no-color/strip_line_char.txt | 6 + .../fixtures/no-color/strip_line_non_ws.toml | 25 + .../fixtures/no-color/strip_line_non_ws.txt | 6 + vendor/annotate-snippets/tests/formatter.rs | 123 + vendor/annotate-snippets/tests/snippet/mod.rs | 43 +- vendor/anyhow/.cargo-checksum.json | 2 +- vendor/anyhow/Cargo.toml | 2 +- vendor/anyhow/src/lib.rs | 2 +- vendor/anyhow/src/macros.rs | 22 - vendor/anyhow/tests/ui/must-use.stderr | 2 +- vendor/anyhow/tests/ui/no-impl.stderr | 2 +- vendor/camino/.cargo-checksum.json | 2 +- vendor/camino/CHANGELOG.md | 18 + vendor/camino/Cargo.toml | 35 +- vendor/camino/README.md | 8 +- vendor/camino/src/lib.rs | 290 +- vendor/camino/src/proptest_impls.rs | 61 + vendor/camino/src/serde_impls.rs | 2 + vendor/clap/.cargo-checksum.json | 2 +- vendor/clap/Cargo.lock | 532 +- vendor/clap/Cargo.toml | 232 +- vendor/clap/README.md | 36 +- vendor/clap/benches/01_default.rs | 15 - vendor/clap/benches/02_simple.rs | 104 - vendor/clap/benches/03_complex.rs | 307 - vendor/clap/benches/04_new_help.rs | 223 - vendor/clap/benches/05_ripgrep.rs | 952 --- vendor/clap/benches/06_rustup.rs | 412 -- vendor/clap/examples/README.md | 26 +- vendor/clap/examples/cargo-example-derive.rs | 2 +- vendor/clap/examples/cargo-example.rs | 6 +- vendor/clap/examples/demo.rs | 4 +- vendor/clap/examples/derive_ref/README.md | 176 +- .../clap/examples/derive_ref/augment_args.rs | 30 + .../derive_ref/augment_subcommands.rs | 21 + .../clap/examples/derive_ref/custom-bool.md | 4 +- .../clap/examples/derive_ref/custom-bool.rs | 10 +- .../examples/derive_ref/flatten_hand_args.rs | 81 + .../examples/derive_ref/hand_subcommand.rs | 81 + .../clap/examples/derive_ref/interop_tests.md | 256 + .../examples/escaped-positional-derive.rs | 6 +- vendor/clap/examples/escaped-positional.rs | 31 +- vendor/clap/examples/git-derive.md | 57 + vendor/clap/examples/git-derive.rs | 56 +- vendor/clap/examples/git.md | 57 + vendor/clap/examples/git.rs | 59 +- vendor/clap/examples/keyvalue-derive.md | 31 - vendor/clap/examples/multicall-busybox.rs | 8 +- vendor/clap/examples/multicall-hostname.rs | 5 +- vendor/clap/examples/pacman.rs | 30 +- vendor/clap/examples/repl.rs | 92 + .../examples/tutorial_builder/01_quick.rs | 33 +- .../tutorial_builder/02_app_settings.rs | 19 +- .../clap/examples/tutorial_builder/02_apps.rs | 10 +- .../examples/tutorial_builder/02_crate.rs | 12 +- .../tutorial_builder/03_01_flag_bool.rs | 20 +- .../tutorial_builder/03_01_flag_count.rs | 15 +- .../examples/tutorial_builder/03_02_option.rs | 4 +- .../tutorial_builder/03_03_positional.rs | 4 +- .../tutorial_builder/03_04_subcommands.rs | 4 +- .../tutorial_builder/03_05_default_values.rs | 4 +- .../examples/tutorial_builder/04_01_enum.rs | 40 +- .../tutorial_builder/04_01_possible.rs | 7 +- .../examples/tutorial_builder/04_02_parse.rs | 10 +- .../tutorial_builder/04_02_validate.rs | 45 +- .../tutorial_builder/04_03_relations.rs | 45 +- .../examples/tutorial_builder/04_04_custom.rs | 51 +- .../examples/tutorial_builder/05_01_assert.rs | 10 +- .../clap/examples/tutorial_builder/README.md | 148 +- .../clap/examples/tutorial_derive/01_quick.rs | 9 +- .../tutorial_derive/02_app_settings.rs | 5 +- .../clap/examples/tutorial_derive/02_apps.rs | 4 +- .../clap/examples/tutorial_derive/02_crate.rs | 4 +- .../tutorial_derive/03_01_flag_bool.rs | 2 +- .../tutorial_derive/03_01_flag_count.rs | 4 +- .../examples/tutorial_derive/03_02_option.rs | 2 +- .../tutorial_derive/03_03_positional.rs | 1 + .../tutorial_derive/03_04_subcommands.rs | 5 +- .../tutorial_derive/03_04_subcommands_alt.rs | 33 + .../tutorial_derive/03_05_default_values.rs | 2 +- .../examples/tutorial_derive/04_01_enum.rs | 2 +- .../examples/tutorial_derive/04_02_parse.rs | 4 +- .../tutorial_derive/04_02_validate.rs | 35 +- .../tutorial_derive/04_03_relations.rs | 14 +- .../examples/tutorial_derive/04_04_custom.rs | 15 +- .../examples/tutorial_derive/05_01_assert.rs | 4 +- .../clap/examples/tutorial_derive/README.md | 159 +- vendor/clap/examples/typed-derive.md | 86 + .../{keyvalue-derive.rs => typed-derive.rs} | 19 +- vendor/clap/src/bin/stdio-fixture.rs | 14 + vendor/clap/src/build/mod.rs | 38 - vendor/clap/src/builder/action.rs | 325 + .../src/{build => builder}/app_settings.rs | 383 +- vendor/clap/src/{build => builder}/arg.rs | 1134 ++-- .../clap/src/{build => builder}/arg_group.rs | 31 +- .../src/{build => builder}/arg_predicate.rs | 0 .../src/{build => builder}/arg_settings.rs | 221 +- vendor/clap/src/{build => builder}/command.rs | 841 ++- .../src/{build => builder}/debug_asserts.rs | 237 +- vendor/clap/src/{build => builder}/macros.rs | 0 vendor/clap/src/builder/mod.rs | 61 + .../src/{build => builder}/possible_value.rs | 59 +- vendor/clap/src/{build => builder}/regex.rs | 0 vendor/clap/src/{build => builder}/tests.rs | 2 +- .../src/{build => builder}/usage_parser.rs | 9 +- .../clap/src/{build => builder}/value_hint.rs | 2 +- vendor/clap/src/builder/value_parser.rs | 2089 ++++++ vendor/clap/src/derive.rs | 187 +- vendor/clap/src/error/kind.rs | 9 +- vendor/clap/src/error/mod.rs | 133 +- vendor/clap/src/lib.rs | 76 +- vendor/clap/src/macros.rs | 185 +- vendor/clap/src/mkeymap.rs | 17 +- vendor/clap/src/output/fmt.rs | 49 +- vendor/clap/src/output/help.rs | 306 +- vendor/clap/src/output/usage.rs | 34 +- vendor/clap/src/parse/arg_matcher.rs | 216 - vendor/clap/src/parse/matches/matched_arg.rs | 365 -- vendor/clap/src/parse/matches/mod.rs | 9 - vendor/clap/src/parse/mod.rs | 13 - vendor/clap/src/parse/parser.rs | 1611 ----- vendor/clap/src/parser/arg_matcher.rs | 282 + vendor/clap/src/parser/error.rs | 56 + .../src/{parse => parser}/features/mod.rs | 0 .../{parse => parser}/features/suggestions.rs | 4 +- vendor/clap/src/parser/matches/any_value.rs | 112 + .../{parse => parser}/matches/arg_matches.rs | 1440 +++-- vendor/clap/src/parser/matches/matched_arg.rs | 240 + vendor/clap/src/parser/matches/mod.rs | 17 + .../{parse => parser}/matches/value_source.rs | 0 vendor/clap/src/parser/mod.rs | 27 + vendor/clap/src/parser/parser.rs | 1727 +++++ .../clap/src/{parse => parser}/validator.rs | 369 +- vendor/clap/src/util/mod.rs | 4 +- vendor/clap/src/util/str_to_bool.rs | 14 +- vendor/clap_derive/.cargo-checksum.json | 1 + vendor/clap_derive/Cargo.toml | 84 + .../{structopt => clap_derive}/LICENSE-APACHE | 0 .../LICENSE-MIT | 2 +- vendor/clap_derive/README.md | 24 + vendor/clap_derive/src/attrs.rs | 1259 ++++ vendor/clap_derive/src/derives/args.rs | 796 +++ vendor/clap_derive/src/derives/into_app.rs | 119 + vendor/clap_derive/src/derives/mod.rs | 23 + vendor/clap_derive/src/derives/parser.rs | 95 + vendor/clap_derive/src/derives/subcommand.rs | 678 ++ vendor/clap_derive/src/derives/value_enum.rs | 124 + vendor/clap_derive/src/dummies.rs | 91 + vendor/clap_derive/src/lib.rs | 74 + .../src/parse.rs | 160 +- .../src/utils}/doc_comments.rs | 10 +- vendor/clap_derive/src/utils/mod.rs | 9 + .../src => clap_derive/src/utils}/spanned.rs | 17 +- .../src => clap_derive/src/utils}/ty.rs | 46 +- vendor/clap_lex/.cargo-checksum.json | 1 + vendor/clap_lex/Cargo.toml | 89 + .../LICENSE-APACHE | 5 +- .../LICENSE-MIT | 4 +- vendor/clap_lex/README.md | 19 + vendor/clap_lex/src/lib.rs | 484 ++ vendor/compiler_builtins/.cargo-checksum.json | 2 +- vendor/compiler_builtins/Cargo.lock | 2 +- vendor/compiler_builtins/Cargo.toml | 2 +- vendor/compiler_builtins/build.rs | 23 +- vendor/compiler_builtins/src/arm_linux.rs | 4 +- vendor/compiler_builtins/src/float/conv.rs | 525 +- vendor/compiler_builtins/src/int/mul.rs | 1 + vendor/compiler_builtins/src/int/sdiv.rs | 3 + vendor/compiler_builtins/src/int/udiv.rs | 7 + vendor/compiler_builtins/src/lib.rs | 4 +- vendor/compiler_builtins/src/macros.rs | 60 +- .../src/{riscv32.rs => riscv.rs} | 16 + vendor/compiletest_rs/.cargo-checksum.json | 2 +- vendor/compiletest_rs/Cargo.toml | 19 +- vendor/compiletest_rs/src/header.rs | 22 +- vendor/compiletest_rs/src/lib.rs | 205 +- vendor/compiletest_rs/src/util.rs | 7 +- .../core-foundation-sys/.cargo-checksum.json | 1 + vendor/core-foundation-sys/Cargo.toml | 27 + .../LICENSE-APACHE | 0 .../LICENSE-MIT | 2 +- .../build.rs} | 14 +- vendor/core-foundation-sys/src/array.rs | 55 + .../src/attributed_string.rs | 55 + vendor/core-foundation-sys/src/base.rs | 157 + vendor/core-foundation-sys/src/bundle.rs | 38 + .../core-foundation-sys/src/characterset.rs | 58 + vendor/core-foundation-sys/src/data.rs | 32 + vendor/core-foundation-sys/src/date.rs | 34 + vendor/core-foundation-sys/src/dictionary.rs | 91 + vendor/core-foundation-sys/src/error.rs | 32 + .../core-foundation-sys/src/filedescriptor.rs | 58 + vendor/core-foundation-sys/src/lib.rs | 31 + vendor/core-foundation-sys/src/messageport.rs | 79 + vendor/core-foundation-sys/src/number.rs | 60 + .../core-foundation-sys/src/propertylist.rs | 46 + vendor/core-foundation-sys/src/runloop.rs | 164 + vendor/core-foundation-sys/src/set.rs | 66 + vendor/core-foundation-sys/src/string.rs | 319 + vendor/core-foundation-sys/src/timezone.rs | 29 + vendor/core-foundation-sys/src/url.rs | 169 + vendor/core-foundation-sys/src/uuid.rs | 49 + vendor/dirs/.cargo-checksum.json | 2 +- vendor/dirs/Cargo.toml | 16 +- vendor/dirs/README.md | 108 +- vendor/dirs/src/lib.rs | 94 +- vendor/dirs/src/lin.rs | 12 +- vendor/dirs/src/mac.rs | 6 +- vendor/dirs/src/wasm.rs | 4 + vendor/dirs/src/win.rs | 4 + vendor/dissimilar/.cargo-checksum.json | 2 +- vendor/dissimilar/Cargo.toml | 11 +- vendor/dissimilar/README.md | 24 +- vendor/dissimilar/src/lib.rs | 6 +- vendor/dissimilar/tests/test.rs | 2 + .../.cargo-checksum.json | 2 +- .../CHANGELOG.md | 0 .../Cargo.toml | 2 +- .../LICENSE-APACHE | 0 .../LICENSE-MIT | 0 .../README.md | 0 .../src/filter/mod.rs | 4 +- .../src/filter/regex.rs | 0 .../src/filter/string.rs | 0 .../src/fmt/humantime/extern_impl.rs | 0 .../src/fmt/humantime/mod.rs | 0 .../src/fmt/humantime/shim_impl.rs | 0 .../src/fmt/mod.rs | 125 +- .../src/fmt/writer/atty.rs | 0 .../src/fmt/writer/mod.rs | 0 .../src/fmt/writer/termcolor/extern_impl.rs | 0 .../src/fmt/writer/termcolor/mod.rs | 0 .../src/fmt/writer/termcolor/shim_impl.rs | 0 .../src/lib.rs | 44 +- .../tests/init-twice-retains-filter.rs | 0 .../tests/log-in-log.rs | 0 .../tests/log_tls_dtors.rs | 0 .../tests/regexp_filter.rs | 0 vendor/expect-test/.cargo-checksum.json | 2 +- vendor/expect-test/CHANGELOG.md | 12 + vendor/expect-test/Cargo.toml | 15 +- vendor/expect-test/src/lib.rs | 177 +- vendor/flate2/.cargo-checksum.json | 2 +- vendor/flate2/Cargo.lock | 28 +- vendor/flate2/Cargo.toml | 63 +- vendor/flate2/README.md | 37 +- vendor/flate2/src/bufreader.rs | 6 +- vendor/flate2/src/ffi/c.rs | 65 +- vendor/flate2/src/ffi/mod.rs | 18 +- vendor/flate2/src/lib.rs | 30 +- vendor/flate2/src/mem.rs | 2 +- vendor/futf/.cargo-checksum.json | 2 +- vendor/futf/Cargo.toml | 14 +- vendor/futf/src/lib.rs | 2 +- vendor/hashbrown-0.11.2/.cargo-checksum.json | 1 - vendor/hashbrown-0.11.2/CHANGELOG.md | 342 - vendor/hashbrown-0.11.2/Cargo.toml | 84 - vendor/hashbrown-0.11.2/README.md | 126 - vendor/hashbrown-0.11.2/benches/bench.rs | 331 - vendor/hashbrown-0.11.2/clippy.toml | 1 - .../src/external_trait_impls/mod.rs | 4 - .../src/external_trait_impls/rayon/helpers.rs | 26 - .../src/external_trait_impls/rayon/map.rs | 734 --- .../src/external_trait_impls/rayon/mod.rs | 4 - .../src/external_trait_impls/rayon/raw.rs | 229 - .../src/external_trait_impls/rayon/set.rs | 659 -- .../src/external_trait_impls/serde.rs | 200 - vendor/hashbrown-0.11.2/src/lib.rs | 161 - vendor/hashbrown-0.11.2/src/macros.rs | 69 - vendor/hashbrown-0.11.2/src/map.rs | 4922 -------------- vendor/hashbrown-0.11.2/src/raw/alloc.rs | 72 - vendor/hashbrown-0.11.2/src/raw/bitmask.rs | 122 - vendor/hashbrown-0.11.2/src/raw/generic.rs | 151 - vendor/hashbrown-0.11.2/src/raw/mod.rs | 2262 ------- vendor/hashbrown-0.11.2/src/raw/sse2.rs | 145 - vendor/hashbrown-0.11.2/src/rustc_entry.rs | 630 -- vendor/hashbrown-0.11.2/src/scopeguard.rs | 49 - vendor/hashbrown-0.11.2/src/set.rs | 2299 ------- vendor/hashbrown-0.11.2/tests/hasher.rs | 65 - vendor/hashbrown-0.11.2/tests/rayon.rs | 533 -- vendor/hashbrown-0.11.2/tests/serde.rs | 65 - vendor/hashbrown-0.11.2/tests/set.rs | 30 - vendor/hashbrown/.cargo-checksum.json | 2 +- vendor/hashbrown/CHANGELOG.md | 31 +- vendor/hashbrown/Cargo.toml | 45 +- vendor/hashbrown/README.md | 2 +- vendor/hashbrown/src/lib.rs | 4 +- vendor/hashbrown/src/macros.rs | 1 + vendor/hashbrown/src/map.rs | 2281 ++++++- vendor/hashbrown/src/raw/alloc.rs | 8 +- vendor/hashbrown/src/raw/mod.rs | 178 +- vendor/hashbrown/src/rustc_entry.rs | 12 +- vendor/hashbrown/src/scopeguard.rs | 27 +- vendor/hashbrown/src/set.rs | 441 ++ vendor/heck-0.3.3/.cargo-checksum.json | 1 + vendor/{macro-utils => heck-0.3.3}/Cargo.toml | 25 +- .../{term-0.6.1 => heck-0.3.3}/LICENSE-APACHE | 0 vendor/heck-0.3.3/LICENSE-MIT | 25 + vendor/heck-0.3.3/README.md | 63 + vendor/{heck => heck-0.3.3}/src/camel.rs | 0 vendor/heck-0.3.3/src/kebab.rs | 49 + vendor/heck-0.3.3/src/lib.rs | 181 + vendor/{heck => heck-0.3.3}/src/mixed.rs | 0 vendor/heck-0.3.3/src/shouty_kebab.rs | 51 + vendor/heck-0.3.3/src/shouty_snake.rs | 64 + vendor/heck-0.3.3/src/snake.rs | 77 + vendor/heck-0.3.3/src/title.rs | 50 + vendor/heck/.cargo-checksum.json | 2 +- vendor/heck/CHANGELOG.md | 11 + vendor/heck/Cargo.toml | 16 +- vendor/heck/README.md | 10 +- vendor/heck/src/kebab.rs | 31 +- vendor/heck/src/lib.rs | 95 +- vendor/heck/src/lower_camel.rs | 85 + vendor/heck/src/shouty_kebab.rs | 31 +- vendor/heck/src/shouty_snake.rs | 41 +- vendor/heck/src/snake.rs | 37 +- vendor/heck/src/title.rs | 31 +- vendor/heck/src/upper_camel.rs | 84 + vendor/indexmap/.cargo-checksum.json | 2 +- vendor/indexmap/Cargo.toml | 38 +- vendor/indexmap/README.md | 55 + vendor/indexmap/README.rst | 69 - vendor/indexmap/RELEASES.md | 379 ++ vendor/indexmap/RELEASES.rst | 354 - vendor/indexmap/benches/bench.rs | 1 - vendor/indexmap/benches/faststring.rs | 1 - vendor/indexmap/build.rs | 1 - vendor/indexmap/src/lib.rs | 2 +- vendor/indexmap/src/map.rs | 55 +- vendor/indexmap/src/map/core.rs | 109 +- vendor/indexmap/src/map/core/raw.rs | 15 +- vendor/indexmap/src/rayon/set.rs | 8 +- vendor/indexmap/src/set.rs | 54 +- vendor/indexmap/src/util.rs | 8 - vendor/indexmap/tests/quick.rs | 48 +- vendor/itoa/.cargo-checksum.json | 2 +- vendor/itoa/Cargo.toml | 8 +- vendor/itoa/src/lib.rs | 2 +- vendor/libc/.cargo-checksum.json | 2 +- vendor/libc/Cargo.toml | 2 +- vendor/libc/src/macros.rs | 2 +- .../src/unix/bsd/freebsdlike/dragonfly/mod.rs | 103 + .../bsd/freebsdlike/freebsd/freebsd12/mod.rs | 2 +- .../bsd/freebsdlike/freebsd/freebsd13/mod.rs | 4 +- .../bsd/freebsdlike/freebsd/freebsd14/mod.rs | 4 +- .../src/unix/bsd/freebsdlike/freebsd/mod.rs | 7 + vendor/libc/src/unix/bsd/netbsdlike/mod.rs | 13 - .../src/unix/bsd/netbsdlike/netbsd/mod.rs | 14 + .../src/unix/bsd/netbsdlike/openbsd/mod.rs | 117 + .../src/unix/linux_like/android/b32/mod.rs | 2 - .../unix/linux_like/android/b64/x86_64/mod.rs | 123 + .../libc/src/unix/linux_like/android/mod.rs | 3 + .../libc/src/unix/linux_like/linux/gnu/mod.rs | 2 - vendor/libc/src/unix/linux_like/linux/mod.rs | 28 +- .../linux_like/linux/musl/b64/riscv64/mod.rs | 1 + .../src/unix/linux_like/linux/musl/mod.rs | 1 + vendor/libc/src/unix/mod.rs | 5 +- vendor/log/.cargo-checksum.json | 2 +- vendor/log/CHANGELOG.md | 7 +- vendor/log/Cargo.toml | 6 +- vendor/log/README.md | 1 + vendor/log/src/kv/value.rs | 62 +- vendor/log/src/lib.rs | 19 +- vendor/macro-utils/.cargo-checksum.json | 1 - vendor/macro-utils/README.md | 39 - vendor/macro-utils/appveyor.yml | 26 - vendor/macro-utils/src/if_match.rs | 205 - vendor/macro-utils/src/lib.rs | 68 - vendor/macro-utils/src/tern_c.rs | 49 - vendor/macro-utils/src/tern_haskell.rs | 49 - vendor/macro-utils/src/tern_python.rs | 75 - vendor/memchr/.cargo-checksum.json | 2 +- vendor/memchr/Cargo.toml | 29 +- vendor/memchr/README.md | 2 +- vendor/memchr/build.rs | 28 +- vendor/memchr/src/memmem/mod.rs | 127 +- vendor/memchr/src/memmem/prefilter/mod.rs | 144 +- vendor/memchr/src/memmem/prefilter/wasm.rs | 39 + vendor/memchr/src/memmem/prefilter/x86/sse.rs | 15 +- vendor/memchr/src/memmem/vector.rs | 33 + vendor/memchr/src/memmem/wasm.rs | 75 + vendor/minifier/.cargo-checksum.json | 2 +- vendor/minifier/Cargo.lock | 17 +- vendor/minifier/Cargo.toml | 19 +- vendor/minifier/src/css/mod.rs | 34 +- vendor/minifier/src/css/tests.rs | 32 +- vendor/minifier/src/css/token.rs | 31 +- vendor/minifier/src/js/token.rs | 317 +- vendor/minifier/src/js/tools.rs | 179 +- vendor/minifier/src/js/utils.rs | 21 +- vendor/minifier/src/json/json_minifier.rs | 2 +- vendor/minifier/src/json/mod.rs | 46 +- vendor/minifier/src/json/read/byte_to_char.rs | 7 +- .../minifier/src/json/read/internal_reader.rs | 2 +- vendor/minifier/src/json/read/json_read.rs | 4 +- vendor/minifier/src/json/string.rs | 67 +- vendor/minifier/src/lib.rs | 2 - vendor/minifier/src/main.rs | 8 +- vendor/minifier/tests/js_minify.rs | 2 +- vendor/miniz_oxide/.cargo-checksum.json | 2 +- vendor/miniz_oxide/Cargo.toml | 4 +- vendor/miniz_oxide/Readme.md | 16 +- vendor/miniz_oxide/src/deflate/core.rs | 41 +- vendor/miniz_oxide/src/deflate/stream.rs | 5 +- vendor/miniz_oxide/src/inflate/core.rs | 20 +- vendor/miniz_oxide/src/inflate/mod.rs | 93 +- vendor/miniz_oxide/src/inflate/stream.rs | 9 +- vendor/miniz_oxide/src/lib.rs | 1 - vendor/ntapi/.cargo-checksum.json | 1 + vendor/ntapi/Cargo.toml | 40 + vendor/ntapi/LICENSE-APACHE | 202 + vendor/{structopt => ntapi}/LICENSE-MIT | 12 +- vendor/ntapi/README.md | 19 + vendor/ntapi/build.rs | 15 + vendor/ntapi/src/lib.rs | 71 + vendor/ntapi/src/macros.rs | 110 + vendor/ntapi/src/ntapi_base.rs | 40 + vendor/ntapi/src/ntdbg.rs | 239 + vendor/ntapi/src/ntexapi.rs | 3001 +++++++++ vendor/ntapi/src/ntgdi.rs | 123 + vendor/ntapi/src/ntioapi.rs | 1464 +++++ vendor/ntapi/src/ntkeapi.rs | 121 + vendor/ntapi/src/ntldr.rs | 661 ++ vendor/ntapi/src/ntlpcapi.rs | 692 ++ vendor/ntapi/src/ntmisc.rs | 42 + vendor/ntapi/src/ntmmapi.rs | 630 ++ vendor/ntapi/src/ntnls.rs | 29 + vendor/ntapi/src/ntobapi.rs | 226 + vendor/ntapi/src/ntpebteb.rs | 431 ++ vendor/ntapi/src/ntpfapi.rs | 219 + vendor/ntapi/src/ntpnpapi.rs | 118 + vendor/ntapi/src/ntpoapi.rs | 134 + vendor/ntapi/src/ntpsapi.rs | 1471 +++++ vendor/ntapi/src/ntregapi.rs | 450 ++ vendor/ntapi/src/ntrtl.rs | 4378 +++++++++++++ vendor/ntapi/src/ntsam.rs | 1077 ++++ vendor/ntapi/src/ntseapi.rs | 439 ++ vendor/ntapi/src/ntsmss.rs | 15 + vendor/ntapi/src/nttmapi.rs | 239 + vendor/ntapi/src/nttp.rs | 207 + vendor/ntapi/src/ntwow64.rs | 476 ++ vendor/ntapi/src/ntxcapi.rs | 29 + vendor/ntapi/src/ntzwapi.rs | 2699 ++++++++ vendor/ntapi/src/string.rs | 58 + vendor/ntapi/src/subprocesstag.rs | 77 + vendor/ntapi/src/winapi_local.rs | 1 + vendor/ntapi/src/winapi_local/um.rs | 2 + vendor/ntapi/src/winapi_local/um/winioctl.rs | 4 + vendor/ntapi/src/winapi_local/um/winnt.rs | 80 + vendor/ntapi/src/winsta.rs | 848 +++ vendor/object/.cargo-checksum.json | 2 +- vendor/object/CHANGELOG.md | 26 + vendor/object/Cargo.toml | 4 +- vendor/object/README.md | 8 + vendor/object/src/common.rs | 4 + vendor/object/src/elf.rs | 12 + vendor/object/src/lib.rs | 2 +- vendor/object/src/read/elf/file.rs | 8 + vendor/object/src/write/elf/object.rs | 15 +- vendor/once_cell/.cargo-checksum.json | 2 +- vendor/once_cell/CHANGELOG.md | 18 +- vendor/once_cell/Cargo.lock | 97 +- vendor/once_cell/Cargo.toml | 29 +- vendor/once_cell/src/imp_pl.rs | 92 +- vendor/once_cell/src/imp_std.rs | 219 +- vendor/once_cell/src/lib.rs | 85 +- vendor/once_cell/src/race.rs | 13 + vendor/once_cell/tests/it.rs | 48 + vendor/parking_lot/.cargo-checksum.json | 2 +- vendor/parking_lot/CHANGELOG.md | 21 + vendor/parking_lot/Cargo.toml | 19 +- vendor/parking_lot/README.md | 24 +- vendor/parking_lot/src/condvar.rs | 266 +- vendor/parking_lot/src/fair_mutex.rs | 2 +- vendor/parking_lot/src/mutex.rs | 2 +- vendor/parking_lot/src/once.rs | 12 +- vendor/parking_lot/src/raw_rwlock.rs | 4 +- vendor/parking_lot/src/rwlock.rs | 2 +- vendor/parking_lot_core/.cargo-checksum.json | 2 +- vendor/parking_lot_core/Cargo.toml | 4 +- vendor/pin-project-lite/.cargo-checksum.json | 2 +- vendor/pin-project-lite/CHANGELOG.md | 41 +- vendor/pin-project-lite/Cargo.toml | 24 +- vendor/pin-project-lite/README.md | 6 +- vendor/pin-project-lite/src/lib.rs | 535 +- vendor/pin-project-lite/tests/lint.rs | 8 +- .../tests/ui/pin_project/conflict-drop.stderr | 2 +- .../ui/pin_project/conflict-unpin.stderr | 6 +- .../ui/pin_project/invalid-bounds.stderr | 314 +- .../tests/ui/pin_project/invalid.stderr | 31 +- .../overlapping_lifetime_names.stderr | 52 +- .../overlapping_unpin_struct.stderr | 2 +- .../tests/ui/pin_project/packed.stderr | 4 +- .../tests/ui/pin_project/unsupported.stderr | 56 +- .../ui/pinned_drop/call-drop-inner.stderr | 10 +- .../pinned_drop/conditional-drop-impl.stderr | 2 +- .../.cargo-checksum.json | 0 .../CHANGELOG.md | 0 .../Cargo.lock | 0 .../Cargo.toml | 0 .../LICENSE-APACHE | 0 .../LICENSE-MIT | 0 .../README.md | 0 .../examples/pretty_assertion.png | Bin .../examples/pretty_assertion.rs | 0 .../examples/pretty_assertion_v0_6_1.png | Bin .../examples/standard_assertion.png | Bin .../examples/standard_assertion.rs | 0 .../scripts/check | 0 .../scripts/install | 0 .../scripts/publish | 0 .../src/lib.rs | 0 .../src/printer.rs | 0 vendor/proc-macro2/.cargo-checksum.json | 2 +- vendor/proc-macro2/Cargo.toml | 6 +- vendor/proc-macro2/src/fallback.rs | 11 +- vendor/proc-macro2/src/lib.rs | 2 +- vendor/proc-macro2/tests/test.rs | 44 + vendor/rayon-core/.cargo-checksum.json | 2 +- vendor/rayon-core/Cargo.toml | 2 +- vendor/rayon-core/src/latch.rs | 10 +- vendor/rayon-core/src/lib.rs | 2 +- vendor/rayon-core/src/registry.rs | 18 +- vendor/rayon-core/src/scope/mod.rs | 2 +- vendor/rayon-core/src/scope/test.rs | 10 +- vendor/rayon-core/src/spawn/mod.rs | 2 +- vendor/rayon-core/src/spawn/test.rs | 4 +- vendor/rayon-core/src/test.rs | 14 +- vendor/rayon-core/src/thread_pool/test.rs | 6 +- vendor/rayon/.cargo-checksum.json | 2 +- vendor/rayon/Cargo.lock | 191 +- vendor/rayon/Cargo.toml | 2 +- vendor/rayon/RELEASES.md | 9 + vendor/rayon/build.rs | 2 +- vendor/rayon/src/delegate.rs | 57 +- vendor/rayon/src/iter/mod.rs | 4 +- vendor/rayon/src/slice/mod.rs | 206 +- vendor/regex-syntax/.cargo-checksum.json | 2 +- vendor/regex-syntax/Cargo.toml | 24 +- vendor/regex-syntax/README.md | 7 +- vendor/regex-syntax/src/ast/parse.rs | 8 +- vendor/regex-syntax/src/ast/print.rs | 9 +- vendor/regex-syntax/src/hir/literal/mod.rs | 33 +- vendor/regex-syntax/src/hir/mod.rs | 14 +- vendor/regex-syntax/src/hir/print.rs | 9 +- vendor/regex-syntax/src/hir/translate.rs | 68 +- vendor/regex-syntax/src/parser.rs | 2 +- vendor/regex/.cargo-checksum.json | 2 +- vendor/regex/CHANGELOG.md | 29 +- vendor/regex/Cargo.lock | 26 +- vendor/regex/Cargo.toml | 4 +- vendor/regex/tests/regression.rs | 3 + vendor/rustc-rayon-core/.cargo-checksum.json | 2 +- vendor/rustc-rayon-core/Cargo.toml | 32 +- vendor/rustc-rayon-core/README.md | 2 +- vendor/rustc-rayon-core/src/join/mod.rs | 21 +- vendor/rustc-rayon-core/src/join/test.rs | 18 + vendor/rustc-rayon-core/src/latch.rs | 286 +- vendor/rustc-rayon-core/src/lib.rs | 85 +- vendor/rustc-rayon-core/src/log.rs | 499 +- vendor/rustc-rayon-core/src/private.rs | 4 +- vendor/rustc-rayon-core/src/registry.rs | 225 +- vendor/rustc-rayon-core/src/scope/mod.rs | 287 +- vendor/rustc-rayon-core/src/scope/test.rs | 96 +- vendor/rustc-rayon-core/src/sleep/README.md | 603 +- vendor/rustc-rayon-core/src/sleep/counters.rs | 275 + vendor/rustc-rayon-core/src/sleep/mod.rs | 589 +- vendor/rustc-rayon-core/src/spawn/mod.rs | 9 +- vendor/rustc-rayon-core/src/spawn/test.rs | 4 +- vendor/rustc-rayon-core/src/test.rs | 14 +- .../rustc-rayon-core/src/thread_pool/mod.rs | 29 +- .../rustc-rayon-core/src/thread_pool/test.rs | 115 +- vendor/rustc-rayon-core/src/util.rs | 10 - vendor/rustc-rayon-core/src/worker_local.rs | 2 +- .../tests/double_init_fail.rs | 6 +- vendor/rustc-rayon/.cargo-checksum.json | 2 +- vendor/rustc-rayon/Cargo.lock | 192 +- vendor/rustc-rayon/Cargo.toml | 38 +- vendor/rustc-rayon/FAQ.md | 2 +- vendor/rustc-rayon/RELEASES.md | 152 +- vendor/rustc-rayon/build.rs | 12 + vendor/rustc-rayon/src/array.rs | 90 + .../src/collections/binary_heap.rs | 62 + .../rustc-rayon/src/collections/hash_map.rs | 29 + .../rustc-rayon/src/collections/hash_set.rs | 27 + vendor/rustc-rayon/src/collections/mod.rs | 54 + .../rustc-rayon/src/collections/vec_deque.rs | 84 +- .../rustc-rayon/src/compile_fail/must_use.rs | 4 + .../src/compile_fail/no_send_par_iter.rs | 6 +- vendor/rustc-rayon/src/delegate.rs | 61 +- vendor/rustc-rayon/src/iter/chain.rs | 2 +- vendor/rustc-rayon/src/iter/chunks.rs | 2 +- vendor/rustc-rayon/src/iter/cloned.rs | 2 +- .../rustc-rayon/src/iter/collect/consumer.rs | 199 +- vendor/rustc-rayon/src/iter/collect/mod.rs | 148 +- vendor/rustc-rayon/src/iter/collect/test.rs | 298 +- vendor/rustc-rayon/src/iter/copied.rs | 10 +- vendor/rustc-rayon/src/iter/enumerate.rs | 2 +- vendor/rustc-rayon/src/iter/extend.rs | 440 +- vendor/rustc-rayon/src/iter/filter.rs | 2 +- vendor/rustc-rayon/src/iter/filter_map.rs | 2 +- vendor/rustc-rayon/src/iter/flat_map.rs | 14 +- vendor/rustc-rayon/src/iter/flat_map_iter.rs | 147 + vendor/rustc-rayon/src/iter/flatten.rs | 124 +- vendor/rustc-rayon/src/iter/flatten_iter.rs | 132 + vendor/rustc-rayon/src/iter/from_par_iter.rs | 30 +- vendor/rustc-rayon/src/iter/inspect.rs | 2 +- vendor/rustc-rayon/src/iter/interleave.rs | 2 +- .../src/iter/interleave_shortest.rs | 2 +- vendor/rustc-rayon/src/iter/intersperse.rs | 2 +- vendor/rustc-rayon/src/iter/len.rs | 12 +- vendor/rustc-rayon/src/iter/map.rs | 2 +- vendor/rustc-rayon/src/iter/map_with.rs | 4 +- vendor/rustc-rayon/src/iter/mod.rs | 703 +- vendor/rustc-rayon/src/iter/panic_fuse.rs | 2 +- vendor/rustc-rayon/src/iter/par_bridge.rs | 40 +- vendor/rustc-rayon/src/iter/plumbing/mod.rs | 2 +- vendor/rustc-rayon/src/iter/positions.rs | 137 + vendor/rustc-rayon/src/iter/repeat.rs | 4 +- vendor/rustc-rayon/src/iter/rev.rs | 2 +- vendor/rustc-rayon/src/iter/skip.rs | 15 +- vendor/rustc-rayon/src/iter/step_by.rs | 144 + vendor/rustc-rayon/src/iter/take.rs | 2 +- vendor/rustc-rayon/src/iter/test.rs | 24 + vendor/rustc-rayon/src/iter/try_fold.rs | 69 +- vendor/rustc-rayon/src/iter/try_reduce.rs | 55 +- .../rustc-rayon/src/iter/try_reduce_with.rs | 61 +- vendor/rustc-rayon/src/iter/unzip.rs | 69 +- vendor/rustc-rayon/src/iter/update.rs | 2 +- vendor/rustc-rayon/src/iter/while_some.rs | 2 +- vendor/rustc-rayon/src/iter/zip.rs | 2 +- vendor/rustc-rayon/src/iter/zip_eq.rs | 2 +- vendor/rustc-rayon/src/lib.rs | 40 +- vendor/rustc-rayon/src/math.rs | 26 + vendor/rustc-rayon/src/prelude.rs | 2 + vendor/rustc-rayon/src/private.rs | 4 +- vendor/rustc-rayon/src/range.rs | 226 +- vendor/rustc-rayon/src/range_inclusive.rs | 229 +- vendor/rustc-rayon/src/slice/chunks.rs | 389 ++ vendor/rustc-rayon/src/slice/mergesort.rs | 66 +- vendor/rustc-rayon/src/slice/mod.rs | 513 +- vendor/rustc-rayon/src/slice/quicksort.rs | 268 +- vendor/rustc-rayon/src/slice/rchunks.rs | 386 ++ vendor/rustc-rayon/src/slice/test.rs | 50 +- vendor/rustc-rayon/src/str.rs | 136 +- vendor/rustc-rayon/src/string.rs | 48 + vendor/rustc-rayon/src/vec.rs | 193 +- vendor/rustc-rayon/tests/chars.rs | 39 + vendor/rustc-rayon/tests/clones.rs | 13 + vendor/rustc-rayon/tests/collect.rs | 111 + vendor/rustc-rayon/tests/cross-pool.rs | 21 + vendor/rustc-rayon/tests/debug.rs | 31 +- vendor/rustc-rayon/tests/octillion.rs | 9 + vendor/rustc-rayon/tests/producer_split_at.rs | 84 + vendor/rustc-rayon/tests/sort-panic-safe.rs | 2 +- vendor/rustc-rayon/tests/str.rs | 22 +- vendor/rustfix-0.5.1/.cargo-checksum.json | 1 - vendor/rustfix-0.5.1/Cargo.toml | 52 - vendor/rustfix-0.5.1/Changelog.md | 79 - vendor/rustfix-0.5.1/Readme.md | 41 - .../proptest-regressions/replace.txt | 8 - vendor/rustfix-0.5.1/src/diagnostics.rs | 89 - vendor/rustfix-0.5.1/src/lib.rs | 268 - vendor/rustfix-0.5.1/src/replace.rs | 327 - vendor/rustfix/.cargo-checksum.json | 2 +- vendor/rustfix/Cargo.toml | 30 +- vendor/rustfix/Readme.md | 4 +- vendor/rustfix/src/diagnostics.rs | 2 +- vendor/rustfix/src/lib.rs | 10 +- vendor/rustfix/src/replace.rs | 6 +- vendor/ryu/.cargo-checksum.json | 2 +- vendor/ryu/Cargo.lock | 18 +- vendor/ryu/Cargo.toml | 10 +- vendor/ryu/benches/bench.rs | 5 + vendor/ryu/src/lib.rs | 2 +- vendor/ryu/tests/exhaustive.rs | 4 +- vendor/semver/.cargo-checksum.json | 2 +- vendor/semver/Cargo.toml | 2 +- vendor/semver/build.rs | 6 - vendor/semver/src/backport.rs | 12 - vendor/semver/src/identifier.rs | 126 +- vendor/semver/src/lib.rs | 12 +- vendor/semver/src/parse.rs | 10 +- vendor/semver/tests/test_autotrait.rs | 12 + vendor/serde/.cargo-checksum.json | 2 +- vendor/serde/Cargo.toml | 36 +- vendor/serde/src/de/mod.rs | 2 +- vendor/serde/src/lib.rs | 12 +- vendor/serde/src/ser/mod.rs | 2 +- vendor/serde_derive/.cargo-checksum.json | 2 +- vendor/serde_derive/Cargo.toml | 27 +- vendor/serde_derive/src/bound.rs | 4 +- vendor/serde_derive/src/internals/attr.rs | 4 +- vendor/serde_derive/src/internals/receiver.rs | 4 +- vendor/serde_derive/src/lib.rs | 3 +- vendor/serde_json/.cargo-checksum.json | 2 +- vendor/serde_json/Cargo.toml | 14 +- vendor/serde_json/README.md | 92 +- vendor/serde_json/src/lib.rs | 10 +- vendor/serde_json/src/value/ser.rs | 8 +- .../serde_json/tests/regression/issue845.rs | 2 + vendor/smallvec/.cargo-checksum.json | 2 +- vendor/smallvec/Cargo.toml | 13 +- vendor/smallvec/benches/bench.rs | 19 + vendor/smallvec/src/lib.rs | 29 +- vendor/structopt-derive/.cargo-checksum.json | 1 - vendor/structopt-derive/Cargo.toml | 45 - vendor/structopt-derive/src/attrs.rs | 685 -- vendor/structopt-derive/src/lib.rs | 1016 --- vendor/structopt/.cargo-checksum.json | 1 - vendor/structopt/CHANGELOG.md | 537 -- vendor/structopt/Cargo.lock | 532 -- vendor/structopt/Cargo.toml | 61 - vendor/structopt/README.md | 151 - vendor/structopt/examples/README.md | 86 - vendor/structopt/examples/after_help.rs | 19 - vendor/structopt/examples/at_least_two.rs | 15 - vendor/structopt/examples/basic.rs | 48 - .../structopt/examples/deny_missing_docs.rs | 51 - vendor/structopt/examples/doc_comments.rs | 74 - vendor/structopt/examples/enum_in_args.rs | 25 - .../examples/enum_in_args_with_strum.rs | 27 - vendor/structopt/examples/enum_tuple.rs | 26 - vendor/structopt/examples/env.rs | 26 - vendor/structopt/examples/example.rs | 54 - vendor/structopt/examples/flatten.rs | 29 - vendor/structopt/examples/gen_completions.rs | 26 - vendor/structopt/examples/git.rs | 35 - vendor/structopt/examples/group.rs | 31 - vendor/structopt/examples/keyvalue.rs | 36 - vendor/structopt/examples/negative_flag.rs | 15 - vendor/structopt/examples/no_version.rs | 17 - vendor/structopt/examples/rename_all.rs | 78 - vendor/structopt/examples/required_if.rs | 43 - vendor/structopt/examples/skip.rs | 47 - .../structopt/examples/subcommand_aliases.rs | 21 - vendor/structopt/examples/true_or_false.rs | 41 - vendor/structopt/src/lib.rs | 1228 ---- vendor/structopt/tests/argument_naming.rs | 339 - vendor/structopt/tests/arguments.rs | 86 - .../structopt/tests/author_version_about.rs | 58 - .../structopt/tests/custom-string-parsers.rs | 310 - vendor/structopt/tests/default_value.rs | 19 - vendor/structopt/tests/deny-warnings.rs | 47 - vendor/structopt/tests/doc-comments-help.rs | 185 - .../tests/explicit_name_no_renaming.rs | 32 - vendor/structopt/tests/flags.rs | 162 - vendor/structopt/tests/flatten.rs | 182 - vendor/structopt/tests/generics.rs | 145 - vendor/structopt/tests/issues.rs | 174 - vendor/structopt/tests/macro-errors.rs | 13 - vendor/structopt/tests/nested-subcommands.rs | 193 - .../structopt/tests/non_literal_attributes.rs | 151 - vendor/structopt/tests/options.rs | 336 - vendor/structopt/tests/privacy.rs | 32 - vendor/structopt/tests/raw_bool_literal.rs | 29 - vendor/structopt/tests/raw_idents.rs | 17 - vendor/structopt/tests/regressions.rs | 45 - vendor/structopt/tests/rename_all_env.rs | 46 - vendor/structopt/tests/skip.rs | 148 - vendor/structopt/tests/special_types.rs | 73 - vendor/structopt/tests/subcommands.rs | 349 - .../structopt/tests/ui/bool_default_value.rs | 21 - .../tests/ui/bool_default_value.stderr | 5 - vendor/structopt/tests/ui/bool_required.rs | 21 - .../structopt/tests/ui/bool_required.stderr | 5 - vendor/structopt/tests/ui/enum_flatten.rs | 21 - vendor/structopt/tests/ui/enum_flatten.stderr | 6 - .../ui/external_subcommand_wrong_type.rs | 19 - .../ui/external_subcommand_wrong_type.stderr | 8 - .../structopt/tests/ui/flatten_and_methods.rs | 29 - .../tests/ui/flatten_and_methods.stderr | 5 - .../structopt/tests/ui/flatten_and_parse.rs | 29 - .../tests/ui/flatten_and_parse.stderr | 5 - .../tests/ui/multiple_external_subcommand.rs | 21 - .../ui/multiple_external_subcommand.stderr | 5 - .../structopt/tests/ui/non_existent_attr.rs | 21 - .../tests/ui/non_existent_attr.stderr | 5 - .../tests/ui/opt_opt_nonpositional.rs | 20 - .../tests/ui/opt_opt_nonpositional.stderr | 5 - .../tests/ui/opt_vec_nonpositional.rs | 20 - .../tests/ui/opt_vec_nonpositional.stderr | 5 - .../tests/ui/option_default_value.rs | 21 - .../tests/ui/option_default_value.stderr | 5 - vendor/structopt/tests/ui/option_required.rs | 21 - .../structopt/tests/ui/option_required.stderr | 5 - .../tests/ui/parse_empty_try_from_os.rs | 21 - .../tests/ui/parse_empty_try_from_os.stderr | 5 - .../tests/ui/parse_function_is_not_path.rs | 21 - .../ui/parse_function_is_not_path.stderr | 5 - .../structopt/tests/ui/parse_literal_spec.rs | 21 - .../tests/ui/parse_literal_spec.stderr | 5 - .../structopt/tests/ui/parse_not_zero_args.rs | 21 - .../tests/ui/parse_not_zero_args.stderr | 5 - vendor/structopt/tests/ui/positional_bool.rs | 10 - .../structopt/tests/ui/positional_bool.stderr | 10 - vendor/structopt/tests/ui/raw.rs | 25 - vendor/structopt/tests/ui/raw.stderr | 19 - .../tests/ui/rename_all_wrong_casing.rs | 21 - .../tests/ui/rename_all_wrong_casing.stderr | 5 - vendor/structopt/tests/ui/skip_flatten.rs | 42 - vendor/structopt/tests/ui/skip_flatten.stderr | 5 - vendor/structopt/tests/ui/skip_subcommand.rs | 42 - .../structopt/tests/ui/skip_subcommand.stderr | 5 - .../tests/ui/skip_with_other_options.rs | 15 - .../tests/ui/skip_with_other_options.stderr | 5 - .../tests/ui/skip_without_default.rs | 29 - .../tests/ui/skip_without_default.stderr | 7 - vendor/structopt/tests/ui/struct_parse.rs | 21 - vendor/structopt/tests/ui/struct_parse.stderr | 5 - .../structopt/tests/ui/struct_subcommand.rs | 21 - .../tests/ui/struct_subcommand.stderr | 5 - .../tests/ui/structopt_empty_attr.rs | 22 - .../tests/ui/structopt_empty_attr.stderr | 5 - .../tests/ui/structopt_name_value_attr.rs | 22 - .../tests/ui/structopt_name_value_attr.stderr | 5 - .../tests/ui/subcommand_and_flatten.rs | 36 - .../tests/ui/subcommand_and_flatten.stderr | 5 - .../tests/ui/subcommand_and_methods.rs | 36 - .../tests/ui/subcommand_and_methods.stderr | 5 - .../tests/ui/subcommand_and_parse.rs | 36 - .../tests/ui/subcommand_and_parse.stderr | 5 - .../structopt/tests/ui/subcommand_opt_opt.rs | 36 - .../tests/ui/subcommand_opt_opt.stderr | 5 - .../structopt/tests/ui/subcommand_opt_vec.rs | 36 - .../tests/ui/subcommand_opt_vec.stderr | 5 - vendor/structopt/tests/ui/tuple_struct.stderr | 7 - vendor/structopt/tests/utils.rs | 45 - vendor/structopt/tests/we_need_syn_full.rs | 19 - vendor/syn/.cargo-checksum.json | 2 +- vendor/syn/Cargo.toml | 8 +- vendor/syn/benches/rust.rs | 8 + vendor/syn/src/buffer.rs | 18 +- vendor/syn/src/custom_keyword.rs | 2 +- vendor/syn/src/error.rs | 3 + vendor/syn/src/expr.rs | 16 +- vendor/syn/src/ident.rs | 5 +- vendor/syn/src/lib.rs | 47 +- vendor/syn/src/macros.rs | 18 +- vendor/syn/src/parse.rs | 3 +- vendor/syn/src/punctuated.rs | 36 +- vendor/syn/src/ty.rs | 4 +- vendor/syn/tests/common/eq.rs | 208 +- vendor/syn/tests/macros/mod.rs | 6 +- vendor/syn/tests/repo/mod.rs | 13 +- vendor/syn/tests/test_precedence.rs | 2 +- vendor/syn/tests/test_round_trip.rs | 58 +- vendor/sysinfo/.cargo-checksum.json | 1 + vendor/sysinfo/ADDING_NEW_PLATFORMS.md | 8 + vendor/sysinfo/CHANGELOG.md | 415 ++ vendor/sysinfo/Cargo.lock | 249 + vendor/sysinfo/Cargo.toml | 100 + vendor/{macro-utils => sysinfo}/LICENSE | 5 +- vendor/sysinfo/Makefile | 45 + vendor/sysinfo/README.md | 174 + vendor/sysinfo/benches/basic.rs | 161 + vendor/sysinfo/build.rs | 19 + vendor/sysinfo/examples/simple.c | 86 + vendor/sysinfo/examples/simple.rs | 431 ++ vendor/sysinfo/md_doc/component.md | 16 + vendor/sysinfo/md_doc/cpu.md | 1 + vendor/sysinfo/md_doc/disk.md | 1 + vendor/sysinfo/md_doc/network_data.md | 1 + vendor/sysinfo/md_doc/networks.md | 8 + vendor/sysinfo/md_doc/pid.md | 20 + vendor/sysinfo/md_doc/process.md | 10 + vendor/sysinfo/md_doc/system.md | 1 + .../sysinfo/src/apple/app_store/component.rs | 26 + vendor/sysinfo/src/apple/app_store/mod.rs | 4 + vendor/sysinfo/src/apple/app_store/process.rs | 82 + vendor/sysinfo/src/apple/component.rs | 3 + vendor/sysinfo/src/apple/cpu.rs | 331 + vendor/sysinfo/src/apple/disk.rs | 66 + vendor/sysinfo/src/apple/ffi.rs | 28 + vendor/sysinfo/src/apple/ios.rs | 5 + vendor/sysinfo/src/apple/macos/component.rs | 221 + vendor/sysinfo/src/apple/macos/disk.rs | 199 + vendor/sysinfo/src/apple/macos/ffi.rs | 156 + vendor/sysinfo/src/apple/macos/mod.rs | 17 + vendor/sysinfo/src/apple/macos/process.rs | 617 ++ vendor/sysinfo/src/apple/macos/system.rs | 136 + vendor/sysinfo/src/apple/mod.rs | 31 + vendor/sysinfo/src/apple/network.rs | 239 + vendor/sysinfo/src/apple/process.rs | 83 + vendor/sysinfo/src/apple/system.rs | 763 +++ vendor/sysinfo/src/apple/users.rs | 178 + vendor/sysinfo/src/apple/utils.rs | 39 + vendor/sysinfo/src/c_interface.rs | 468 ++ vendor/sysinfo/src/common.rs | 965 +++ vendor/sysinfo/src/debug.rs | 132 + vendor/sysinfo/src/freebsd/component.rs | 71 + vendor/sysinfo/src/freebsd/cpu.rs | 44 + vendor/sysinfo/src/freebsd/disk.rs | 143 + vendor/sysinfo/src/freebsd/mod.rs | 16 + vendor/sysinfo/src/freebsd/network.rs | 199 + vendor/sysinfo/src/freebsd/process.rs | 254 + vendor/sysinfo/src/freebsd/system.rs | 803 +++ vendor/sysinfo/src/freebsd/utils.rs | 296 + vendor/sysinfo/src/lib.rs | 429 ++ vendor/sysinfo/src/linux/component.rs | 189 + vendor/sysinfo/src/linux/cpu.rs | 357 + vendor/sysinfo/src/linux/disk.rs | 292 + vendor/sysinfo/src/linux/mod.rs | 16 + vendor/sysinfo/src/linux/network.rs | 314 + vendor/sysinfo/src/linux/process.rs | 700 ++ vendor/sysinfo/src/linux/system.rs | 852 +++ vendor/sysinfo/src/linux/utils.rs | 55 + vendor/sysinfo/src/macros.rs | 58 + vendor/sysinfo/src/sysinfo.h | 45 + vendor/sysinfo/src/system.rs | 117 + vendor/sysinfo/src/traits.rs | 1582 +++++ vendor/sysinfo/src/unknown/component.rs | 26 + vendor/sysinfo/src/unknown/cpu.rs | 34 + vendor/sysinfo/src/unknown/disk.rs | 42 + vendor/sysinfo/src/unknown/mod.rs | 15 + vendor/sysinfo/src/unknown/network.rs | 81 + vendor/sysinfo/src/unknown/process.rs | 92 + vendor/sysinfo/src/unknown/system.rs | 171 + vendor/sysinfo/src/users.rs | 97 + vendor/sysinfo/src/utils.rs | 61 + vendor/sysinfo/src/windows/component.rs | 374 ++ vendor/sysinfo/src/windows/cpu.rs | 548 ++ vendor/sysinfo/src/windows/disk.rs | 249 + vendor/sysinfo/src/windows/macros.rs | 16 + vendor/sysinfo/src/windows/mod.rs | 20 + vendor/sysinfo/src/windows/network.rs | 249 + vendor/sysinfo/src/windows/process.rs | 1019 +++ vendor/sysinfo/src/windows/system.rs | 623 ++ vendor/sysinfo/src/windows/tools.rs | 55 + vendor/sysinfo/src/windows/users.rs | 181 + vendor/sysinfo/src/windows/utils.rs | 36 + vendor/sysinfo/tests/code_checkers/docs.rs | 135 + vendor/sysinfo/tests/code_checkers/headers.rs | 59 + vendor/sysinfo/tests/code_checkers/mod.rs | 49 + vendor/sysinfo/tests/code_checkers/signals.rs | 64 + vendor/sysinfo/tests/code_checkers/utils.rs | 49 + vendor/sysinfo/tests/cpu.rs | 32 + vendor/sysinfo/tests/disk_list.rs | 14 + vendor/sysinfo/tests/extras.rs | 3 + vendor/sysinfo/tests/network.rs | 15 + vendor/sysinfo/tests/process.rs | 381 ++ vendor/sysinfo/tests/send_sync.rs | 10 + vendor/sysinfo/tests/uptime.rs | 12 + vendor/tar/.cargo-checksum.json | 2 +- vendor/tar/Cargo.lock | 38 +- vendor/tar/Cargo.toml | 11 +- vendor/tar/src/archive.rs | 98 +- vendor/tar/src/builder.rs | 48 + vendor/tar/src/entry.rs | 25 +- vendor/tar/src/error.rs | 7 +- vendor/tar/src/header.rs | 19 +- vendor/tar/src/pax.rs | 23 +- vendor/tar/tests/all.rs | 154 +- vendor/tendril/.cargo-checksum.json | 2 +- vendor/tendril/Cargo.lock | 193 + vendor/tendril/Cargo.toml | 13 +- vendor/tendril/README.md | 37 +- vendor/tendril/examples/fuzz.rs | 33 +- vendor/tendril/src/bench.rs | 55 +- vendor/tendril/src/buf32.rs | 14 +- vendor/tendril/src/fmt.rs | 105 +- vendor/tendril/src/lib.rs | 24 +- vendor/tendril/src/stream.rs | 267 +- vendor/tendril/src/tendril.rs | 861 ++- vendor/tendril/src/utf8_decode.rs | 59 +- vendor/tendril/src/util.rs | 38 +- vendor/term-0.6.1/.cargo-checksum.json | 1 - vendor/term-0.6.1/Cargo.toml | 38 - vendor/term-0.6.1/README.md | 36 - vendor/term-0.6.1/rustfmt.toml | 3 - vendor/term-0.6.1/src/lib.rs | 397 -- vendor/term-0.6.1/src/terminfo/mod.rs | 409 -- vendor/term-0.6.1/src/terminfo/parm.rs | 748 --- .../src/terminfo/parser/compiled.rs | 204 - .../term-0.6.1/src/terminfo/parser/names.rs | 553 -- vendor/term-0.6.1/src/terminfo/searcher.rs | 93 - vendor/term-0.6.1/src/win.rs | 418 -- vendor/term-0.6.1/tests/data/dumb | Bin 308 -> 0 bytes vendor/term-0.6.1/tests/data/linux | Bin 1780 -> 0 bytes vendor/term-0.6.1/tests/data/linux-16color | Bin 1858 -> 0 bytes vendor/term-0.6.1/tests/data/linux-basic | Bin 1664 -> 0 bytes vendor/term-0.6.1/tests/data/linux-c | Bin 2120 -> 0 bytes vendor/term-0.6.1/tests/data/linux-c-nc | Bin 1766 -> 0 bytes vendor/term-0.6.1/tests/data/linux-koi8 | Bin 1808 -> 0 bytes vendor/term-0.6.1/tests/data/linux-koi8r | Bin 1814 -> 0 bytes vendor/term-0.6.1/tests/data/linux-lat | Bin 1822 -> 0 bytes vendor/term-0.6.1/tests/data/linux-m | Bin 1770 -> 0 bytes vendor/term-0.6.1/tests/data/linux-nic | Bin 1810 -> 0 bytes vendor/term-0.6.1/tests/data/linux-vt | Bin 1702 -> 0 bytes vendor/term-0.6.1/tests/data/linux2.2 | Bin 1788 -> 0 bytes vendor/term-0.6.1/tests/data/linux2.6 | Bin 1785 -> 0 bytes vendor/term-0.6.1/tests/data/linux2.6.26 | Bin 1789 -> 0 bytes vendor/term-0.6.1/tests/data/linux3.0 | Bin 1788 -> 0 bytes vendor/term-0.6.1/tests/data/rxvt | Bin 2285 -> 0 bytes vendor/term-0.6.1/tests/data/rxvt-16color | Bin 2497 -> 0 bytes vendor/term-0.6.1/tests/data/rxvt-256color | Bin 2427 -> 0 bytes vendor/term-0.6.1/tests/data/rxvt-88color | Bin 2425 -> 0 bytes vendor/term-0.6.1/tests/data/rxvt-basic | Bin 2145 -> 0 bytes vendor/term-0.6.1/tests/data/rxvt-color | Bin 2229 -> 0 bytes vendor/term-0.6.1/tests/data/rxvt-cygwin | Bin 2251 -> 0 bytes .../term-0.6.1/tests/data/rxvt-cygwin-native | Bin 2269 -> 0 bytes vendor/term-0.6.1/tests/data/rxvt-xpm | Bin 2227 -> 0 bytes vendor/term-0.6.1/tests/data/screen | Bin 1587 -> 0 bytes vendor/term-0.6.1/tests/data/screen-256color | Bin 1912 -> 0 bytes vendor/term-0.6.1/tests/data/vt100 | Bin 1190 -> 0 bytes vendor/term-0.6.1/tests/data/xterm | Bin 3412 -> 0 bytes vendor/term-0.6.1/tests/data/xterm-256color | Bin 3713 -> 0 bytes vendor/term-0.6.1/tests/terminfo.rs | 29 - vendor/textwrap/.cargo-checksum.json | 2 +- vendor/textwrap/CHANGELOG.md | 58 + vendor/textwrap/Cargo.lock | 962 +++ vendor/textwrap/Cargo.toml | 39 +- vendor/textwrap/README.md | 79 +- vendor/textwrap/rustfmt.toml | 1 + vendor/textwrap/src/core.rs | 29 +- vendor/textwrap/src/lib.rs | 600 +- vendor/textwrap/src/word_separators.rs | 606 +- vendor/textwrap/src/word_splitters.rs | 291 +- vendor/textwrap/src/wrap_algorithms.rs | 290 +- .../src/wrap_algorithms/optimal_fit.rs | 337 +- vendor/textwrap/tests/traits.rs | 86 - vendor/thorin-dwp/.cargo-checksum.json | 2 +- vendor/thorin-dwp/Cargo.toml | 28 +- vendor/thorin-dwp/README.md | 2 +- vendor/tinyvec/.cargo-checksum.json | 2 +- vendor/tinyvec/CHANGELOG.md | 8 + vendor/tinyvec/Cargo.toml | 54 +- vendor/tinyvec/src/arrayvec.rs | 63 +- vendor/tinyvec/src/tinyvec.rs | 126 + vendor/tinyvec/tests/tinyvec.rs | 57 + .../tracing-attributes/.cargo-checksum.json | 2 +- vendor/tracing-attributes/CHANGELOG.md | 28 + vendor/tracing-attributes/Cargo.toml | 40 +- vendor/tracing-attributes/README.md | 4 +- vendor/tracing-attributes/src/attr.rs | 33 + vendor/tracing-attributes/src/expand.rs | 20 +- vendor/tracing-attributes/src/lib.rs | 51 +- vendor/tracing-attributes/tests/async_fn.rs | 23 +- .../tracing-attributes/tests/destructuring.rs | 4 +- vendor/tracing-attributes/tests/err.rs | 7 +- vendor/tracing-attributes/tests/fields.rs | 8 +- .../tracing-attributes/tests/follows_from.rs | 99 + vendor/tracing-attributes/tests/instrument.rs | 4 +- vendor/tracing-attributes/tests/levels.rs | 4 +- vendor/tracing-attributes/tests/names.rs | 4 +- vendor/tracing-attributes/tests/parents.rs | 102 + vendor/tracing-attributes/tests/ret.rs | 7 +- vendor/tracing-attributes/tests/support.rs | 5 - vendor/tracing-attributes/tests/targets.rs | 4 +- vendor/tracing-core/.cargo-checksum.json | 2 +- vendor/tracing-core/CHANGELOG.md | 33 +- vendor/tracing-core/Cargo.toml | 45 +- vendor/tracing-core/README.md | 26 +- vendor/tracing-core/src/callsite.rs | 583 +- vendor/tracing-core/src/dispatcher.rs | 21 +- vendor/tracing-core/src/field.rs | 19 +- vendor/tracing-core/src/lib.rs | 4 - vendor/tracing-core/src/metadata.rs | 17 +- vendor/tracing-core/src/span.rs | 17 +- vendor/tracing-core/src/subscriber.rs | 21 +- vendor/tracing-log/.cargo-checksum.json | 2 +- vendor/tracing-log/CHANGELOG.md | 26 + vendor/tracing-log/Cargo.toml | 62 +- vendor/tracing-log/README.md | 4 +- vendor/tracing-log/benches/logging.rs | 91 + vendor/tracing-log/src/interest_cache.rs | 542 ++ vendor/tracing-log/src/lib.rs | 37 +- vendor/tracing-log/src/log_tracer.rs | 66 +- vendor/tracing-log/src/trace_logger.rs | 17 +- vendor/tracing-log/tests/log_tracer.rs | 8 +- vendor/tracing-tree/.cargo-checksum.json | 2 +- vendor/tracing-tree/Cargo.lock | 95 +- vendor/tracing-tree/Cargo.toml | 15 +- vendor/tracing-tree/src/lib.rs | 12 +- vendor/tracing/.cargo-checksum.json | 2 +- vendor/tracing/CHANGELOG.md | 16 + vendor/tracing/Cargo.toml | 4 +- vendor/tracing/README.md | 8 +- vendor/tracing/src/dispatcher.rs | 4 - vendor/tracing/src/lib.rs | 202 +- vendor/tracing/src/macros.rs | 42 +- vendor/tracing/src/span.rs | 10 +- .../tests/register_callsite_deadlock.rs | 47 + vendor/unicode-bidi/.cargo-checksum.json | 2 +- vendor/unicode-bidi/Cargo.toml | 43 +- vendor/unicode-bidi/README.md | 4 +- vendor/unicode-bidi/src/char_data/mod.rs | 49 +- vendor/unicode-bidi/src/char_data/tables.rs | 796 +-- vendor/unicode-bidi/src/data_source.rs | 16 + vendor/unicode-bidi/src/deprecated.rs | 11 +- vendor/unicode-bidi/src/explicit.rs | 20 +- vendor/unicode-bidi/src/implicit.rs | 23 +- vendor/unicode-bidi/src/level.rs | 4 +- vendor/unicode-bidi/src/lib.rs | 340 +- vendor/unicode-bidi/src/prepare.rs | 20 +- vendor/unicode-ident/.cargo-checksum.json | 1 + vendor/unicode-ident/Cargo.toml | 50 + vendor/unicode-ident/LICENSE-APACHE | 201 + .../LICENSE-MIT | 2 - vendor/unicode-ident/README.md | 277 + vendor/unicode-ident/benches/xid.rs | 124 + vendor/unicode-ident/src/lib.rs | 268 + vendor/unicode-ident/src/tables.rs | 624 ++ vendor/unicode-ident/tests/compare.rs | 64 + vendor/unicode-ident/tests/fst/mod.rs | 11 + .../unicode-ident/tests/fst/xid_continue.fst | Bin 0 -> 70255 bytes vendor/unicode-ident/tests/fst/xid_start.fst | Bin 0 -> 62642 bytes vendor/unicode-ident/tests/roaring/mod.rs | 21 + vendor/unicode-ident/tests/static_size.rs | 83 + vendor/unicode-ident/tests/trie/mod.rs | 7 + vendor/unicode-ident/tests/trie/trie.rs | 436 ++ vendor/unicode-xid/.cargo-checksum.json | 2 +- vendor/unicode-xid/Cargo.toml | 38 +- vendor/unicode-xid/README.md | 2 +- vendor/unicode-xid/src/tables.rs | 144 +- vendor/windows-sys/.cargo-checksum.json | 2 +- vendor/windows-sys/Cargo.toml | 26 +- vendor/windows-sys/readme.md | 93 + .../Windows/AI/MachineLearning/Preview/mod.rs | 1 - .../src/Windows/AI/MachineLearning/mod.rs | 1 - vendor/windows-sys/src/Windows/AI/mod.rs | 1 - .../ApplicationModel/Activation/mod.rs | 1 - .../ApplicationModel/AppExtensions/mod.rs | 1 - .../ApplicationModel/AppService/mod.rs | 1 - .../Appointments/AppointmentsProvider/mod.rs | 1 - .../Appointments/DataProvider/mod.rs | 1 - .../ApplicationModel/Appointments/mod.rs | 1 - .../ApplicationModel/Background/mod.rs | 1 - .../ApplicationModel/Calls/Background/mod.rs | 1 - .../ApplicationModel/Calls/Provider/mod.rs | 1 - .../src/Windows/ApplicationModel/Calls/mod.rs | 1 - .../src/Windows/ApplicationModel/Chat/mod.rs | 1 - .../CommunicationBlocking/mod.rs | 2 +- .../Contacts/DataProvider/mod.rs | 1 - .../ApplicationModel/Contacts/Provider/mod.rs | 1 - .../Windows/ApplicationModel/Contacts/mod.rs | 1 - .../ConversationalAgent/mod.rs | 1 - .../src/Windows/ApplicationModel/Core/mod.rs | 1 - .../DataTransfer/DragDrop/Core/mod.rs | 1 - .../DataTransfer/DragDrop/mod.rs | 1 - .../DataTransfer/ShareTarget/mod.rs | 1 - .../ApplicationModel/DataTransfer/mod.rs | 1 - .../Email/DataProvider/mod.rs | 1 - .../src/Windows/ApplicationModel/Email/mod.rs | 1 - .../ExtendedExecution/Foreground/mod.rs | 1 - .../ApplicationModel/ExtendedExecution/mod.rs | 1 - .../ApplicationModel/Holographic/mod.rs | 1 - .../ApplicationModel/LockScreen/mod.rs | 1 - .../ApplicationModel/Payments/Provider/mod.rs | 1 - .../Windows/ApplicationModel/Payments/mod.rs | 1 - .../Preview/Holographic/mod.rs | 1 - .../Preview/InkWorkspace/mod.rs | 1 - .../ApplicationModel/Preview/Notes/mod.rs | 1 - .../Windows/ApplicationModel/Preview/mod.rs | 1 - .../ApplicationModel/Resources/Core/mod.rs | 1 - .../Resources/Management/mod.rs | 1 - .../Windows/ApplicationModel/Resources/mod.rs | 1 - .../ApplicationModel/Search/Core/mod.rs | 1 - .../Windows/ApplicationModel/Search/mod.rs | 1 - .../SocialInfo/Provider/mod.rs | 1 - .../ApplicationModel/SocialInfo/mod.rs | 1 - .../Store/LicenseManagement/mod.rs | 1 - .../Store/Preview/InstallControl/mod.rs | 1 - .../ApplicationModel/Store/Preview/mod.rs | 1 - .../src/Windows/ApplicationModel/Store/mod.rs | 1 - .../UserActivities/Core/mod.rs | 2 +- .../ApplicationModel/UserActivities/mod.rs | 1 - .../UserDataAccounts/Provider/mod.rs | 1 - .../UserDataAccounts/SystemAccess/mod.rs | 1 - .../ApplicationModel/UserDataAccounts/mod.rs | 1 - .../UserDataTasks/DataProvider/mod.rs | 1 - .../ApplicationModel/UserDataTasks/mod.rs | 1 - .../ApplicationModel/VoiceCommands/mod.rs | 1 - .../ApplicationModel/Wallet/System/mod.rs | 1 - .../Windows/ApplicationModel/Wallet/mod.rs | 1 - .../src/Windows/ApplicationModel/mod.rs | 1 - .../windows-sys/src/Windows/Data/Html/mod.rs | 2 +- .../windows-sys/src/Windows/Data/Json/mod.rs | 1 - .../windows-sys/src/Windows/Data/Pdf/mod.rs | 1 - .../windows-sys/src/Windows/Data/Text/mod.rs | 1 - .../src/Windows/Data/Xml/Dom/mod.rs | 1 - .../src/Windows/Data/Xml/Xsl/mod.rs | 1 - .../windows-sys/src/Windows/Data/Xml/mod.rs | 1 - vendor/windows-sys/src/Windows/Data/mod.rs | 1 - .../src/Windows/Devices/Adc/Provider/mod.rs | 1 - .../src/Windows/Devices/Adc/mod.rs | 1 - .../src/Windows/Devices/AllJoyn/mod.rs | 1 - .../src/Windows/Devices/Background/mod.rs | 1 - .../Devices/Bluetooth/Advertisement/mod.rs | 1 - .../Devices/Bluetooth/Background/mod.rs | 1 - .../Bluetooth/GenericAttributeProfile/mod.rs | 1 - .../Windows/Devices/Bluetooth/Rfcomm/mod.rs | 1 - .../src/Windows/Devices/Bluetooth/mod.rs | 1 - .../src/Windows/Devices/Custom/mod.rs | 1 - .../src/Windows/Devices/Display/Core/mod.rs | 1 - .../src/Windows/Devices/Display/mod.rs | 1 - .../Windows/Devices/Enumeration/Pnp/mod.rs | 1 - .../src/Windows/Devices/Enumeration/mod.rs | 1 - .../Devices/Geolocation/Geofencing/mod.rs | 1 - .../src/Windows/Devices/Geolocation/mod.rs | 1 - .../src/Windows/Devices/Gpio/Provider/mod.rs | 1 - .../src/Windows/Devices/Gpio/mod.rs | 1 - .../src/Windows/Devices/Haptics/mod.rs | 1 - .../Devices/HumanInterfaceDevice/mod.rs | 1 - .../src/Windows/Devices/I2c/Provider/mod.rs | 1 - .../src/Windows/Devices/I2c/mod.rs | 1 - .../src/Windows/Devices/Input/Preview/mod.rs | 1 - .../src/Windows/Devices/Input/mod.rs | 1 - .../src/Windows/Devices/Lights/Effects/mod.rs | 1 - .../src/Windows/Devices/Lights/mod.rs | 1 - .../src/Windows/Devices/Midi/mod.rs | 1 - .../Devices/Perception/Provider/mod.rs | 1 - .../src/Windows/Devices/Perception/mod.rs | 1 - .../Devices/PointOfService/Provider/mod.rs | 1 - .../src/Windows/Devices/PointOfService/mod.rs | 1 - .../src/Windows/Devices/Portable/mod.rs | 1 - .../src/Windows/Devices/Power/mod.rs | 1 - .../Devices/Printers/Extensions/mod.rs | 1 - .../src/Windows/Devices/Printers/mod.rs | 1 - .../src/Windows/Devices/Pwm/Provider/mod.rs | 1 - .../src/Windows/Devices/Pwm/mod.rs | 1 - .../src/Windows/Devices/Radios/mod.rs | 1 - .../src/Windows/Devices/Scanners/mod.rs | 1 - .../src/Windows/Devices/Sensors/Custom/mod.rs | 1 - .../src/Windows/Devices/Sensors/mod.rs | 1 - .../Devices/SerialCommunication/mod.rs | 1 - .../src/Windows/Devices/SmartCards/mod.rs | 1 - .../src/Windows/Devices/Sms/mod.rs | 1 - .../src/Windows/Devices/Spi/Provider/mod.rs | 1 - .../src/Windows/Devices/Spi/mod.rs | 1 - .../src/Windows/Devices/Usb/mod.rs | 1 - .../src/Windows/Devices/WiFi/mod.rs | 1 - .../Devices/WiFiDirect/Services/mod.rs | 1 - .../src/Windows/Devices/WiFiDirect/mod.rs | 1 - vendor/windows-sys/src/Windows/Devices/mod.rs | 1 - .../Windows/Embedded/DeviceLockdown/mod.rs | 1 - .../windows-sys/src/Windows/Embedded/mod.rs | 1 - .../src/Windows/Foundation/Collections/mod.rs | 1 - .../src/Windows/Foundation/Diagnostics/mod.rs | 1 - .../src/Windows/Foundation/Metadata/mod.rs | 1 - .../src/Windows/Foundation/Numerics/mod.rs | 1 - .../windows-sys/src/Windows/Foundation/mod.rs | 1 - .../src/Windows/Gaming/Input/Custom/mod.rs | 1 - .../Windows/Gaming/Input/ForceFeedback/mod.rs | 1 - .../src/Windows/Gaming/Input/Preview/mod.rs | 2 +- .../src/Windows/Gaming/Input/mod.rs | 1 - .../Gaming/Preview/GamesEnumeration/mod.rs | 1 - .../src/Windows/Gaming/Preview/mod.rs | 1 - .../windows-sys/src/Windows/Gaming/UI/mod.rs | 1 - .../Windows/Gaming/XboxLive/Storage/mod.rs | 1 - .../src/Windows/Gaming/XboxLive/mod.rs | 1 - vendor/windows-sys/src/Windows/Gaming/mod.rs | 1 - .../Windows/Globalization/Collation/mod.rs | 1 - .../Globalization/DateTimeFormatting/mod.rs | 1 - .../src/Windows/Globalization/Fonts/mod.rs | 1 - .../Globalization/NumberFormatting/mod.rs | 1 - .../PhoneNumberFormatting/mod.rs | 1 - .../src/Windows/Globalization/mod.rs | 1 - .../src/Windows/Graphics/Capture/mod.rs | 1 - .../Graphics/DirectX/Direct3D11/mod.rs | 1 - .../src/Windows/Graphics/DirectX/mod.rs | 1 - .../src/Windows/Graphics/Display/Core/mod.rs | 1 - .../src/Windows/Graphics/Display/mod.rs | 1 - .../src/Windows/Graphics/Effects/mod.rs | 1 - .../src/Windows/Graphics/Holographic/mod.rs | 1 - .../src/Windows/Graphics/Imaging/mod.rs | 1 - .../Graphics/Printing/OptionDetails/mod.rs | 1 - .../Graphics/Printing/PrintSupport/mod.rs | 1 - .../Graphics/Printing/PrintTicket/mod.rs | 1 - .../Windows/Graphics/Printing/Workflow/mod.rs | 1 - .../src/Windows/Graphics/Printing/mod.rs | 1 - .../src/Windows/Graphics/Printing3D/mod.rs | 1 - .../windows-sys/src/Windows/Graphics/mod.rs | 1 - .../src/Windows/Management/Core/mod.rs | 1 - .../Management/Deployment/Preview/mod.rs | 1 - .../src/Windows/Management/Deployment/mod.rs | 1 - .../src/Windows/Management/Policies/mod.rs | 1 - .../src/Windows/Management/Update/mod.rs | 1 - .../src/Windows/Management/Workplace/mod.rs | 1 - .../windows-sys/src/Windows/Management/mod.rs | 1 - .../src/Windows/Media/AppBroadcasting/mod.rs | 1 - .../src/Windows/Media/AppRecording/mod.rs | 1 - .../src/Windows/Media/Audio/mod.rs | 1 - .../src/Windows/Media/Capture/Core/mod.rs | 1 - .../src/Windows/Media/Capture/Frames/mod.rs | 1 - .../src/Windows/Media/Capture/mod.rs | 1 - .../src/Windows/Media/Casting/mod.rs | 1 - .../src/Windows/Media/ClosedCaptioning/mod.rs | 1 - .../Windows/Media/ContentRestrictions/mod.rs | 1 - .../src/Windows/Media/Control/mod.rs | 1 - .../src/Windows/Media/Core/Preview/mod.rs | 2 +- .../windows-sys/src/Windows/Media/Core/mod.rs | 1 - .../src/Windows/Media/Devices/Core/mod.rs | 1 - .../src/Windows/Media/Devices/mod.rs | 1 - .../src/Windows/Media/DialProtocol/mod.rs | 1 - .../src/Windows/Media/Editing/mod.rs | 1 - .../src/Windows/Media/Effects/mod.rs | 1 - .../src/Windows/Media/FaceAnalysis/mod.rs | 1 - .../src/Windows/Media/Import/mod.rs | 1 - .../src/Windows/Media/MediaProperties/mod.rs | 1 - .../src/Windows/Media/Miracast/mod.rs | 1 - .../windows-sys/src/Windows/Media/Ocr/mod.rs | 1 - .../src/Windows/Media/PlayTo/mod.rs | 1 - .../src/Windows/Media/Playback/mod.rs | 1 - .../src/Windows/Media/Playlists/mod.rs | 1 - .../Windows/Media/Protection/PlayReady/mod.rs | 1 - .../src/Windows/Media/Protection/mod.rs | 1 - .../src/Windows/Media/Render/mod.rs | 1 - .../Windows/Media/SpeechRecognition/mod.rs | 1 - .../src/Windows/Media/SpeechSynthesis/mod.rs | 1 - .../Windows/Media/Streaming/Adaptive/mod.rs | 1 - .../src/Windows/Media/Streaming/mod.rs | 1 - .../src/Windows/Media/Transcoding/mod.rs | 1 - vendor/windows-sys/src/Windows/Media/mod.rs | 1 - .../Networking/BackgroundTransfer/mod.rs | 1 - .../Windows/Networking/Connectivity/mod.rs | 1 - .../Networking/NetworkOperators/mod.rs | 1 - .../src/Windows/Networking/Proximity/mod.rs | 1 - .../Networking/PushNotifications/mod.rs | 1 - .../Networking/ServiceDiscovery/Dnssd/mod.rs | 1 - .../Networking/ServiceDiscovery/mod.rs | 1 - .../src/Windows/Networking/Sockets/mod.rs | 1 - .../src/Windows/Networking/Vpn/mod.rs | 1 - .../src/Windows/Networking/XboxLive/mod.rs | 1 - .../windows-sys/src/Windows/Networking/mod.rs | 1 - .../Windows/Perception/Automation/Core/mod.rs | 2 +- .../src/Windows/Perception/Automation/mod.rs | 1 - .../src/Windows/Perception/People/mod.rs | 1 - .../Windows/Perception/Spatial/Preview/mod.rs | 1 - .../Perception/Spatial/Surfaces/mod.rs | 1 - .../src/Windows/Perception/Spatial/mod.rs | 1 - .../windows-sys/src/Windows/Perception/mod.rs | 1 - .../src/Windows/Phone/ApplicationModel/mod.rs | 1 - .../Windows/Phone/Devices/Notification/mod.rs | 1 - .../src/Windows/Phone/Devices/Power/mod.rs | 1 - .../src/Windows/Phone/Devices/mod.rs | 1 - .../Phone/Management/Deployment/mod.rs | 1 - .../src/Windows/Phone/Management/mod.rs | 1 - .../src/Windows/Phone/Media/Devices/mod.rs | 1 - .../src/Windows/Phone/Media/mod.rs | 1 - .../Phone/Notification/Management/mod.rs | 1 - .../src/Windows/Phone/Notification/mod.rs | 1 - .../PersonalInformation/Provisioning/mod.rs | 2 +- .../Windows/Phone/PersonalInformation/mod.rs | 1 - .../Windows/Phone/Speech/Recognition/mod.rs | 1 - .../src/Windows/Phone/Speech/mod.rs | 1 - .../src/Windows/Phone/StartScreen/mod.rs | 1 - .../src/Windows/Phone/System/Power/mod.rs | 1 - .../src/Windows/Phone/System/Profile/mod.rs | 2 +- .../UserProfile/GameServices/Core/mod.rs | 1 - .../System/UserProfile/GameServices/mod.rs | 1 - .../Windows/Phone/System/UserProfile/mod.rs | 1 - .../src/Windows/Phone/System/mod.rs | 1 - .../src/Windows/Phone/UI/Input/mod.rs | 1 - .../windows-sys/src/Windows/Phone/UI/mod.rs | 1 - vendor/windows-sys/src/Windows/Phone/mod.rs | 1 - .../Authentication/Identity/Core/mod.rs | 1 - .../Authentication/Identity/Provider/mod.rs | 1 - .../Security/Authentication/Identity/mod.rs | 1 - .../Security/Authentication/OnlineId/mod.rs | 1 - .../Security/Authentication/Web/Core/mod.rs | 1 - .../Authentication/Web/Provider/mod.rs | 1 - .../Security/Authentication/Web/mod.rs | 1 - .../Windows/Security/Authentication/mod.rs | 1 - .../Authorization/AppCapabilityAccess/mod.rs | 1 - .../src/Windows/Security/Authorization/mod.rs | 1 - .../Windows/Security/Credentials/UI/mod.rs | 1 - .../src/Windows/Security/Credentials/mod.rs | 1 - .../Security/Cryptography/Certificates/mod.rs | 1 - .../Windows/Security/Cryptography/Core/mod.rs | 1 - .../Cryptography/DataProtection/mod.rs | 1 - .../src/Windows/Security/Cryptography/mod.rs | 1 - .../Windows/Security/DataProtection/mod.rs | 1 - .../Windows/Security/EnterpriseData/mod.rs | 1 - .../ExchangeActiveSyncProvisioning/mod.rs | 1 - .../src/Windows/Security/Isolation/mod.rs | 1 - .../windows-sys/src/Windows/Security/mod.rs | 1 - .../src/Windows/Services/Cortana/mod.rs | 1 - .../src/Windows/Services/Maps/Guidance/mod.rs | 1 - .../Windows/Services/Maps/LocalSearch/mod.rs | 1 - .../Windows/Services/Maps/OfflineMaps/mod.rs | 1 - .../src/Windows/Services/Maps/mod.rs | 1 - .../src/Windows/Services/Store/mod.rs | 1 - .../Windows/Services/TargetedContent/mod.rs | 1 - .../windows-sys/src/Windows/Services/mod.rs | 1 - .../src/Windows/Storage/AccessCache/mod.rs | 1 - .../src/Windows/Storage/BulkAccess/mod.rs | 1 - .../src/Windows/Storage/Compression/mod.rs | 1 - .../src/Windows/Storage/FileProperties/mod.rs | 1 - .../Windows/Storage/Pickers/Provider/mod.rs | 1 - .../src/Windows/Storage/Pickers/mod.rs | 1 - .../src/Windows/Storage/Provider/mod.rs | 1 - .../src/Windows/Storage/Search/mod.rs | 1 - .../src/Windows/Storage/Streams/mod.rs | 1 - vendor/windows-sys/src/Windows/Storage/mod.rs | 1 - .../System/Diagnostics/DevicePortal/mod.rs | 1 - .../System/Diagnostics/Telemetry/mod.rs | 1 - .../System/Diagnostics/TraceReporting/mod.rs | 1 - .../src/Windows/System/Diagnostics/mod.rs | 1 - .../src/Windows/System/Display/mod.rs | 1 - .../System/Implementation/FileExplorer/mod.rs | 1 - .../src/Windows/System/Implementation/mod.rs | 1 - .../src/Windows/System/Inventory/mod.rs | 1 - .../Windows/System/Power/Diagnostics/mod.rs | 2 +- .../src/Windows/System/Power/mod.rs | 1 - .../src/Windows/System/Preview/mod.rs | 1 - .../System/Profile/SystemManufacturers/mod.rs | 1 - .../src/Windows/System/Profile/mod.rs | 1 - .../Windows/System/RemoteDesktop/Input/mod.rs | 1 - .../src/Windows/System/RemoteDesktop/mod.rs | 1 - .../src/Windows/System/RemoteSystems/mod.rs | 1 - .../src/Windows/System/Threading/Core/mod.rs | 1 - .../src/Windows/System/Threading/mod.rs | 1 - .../src/Windows/System/Update/mod.rs | 1 - .../src/Windows/System/UserProfile/mod.rs | 1 - vendor/windows-sys/src/Windows/System/mod.rs | 1 - .../src/Windows/UI/Accessibility/mod.rs | 1 - .../src/Windows/UI/ApplicationSettings/mod.rs | 1 - .../src/Windows/UI/Composition/Core/mod.rs | 1 - .../src/Windows/UI/Composition/Desktop/mod.rs | 1 - .../Windows/UI/Composition/Diagnostics/mod.rs | 1 - .../src/Windows/UI/Composition/Effects/mod.rs | 1 - .../UI/Composition/Interactions/mod.rs | 1 - .../src/Windows/UI/Composition/Scenes/mod.rs | 1 - .../src/Windows/UI/Composition/mod.rs | 1 - .../Windows/UI/Core/AnimationMetrics/mod.rs | 1 - .../src/Windows/UI/Core/Preview/mod.rs | 1 - vendor/windows-sys/src/Windows/UI/Core/mod.rs | 1 - .../src/Windows/UI/Input/Core/mod.rs | 1 - .../Windows/UI/Input/Inking/Analysis/mod.rs | 1 - .../src/Windows/UI/Input/Inking/Core/mod.rs | 1 - .../Windows/UI/Input/Inking/Preview/mod.rs | 1 - .../src/Windows/UI/Input/Inking/mod.rs | 1 - .../Windows/UI/Input/Preview/Injection/mod.rs | 1 - .../src/Windows/UI/Input/Preview/mod.rs | 1 - .../src/Windows/UI/Input/Spatial/mod.rs | 1 - .../windows-sys/src/Windows/UI/Input/mod.rs | 1 - .../UI/Notifications/Management/mod.rs | 1 - .../src/Windows/UI/Notifications/mod.rs | 1 - .../windows-sys/src/Windows/UI/Popups/mod.rs | 1 - .../windows-sys/src/Windows/UI/Shell/mod.rs | 1 - .../src/Windows/UI/StartScreen/mod.rs | 1 - .../src/Windows/UI/Text/Core/mod.rs | 1 - vendor/windows-sys/src/Windows/UI/Text/mod.rs | 1 - .../src/Windows/UI/UIAutomation/Core/mod.rs | 1 - .../src/Windows/UI/UIAutomation/mod.rs | 1 - .../src/Windows/UI/ViewManagement/Core/mod.rs | 1 - .../src/Windows/UI/ViewManagement/mod.rs | 1 - .../src/Windows/UI/WebUI/Core/mod.rs | 1 - .../windows-sys/src/Windows/UI/WebUI/mod.rs | 1 - .../UI/WindowManagement/Preview/mod.rs | 1 - .../src/Windows/UI/WindowManagement/mod.rs | 1 - .../Windows/UI/Xaml/Automation/Peers/mod.rs | 1 - .../UI/Xaml/Automation/Provider/mod.rs | 1 - .../Windows/UI/Xaml/Automation/Text/mod.rs | 1 - .../src/Windows/UI/Xaml/Automation/mod.rs | 1 - .../src/Windows/UI/Xaml/Controls/Maps/mod.rs | 1 - .../UI/Xaml/Controls/Primitives/mod.rs | 1 - .../src/Windows/UI/Xaml/Controls/mod.rs | 1 - .../src/Windows/UI/Xaml/Core/Direct/mod.rs | 1 - .../src/Windows/UI/Xaml/Core/mod.rs | 1 - .../src/Windows/UI/Xaml/Data/mod.rs | 1 - .../src/Windows/UI/Xaml/Documents/mod.rs | 1 - .../src/Windows/UI/Xaml/Hosting/mod.rs | 1 - .../src/Windows/UI/Xaml/Input/mod.rs | 1 - .../src/Windows/UI/Xaml/Interop/mod.rs | 1 - .../src/Windows/UI/Xaml/Markup/mod.rs | 1 - .../Windows/UI/Xaml/Media/Animation/mod.rs | 1 - .../src/Windows/UI/Xaml/Media/Imaging/mod.rs | 1 - .../src/Windows/UI/Xaml/Media/Media3D/mod.rs | 1 - .../src/Windows/UI/Xaml/Media/mod.rs | 1 - .../src/Windows/UI/Xaml/Navigation/mod.rs | 1 - .../src/Windows/UI/Xaml/Printing/mod.rs | 1 - .../src/Windows/UI/Xaml/Resources/mod.rs | 1 - .../src/Windows/UI/Xaml/Shapes/mod.rs | 1 - vendor/windows-sys/src/Windows/UI/Xaml/mod.rs | 1 - vendor/windows-sys/src/Windows/UI/mod.rs | 1 - .../src/Windows/Web/AtomPub/mod.rs | 1 - .../src/Windows/Web/Http/Diagnostics/mod.rs | 1 - .../src/Windows/Web/Http/Filters/mod.rs | 1 - .../src/Windows/Web/Http/Headers/mod.rs | 1 - .../windows-sys/src/Windows/Web/Http/mod.rs | 1 - .../src/Windows/Web/Syndication/mod.rs | 1 - .../src/Windows/Web/UI/Interop/mod.rs | 1 - vendor/windows-sys/src/Windows/Web/UI/mod.rs | 1 - vendor/windows-sys/src/Windows/Web/mod.rs | 1 - .../Win32/AI/MachineLearning/DirectML/mod.rs | 1 - .../Win32/AI/MachineLearning/WinML/mod.rs | 1 - .../Windows/Win32/AI/MachineLearning/mod.rs | 1 - .../windows-sys/src/Windows/Win32/AI/mod.rs | 1 - .../src/Windows/Win32/Data/HtmlHelp/mod.rs | 7 +- .../Win32/Data/RightsManagement/mod.rs | 5 +- .../src/Windows/Win32/Data/Xml/MsXml/mod.rs | 1 - .../src/Windows/Win32/Data/Xml/XmlLite/mod.rs | 1 - .../src/Windows/Win32/Data/Xml/mod.rs | 1 - .../windows-sys/src/Windows/Win32/Data/mod.rs | 1 - .../src/Windows/Win32/Devices/AllJoyn/mod.rs | 3 +- .../Win32/Devices/BiometricFramework/mod.rs | 1 - .../Windows/Win32/Devices/Bluetooth/mod.rs | 304 +- .../Win32/Devices/Communication/mod.rs | 1 - .../Windows/Win32/Devices/DeviceAccess/mod.rs | 1 - .../DeviceAndDriverInstallation/mod.rs | 678 +- .../Windows/Win32/Devices/DeviceQuery/mod.rs | 1 - .../src/Windows/Win32/Devices/Display/mod.rs | 31 +- .../Win32/Devices/Enumeration/Pnp/mod.rs | 5 +- .../Windows/Win32/Devices/Enumeration/mod.rs | 1 - .../src/Windows/Win32/Devices/Fax/mod.rs | 109 +- .../Win32/Devices/FunctionDiscovery/mod.rs | 207 +- .../Windows/Win32/Devices/Geolocation/mod.rs | 1 - .../Win32/Devices/HumanInterfaceDevice/mod.rs | 117 +- .../Win32/Devices/ImageAcquisition/mod.rs | 545 +- .../Win32/Devices/PortableDevices/mod.rs | 701 +- .../Windows/Win32/Devices/Properties/mod.rs | 976 ++- .../src/Windows/Win32/Devices/Pwm/mod.rs | 3 +- .../src/Windows/Win32/Devices/Sensors/mod.rs | 1 - .../Win32/Devices/SerialCommunication/mod.rs | 1 - .../src/Windows/Win32/Devices/Tapi/mod.rs | 7 +- .../src/Windows/Win32/Devices/Usb/mod.rs | 11 +- .../Win32/Devices/WebServicesOnDevices/mod.rs | 7 +- .../src/Windows/Win32/Devices/mod.rs | 1 - .../src/Windows/Win32/Foundation/mod.rs | 5 +- .../src/Windows/Win32/Gaming/mod.rs | 5 +- .../src/Windows/Win32/Globalization/mod.rs | 171 +- .../Graphics/CompositionSwapchain/mod.rs | 1 - .../src/Windows/Win32/Graphics/DXCore/mod.rs | 1 - .../Win32/Graphics/Direct2D/Common/mod.rs | 1 - .../Windows/Win32/Graphics/Direct2D/mod.rs | 1 - .../Win32/Graphics/Direct3D/Dxc/mod.rs | 43 +- .../Win32/Graphics/Direct3D/Fxc/mod.rs | 5 +- .../Windows/Win32/Graphics/Direct3D/mod.rs | 1 - .../Windows/Win32/Graphics/Direct3D10/mod.rs | 31 +- .../Windows/Win32/Graphics/Direct3D11/mod.rs | 41 +- .../Win32/Graphics/Direct3D11on12/mod.rs | 1 - .../Windows/Win32/Graphics/Direct3D12/mod.rs | 1 - .../Windows/Win32/Graphics/Direct3D9/mod.rs | 1 - .../Win32/Graphics/Direct3D9on12/mod.rs | 1 - .../Win32/Graphics/DirectComposition/mod.rs | 1 - .../Windows/Win32/Graphics/DirectDraw/mod.rs | 11 +- .../Win32/Graphics/DirectManipulation/mod.rs | 1 - .../Windows/Win32/Graphics/DirectWrite/mod.rs | 1 - .../src/Windows/Win32/Graphics/Dwm/mod.rs | 1 - .../Windows/Win32/Graphics/Dxgi/Common/mod.rs | 1 - .../src/Windows/Win32/Graphics/Dxgi/mod.rs | 1 - .../src/Windows/Win32/Graphics/Gdi/mod.rs | 57 - .../src/Windows/Win32/Graphics/Hlsl/mod.rs | 3 +- .../Windows/Win32/Graphics/Imaging/D2D/mod.rs | 1 - .../src/Windows/Win32/Graphics/Imaging/mod.rs | 1 - .../src/Windows/Win32/Graphics/OpenGL/mod.rs | 63 +- .../Graphics/Printing/PrintTicket/mod.rs | 1 - .../Windows/Win32/Graphics/Printing/mod.rs | 237 +- .../src/Windows/Win32/Graphics/mod.rs | 1 - .../MobileDeviceManagementRegistration/mod.rs | 1 - .../src/Windows/Win32/Management/mod.rs | 1 - .../src/Windows/Win32/Media/Audio/Apo/mod.rs | 1 - .../Win32/Media/Audio/DirectMusic/mod.rs | 3 +- .../Win32/Media/Audio/DirectSound/mod.rs | 1 - .../Win32/Media/Audio/Endpoints/mod.rs | 1 - .../Windows/Win32/Media/Audio/XAudio2/mod.rs | 13 +- .../src/Windows/Win32/Media/Audio/mod.rs | 21 +- .../Windows/Win32/Media/DeviceManager/mod.rs | 193 +- .../Windows/Win32/Media/DirectShow/Xml/mod.rs | 1 - .../src/Windows/Win32/Media/DirectShow/mod.rs | 115 +- .../Windows/Win32/Media/DxMediaObjects/mod.rs | 1 - .../Win32/Media/KernelStreaming/mod.rs | 31 +- .../Win32/Media/LibrarySharingServices/mod.rs | 1 - .../Win32/Media/MediaFoundation/mod.rs | 77 +- .../Windows/Win32/Media/MediaPlayer/mod.rs | 191 +- .../src/Windows/Win32/Media/Multimedia/mod.rs | 13 +- .../Win32/Media/PictureAcquisition/mod.rs | 1 - .../src/Windows/Win32/Media/Speech/mod.rs | 103 +- .../src/Windows/Win32/Media/Streaming/mod.rs | 1 - .../Win32/Media/WindowsMediaFormat/mod.rs | 445 +- .../src/Windows/Win32/Media/mod.rs | 1 - .../Win32/NetworkManagement/Dhcp/mod.rs | 7 +- .../Win32/NetworkManagement/Dns/mod.rs | 1 - .../InternetConnectionWizard/mod.rs | 5 +- .../Win32/NetworkManagement/IpHelper/mod.rs | 36 +- .../NetworkManagement/MobileBroadband/mod.rs | 1 - .../Win32/NetworkManagement/Multicast/mod.rs | 1 - .../Win32/NetworkManagement/Ndis/mod.rs | 9 +- .../Win32/NetworkManagement/NetBios/mod.rs | 5 +- .../NetworkManagement/NetManagement/mod.rs | 205 +- .../Win32/NetworkManagement/NetShell/mod.rs | 9 +- .../NetworkDiagnosticsFramework/mod.rs | 1 - .../NetworkPolicyServer/mod.rs | 21 +- .../Win32/NetworkManagement/P2P/mod.rs | 9 +- .../Win32/NetworkManagement/QoS/mod.rs | 3 +- .../Win32/NetworkManagement/Rras/mod.rs | 59 +- .../Win32/NetworkManagement/Snmp/mod.rs | 1 - .../Win32/NetworkManagement/WNet/mod.rs | 1 - .../Win32/NetworkManagement/WebDav/mod.rs | 1 - .../Win32/NetworkManagement/WiFi/mod.rs | 235 +- .../WindowsConnectNow/mod.rs | 3 +- .../WindowsConnectionManager/mod.rs | 1 - .../WindowsFilteringPlatform/mod.rs | 53 +- .../NetworkManagement/WindowsFirewall/mod.rs | 1 - .../WindowsNetworkVirtualization/mod.rs | 1 - .../Windows/Win32/NetworkManagement/mod.rs | 1 - .../Win32/Networking/ActiveDirectory/mod.rs | 109 +- .../mod.rs | 1 - .../Win32/Networking/Clustering/mod.rs | 815 ++- .../Win32/Networking/HttpServer/mod.rs | 15 +- .../src/Windows/Win32/Networking/Ldap/mod.rs | 357 +- .../Networking/NetworkListManager/mod.rs | 27 +- .../RemoteDifferentialCompression/mod.rs | 1 - .../Windows/Win32/Networking/WebSocket/mod.rs | 1 - .../Windows/Win32/Networking/WinHttp/mod.rs | 3 - .../Windows/Win32/Networking/WinInet/mod.rs | 79 +- .../Windows/Win32/Networking/WinSock/mod.rs | 239 +- .../Networking/WindowsWebServices/mod.rs | 27 +- .../src/Windows/Win32/Networking/mod.rs | 1 - .../Windows/Win32/Security/AppLocker/mod.rs | 23 +- .../Authentication/Identity/Provider/mod.rs | 23 +- .../Security/Authentication/Identity/mod.rs | 542 +- .../Win32/Security/Authentication/mod.rs | 1 - .../Win32/Security/Authorization/UI/mod.rs | 3 +- .../Win32/Security/Authorization/mod.rs | 341 +- .../Win32/Security/ConfigurationSnapin/mod.rs | 19 +- .../Windows/Win32/Security/Credentials/mod.rs | 90 +- .../Security/Cryptography/Catalog/mod.rs | 9 +- .../Security/Cryptography/Certificates/mod.rs | 1153 ++-- .../Win32/Security/Cryptography/Sip/mod.rs | 1 - .../Win32/Security/Cryptography/UI/mod.rs | 3 +- .../Win32/Security/Cryptography/mod.rs | 2431 ++++--- .../Win32/Security/DiagnosticDataQuery/mod.rs | 1 - .../Win32/Security/DirectoryServices/mod.rs | 5 +- .../Win32/Security/EnterpriseData/mod.rs | 1 - .../ExtensibleAuthenticationProtocol/mod.rs | 65 +- .../Windows/Win32/Security/Isolation/mod.rs | 1 - .../Win32/Security/LicenseProtection/mod.rs | 1 - .../Security/NetworkAccessProtection/mod.rs | 1 - .../src/Windows/Win32/Security/Tpm/mod.rs | 1 - .../Windows/Win32/Security/WinTrust/mod.rs | 125 +- .../src/Windows/Win32/Security/WinWlx/mod.rs | 1 - .../src/Windows/Win32/Security/mod.rs | 160 +- .../src/Windows/Win32/Storage/Cabinets/mod.rs | 1 - .../Windows/Win32/Storage/CloudFilters/mod.rs | 1 - .../Windows/Win32/Storage/Compression/mod.rs | 1 - .../Win32/Storage/DataDeduplication/mod.rs | 1 - .../Storage/DistributedFileSystem/mod.rs | 77 +- .../Win32/Storage/EnhancedStorage/mod.rs | 111 +- .../Windows/Win32/Storage/FileHistory/mod.rs | 1 - .../Storage/FileServerResourceManager/mod.rs | 1 - .../Windows/Win32/Storage/FileSystem/mod.rs | 51 +- .../src/Windows/Win32/Storage/Imapi/mod.rs | 7 +- .../Windows/Win32/Storage/IndexServer/mod.rs | 5 +- .../Storage/InstallableFileSystems/mod.rs | 1 - .../Windows/Win32/Storage/IscsiDisc/mod.rs | 67 +- .../src/Windows/Win32/Storage/Jet/mod.rs | 7 +- .../Windows/Win32/Storage/OfflineFiles/mod.rs | 3 +- .../Win32/Storage/OperationRecorder/mod.rs | 1 - .../Win32/Storage/Packaging/Appx/mod.rs | 198 +- .../Win32/Storage/Packaging/Opc/mod.rs | 1 - .../Windows/Win32/Storage/Packaging/mod.rs | 1 - .../Win32/Storage/ProjectedFileSystem/mod.rs | 1 - .../Win32/Storage/StructuredStorage/mod.rs | 1 - .../src/Windows/Win32/Storage/Vhd/mod.rs | 62 +- .../Win32/Storage/VirtualDiskService/mod.rs | 1 - .../src/Windows/Win32/Storage/Vss/mod.rs | 1 - .../Windows/Win32/Storage/Xps/Printing/mod.rs | 1 - .../src/Windows/Win32/Storage/Xps/mod.rs | 1 - .../src/Windows/Win32/Storage/mod.rs | 1 - .../Windows/Win32/System/AddressBook/mod.rs | 18 +- .../Windows/Win32/System/Antimalware/mod.rs | 1 - .../mod.rs | 529 +- .../Win32/System/ApplicationVerifier/mod.rs | 1 - .../Win32/System/AssessmentTool/mod.rs | 1 - .../Windows/Win32/System/Com/CallObj/mod.rs | 1 - .../System/Com/ChannelCredentials/mod.rs | 1 - .../Windows/Win32/System/Com/Events/mod.rs | 1 - .../Windows/Win32/System/Com/Marshal/mod.rs | 1 - .../Win32/System/Com/StructuredStorage/mod.rs | 13 +- .../src/Windows/Win32/System/Com/UI/mod.rs | 1 - .../Windows/Win32/System/Com/Urlmon/mod.rs | 1 - .../src/Windows/Win32/System/Com/mod.rs | 17 +- .../Win32/System/ComponentServices/mod.rs | 5 +- .../src/Windows/Win32/System/Console/mod.rs | 1 - .../src/Windows/Win32/System/Contacts/mod.rs | 197 +- .../Win32/System/CorrelationVector/mod.rs | 1 - .../Windows/Win32/System/DataExchange/mod.rs | 17 +- .../Win32/System/DeploymentServices/mod.rs | 1 - .../Win32/System/DesktopSharing/mod.rs | 1 - .../Win32/System/DeveloperLicensing/mod.rs | 1 - .../Win32/System/Diagnostics/Ceip/mod.rs | 1 - .../System/Diagnostics/Debug/WebApp/mod.rs | 1 - .../Win32/System/Diagnostics/Debug/mod.rs | 35 +- .../Win32/System/Diagnostics/Etw/mod.rs | 29 +- .../Diagnostics/ProcessSnapshotting/mod.rs | 1 - .../Win32/System/Diagnostics/ToolHelp/mod.rs | 1 - .../Windows/Win32/System/Diagnostics/mod.rs | 1 - .../DistributedTransactionCoordinator/mod.rs | 1 - .../Windows/Win32/System/Environment/mod.rs | 1 - .../Win32/System/ErrorReporting/mod.rs | 11 +- .../Win32/System/EventCollector/mod.rs | 1 - .../src/Windows/Win32/System/EventLog/mod.rs | 1 - .../System/EventNotificationService/mod.rs | 1 - .../Windows/Win32/System/GroupPolicy/mod.rs | 27 +- .../Windows/Win32/System/HostCompute/mod.rs | 1 - .../Win32/System/HostComputeNetwork/mod.rs | 1 - .../Win32/System/HostComputeSystem/mod.rs | 1 - .../Windows/Win32/System/Hypervisor/mod.rs | 3 +- .../src/Windows/Win32/System/IO/mod.rs | 1 - .../src/Windows/Win32/System/Iis/mod.rs | 119 +- .../src/Windows/Win32/System/Ioctl/mod.rs | 57 +- .../Windows/Win32/System/JobObjects/mod.rs | 1 - .../src/Windows/Win32/System/Js/mod.rs | 1 - .../src/Windows/Win32/System/Kernel/mod.rs | 1 - .../Windows/Win32/System/LibraryLoader/mod.rs | 1 - .../src/Windows/Win32/System/Mailslots/mod.rs | 1 - .../src/Windows/Win32/System/Mapi/mod.rs | 1 - .../Win32/System/Memory/NonVolatile/mod.rs | 1 - .../src/Windows/Win32/System/Memory/mod.rs | 1 - .../Win32/System/MessageQueuing/mod.rs | 67 +- .../Windows/Win32/System/MixedReality/mod.rs | 1 - .../src/Windows/Win32/System/Mmc/mod.rs | 1 - .../src/Windows/Win32/System/Ole/mod.rs | 27 +- .../Win32/System/ParentalControls/mod.rs | 1 - .../Win32/System/PasswordManagement/mod.rs | 1 - .../HardwareCounterProfiling/mod.rs | 1 - .../Windows/Win32/System/Performance/mod.rs | 5 +- .../src/Windows/Win32/System/Pipes/mod.rs | 1 - .../src/Windows/Win32/System/Power/mod.rs | 7 +- .../Windows/Win32/System/ProcessStatus/mod.rs | 1 - .../System/RealTimeCommunications/mod.rs | 1 - .../src/Windows/Win32/System/Recovery/mod.rs | 1 - .../src/Windows/Win32/System/Registry/mod.rs | 1507 +++-- .../Win32/System/RemoteAssistance/mod.rs | 1 - .../Windows/Win32/System/RemoteDesktop/mod.rs | 11 +- .../Win32/System/RemoteManagement/mod.rs | 17 +- .../Win32/System/RestartManager/mod.rs | 1 - .../src/Windows/Win32/System/Restore/mod.rs | 1 - .../src/Windows/Win32/System/Rpc/mod.rs | 1 - .../Windows/Win32/System/Search/Common/mod.rs | 1 - .../src/Windows/Win32/System/Search/mod.rs | 23 +- .../Win32/System/SecurityCenter/mod.rs | 1 - .../Windows/Win32/System/ServerBackup/mod.rs | 1 - .../src/Windows/Win32/System/Services/mod.rs | 25 +- .../SettingsManagementInfrastructure/mod.rs | 15 +- .../Win32/System/SetupAndMigration/mod.rs | 1 - .../src/Windows/Win32/System/Shutdown/mod.rs | 1 - .../src/Windows/Win32/System/SideShow/mod.rs | 1 - .../src/Windows/Win32/System/SqlLite/mod.rs | 2276 ------- .../Win32/System/StationsAndDesktops/mod.rs | 1 - .../Win32/System/SubsystemForLinux/mod.rs | 1 - .../Win32/System/SystemInformation/mod.rs | 1 - .../Win32/System/SystemServices/mod.rs | 217 +- .../Windows/Win32/System/TaskScheduler/mod.rs | 1 - .../src/Windows/Win32/System/Threading/mod.rs | 1 - .../src/Windows/Win32/System/Time/mod.rs | 13 +- .../Win32/System/TpmBaseServices/mod.rs | 1 - .../Win32/System/TransactionServer/mod.rs | 1 - .../Windows/Win32/System/UpdateAgent/mod.rs | 1 - .../Win32/System/UpdateAssessment/mod.rs | 1 - .../Win32/System/UserAccessLogging/mod.rs | 1 - .../Win32/System/VirtualDosMachines/mod.rs | 1 - .../Windows/Win32/System/WinRT/AllJoyn/mod.rs | 1 - .../Win32/System/WinRT/Composition/mod.rs | 1 - .../Win32/System/WinRT/CoreInputView/mod.rs | 1 - .../Win32/System/WinRT/Direct3D11/mod.rs | 1 - .../Windows/Win32/System/WinRT/Display/mod.rs | 1 - .../System/WinRT/Graphics/Capture/mod.rs | 1 - .../System/WinRT/Graphics/Direct2D/mod.rs | 1 - .../System/WinRT/Graphics/Imaging/mod.rs | 1 - .../Win32/System/WinRT/Graphics/mod.rs | 1 - .../Win32/System/WinRT/Holographic/mod.rs | 1 - .../Win32/System/WinRT/Isolation/mod.rs | 1 - .../src/Windows/Win32/System/WinRT/ML/mod.rs | 1 - .../Windows/Win32/System/WinRT/Media/mod.rs | 1 - .../src/Windows/Win32/System/WinRT/Pdf/mod.rs | 1 - .../Win32/System/WinRT/Printing/mod.rs | 1 - .../Windows/Win32/System/WinRT/Shell/mod.rs | 1 - .../Windows/Win32/System/WinRT/Storage/mod.rs | 1 - .../Windows/Win32/System/WinRT/Xaml/mod.rs | 1 - .../src/Windows/Win32/System/WinRT/mod.rs | 44 +- .../Win32/System/WindowsProgramming/mod.rs | 59 +- .../Windows/Win32/System/WindowsSync/mod.rs | 1 - .../src/Windows/Win32/System/Wmi/mod.rs | 5 +- .../src/Windows/Win32/System/mod.rs | 3 - .../src/Windows/Win32/UI/Accessibility/mod.rs | 1 - .../src/Windows/Win32/UI/Animation/mod.rs | 1 - .../src/Windows/Win32/UI/ColorSystem/mod.rs | 13 +- .../Windows/Win32/UI/Controls/Dialogs/mod.rs | 43 +- .../Windows/Win32/UI/Controls/RichEdit/mod.rs | 31 +- .../src/Windows/Win32/UI/Controls/mod.rs | 185 +- .../src/Windows/Win32/UI/HiDpi/mod.rs | 1 - .../src/Windows/Win32/UI/Input/Ime/mod.rs | 35 +- .../src/Windows/Win32/UI/Input/Ink/mod.rs | 1 - .../Win32/UI/Input/KeyboardAndMouse/mod.rs | 37 +- .../src/Windows/Win32/UI/Input/Pointer/mod.rs | 1 - .../src/Windows/Win32/UI/Input/Radial/mod.rs | 1 - .../src/Windows/Win32/UI/Input/Touch/mod.rs | 1 - .../Win32/UI/Input/XboxController/mod.rs | 7 +- .../src/Windows/Win32/UI/Input/mod.rs | 1 - .../Win32/UI/InteractionContext/mod.rs | 1 - .../LegacyWindowsEnvironmentFeatures/mod.rs | 1 - .../src/Windows/Win32/UI/Magnification/mod.rs | 7 +- .../src/Windows/Win32/UI/Notifications/mod.rs | 1 - .../src/Windows/Win32/UI/Ribbon/mod.rs | 1 - .../src/Windows/Win32/UI/Shell/Common/mod.rs | 1 - .../Win32/UI/Shell/PropertiesSystem/mod.rs | 1 - .../src/Windows/Win32/UI/Shell/mod.rs | 203 +- .../src/Windows/Win32/UI/TabletPC/mod.rs | 139 +- .../src/Windows/Win32/UI/TextServices/mod.rs | 11 +- .../Win32/UI/WindowsAndMessaging/mod.rs | 13 +- .../src/Windows/Win32/UI/Wpf/mod.rs | 1 - .../Windows/Win32/UI/Xaml/Diagnostics/mod.rs | 1 - .../src/Windows/Win32/UI/Xaml/mod.rs | 1 - .../windows-sys/src/Windows/Win32/UI/mod.rs | 1 - .../src/Windows/Win32/Web/MsHtml/mod.rs | 325 +- .../windows-sys/src/Windows/Win32/Web/mod.rs | 1 - vendor/windows-sys/src/Windows/Win32/mod.rs | 1 - vendor/windows-sys/src/Windows/mod.rs | 1 - vendor/windows-sys/src/lib.rs | 1 + .../windows_aarch64_msvc/.cargo-checksum.json | 2 +- vendor/windows_aarch64_msvc/Cargo.toml | 2 +- vendor/windows_aarch64_msvc/lib/windows.lib | Bin 4400572 -> 4345164 bytes vendor/windows_aarch64_msvc/src/lib.rs | 2 +- vendor/windows_i686_gnu/.cargo-checksum.json | 2 +- vendor/windows_i686_gnu/Cargo.toml | 2 +- vendor/windows_i686_gnu/lib/libwindows.a | Bin 13811190 -> 14009016 bytes vendor/windows_i686_gnu/src/lib.rs | 2 +- vendor/windows_i686_msvc/.cargo-checksum.json | 2 +- vendor/windows_i686_msvc/Cargo.toml | 2 +- vendor/windows_i686_msvc/lib/windows.lib | Bin 4710054 -> 4650454 bytes vendor/windows_i686_msvc/src/lib.rs | 2 +- .../windows_x86_64_gnu/.cargo-checksum.json | 2 +- vendor/windows_x86_64_gnu/Cargo.toml | 2 +- vendor/windows_x86_64_gnu/lib/libwindows.a | Bin 13680228 -> 13879932 bytes vendor/windows_x86_64_gnu/src/lib.rs | 2 +- .../windows_x86_64_msvc/.cargo-checksum.json | 2 +- vendor/windows_x86_64_msvc/Cargo.toml | 2 +- vendor/windows_x86_64_msvc/lib/windows.lib | Bin 4400572 -> 4345164 bytes vendor/windows_x86_64_msvc/src/lib.rs | 2 +- version | 2 +- 7071 files changed, 203615 insertions(+), 122510 deletions(-) create mode 100644 compiler/rustc/Windows Manifest.xml create mode 100644 compiler/rustc/build.rs delete mode 100644 compiler/rustc_ast/src/ast/tests.rs create mode 100644 compiler/rustc_builtin_macros/src/assert/context.rs delete mode 100644 compiler/rustc_codegen_cranelift/scripts/config.sh delete mode 100644 compiler/rustc_codegen_cranelift/scripts/ext_config.sh create mode 100644 compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs delete mode 100644 compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs delete mode 100644 compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs create mode 100644 compiler/rustc_codegen_gcc/.rustfmt.toml create mode 100644 compiler/rustc_codegen_gcc/crate_patches/0002-rand-Disable-failing-test.patch create mode 100644 compiler/rustc_codegen_gcc/rustc_patches/compile_test.patch create mode 100644 compiler/rustc_codegen_gcc/src/intrinsic/archs.rs rename compiler/rustc_codegen_gcc/tests/{lib.rs => lang_tests_common.rs} (77%) create mode 100644 compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs create mode 100644 compiler/rustc_codegen_gcc/tests/lang_tests_release.rs create mode 100644 compiler/rustc_codegen_gcc/tools/generate_intrinsics.py create mode 100644 compiler/rustc_error_codes/src/error_codes/E0788.md create mode 100644 compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl create mode 100644 compiler/rustc_infer/src/infer/outlives/test_type_match.rs create mode 100644 compiler/rustc_macros/src/diagnostics/fluent.rs create mode 100644 compiler/rustc_middle/src/ty/parameterized.rs create mode 100644 compiler/rustc_middle/src/ty/rvalue_scopes.rs create mode 100644 compiler/rustc_mir_transform/src/dead_store_elimination.rs create mode 100644 compiler/rustc_mir_transform/src/elaborate_box_derefs.rs delete mode 100644 compiler/rustc_serialize/src/json.rs delete mode 100644 compiler/rustc_serialize/src/json/tests.rs delete mode 100644 compiler/rustc_serialize/tests/json.rs create mode 100644 compiler/rustc_smir/Cargo.toml create mode 100644 compiler/rustc_smir/README.md create mode 100644 compiler/rustc_smir/rust-toolchain.toml create mode 100644 compiler/rustc_smir/src/lib.rs create mode 100644 compiler/rustc_smir/src/mir.rs create mode 100644 compiler/rustc_smir/src/very_unstable.rs create mode 100644 compiler/rustc_target/src/json.rs create mode 100644 compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs create mode 100644 compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs create mode 100644 compiler/rustc_target/src/spec/armv7k_apple_watchos.rs create mode 100644 compiler/rustc_target/src/spec/riscv32imac_unknown_xous_elf.rs create mode 100644 compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs create mode 100644 compiler/rustc_type_ir/src/codec.rs create mode 100644 compiler/rustc_type_ir/src/sty.rs create mode 100644 compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs rename compiler/{rustc_passes/src => rustc_typeck/src/check}/intrinsicck.rs (83%) rename compiler/{rustc_passes/src => rustc_typeck/src/check}/region.rs (93%) create mode 100644 compiler/rustc_typeck/src/check/rvalue_scopes.rs create mode 100644 library/alloc/src/collections/btree/set_val.rs delete mode 100755 library/backtrace/ci/miri-rustup.sh create mode 100644 library/core/src/asserting.rs create mode 100644 library/core/src/cell/lazy.rs create mode 100644 library/core/src/cell/once.rs create mode 100644 library/core/src/iter/sources/from_generator.rs create mode 100644 library/core/tests/asserting.rs create mode 100644 library/proc_macro/src/bridge/selfless_reify.rs create mode 100644 library/std/src/os/horizon/fs.rs create mode 100644 library/std/src/os/horizon/mod.rs create mode 100644 library/std/src/os/horizon/raw.rs create mode 100644 library/std/src/os/windows/io/tests.rs create mode 100644 library/std/src/sync/lazy_lock.rs create mode 100644 library/std/src/sync/lazy_lock/tests.rs create mode 100644 library/std/src/sync/once_lock.rs rename library/std/src/{lazy => sync/once_lock}/tests.rs (50%) create mode 100644 library/std/src/sys_common/lazy_box.rs create mode 100644 src/bootstrap/metrics.rs delete mode 100644 src/ci/azure-pipelines/auto.yml delete mode 100644 src/ci/azure-pipelines/try.yml delete mode 100755 src/ci/scripts/clean-disk.sh delete mode 100755 src/ci/scripts/symlink-build-dir.sh rename src/doc/book/listings/ch08-common-collections/{listing-08-07 => listing-08-06}/output.txt (100%) delete mode 100644 src/doc/book/listings/ch08-common-collections/listing-08-26/Cargo.lock delete mode 100644 src/doc/book/listings/ch08-common-collections/listing-08-26/Cargo.toml delete mode 100644 src/doc/book/listings/ch08-common-collections/listing-08-26/src/main.rs delete mode 100644 src/doc/book/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.lock delete mode 100644 src/doc/book/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.toml delete mode 100644 src/doc/book/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/output.txt delete mode 100644 src/doc/book/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/src/main.rs rename src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/{listing-10-16 => listing-10-15}/src/lib.rs (100%) delete mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/main.rs create mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt create mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/src/main.rs delete mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt rename src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/{listing-10-19 => listing-10-17}/rustfmt-ignore (100%) rename src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/{listing-10-21 => listing-10-20}/output.txt (100%) rename src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/{listing-10-24 => listing-10-23}/output.txt (100%) delete mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.lock delete mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/src/main.rs delete mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.lock delete mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.toml delete mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/output.txt delete mode 100644 src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/src/main.rs create mode 100644 src/doc/book/listings/ch13-functional-features/listing-13-07/.rustfmt.toml create mode 100644 src/doc/book/listings/ch13-functional-features/listing-13-08/.rustfmt.toml create mode 100644 src/doc/book/listings/ch13-functional-features/listing-13-09/.rustfmt.toml delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-04/src/main.rs rename src/doc/book/listings/ch20-web-server/{listing-20-08 => listing-20-07}/404.html (100%) delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-08/Cargo.lock delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-08/Cargo.toml delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-08/hello.html delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-08/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-13/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-13/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-14/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-14/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-15/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-15/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-16/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-16/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-17/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-17/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-18/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-18/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-19/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-19/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-20/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-20/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-21/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-21/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-22/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-22/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-23/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-23/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/listing-20-24/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/listing-20-24/src/main.rs rename src/doc/book/listings/ch20-web-server/listing-20-25/src/{bin => }/main.rs (96%) delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-03-define-execute/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/no-listing-03-define-execute/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-05-fix-worker-new/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/no-listing-05-fix-worker-new/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/bin/main.rs create mode 100644 src/doc/book/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/main.rs delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.lock delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.toml delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-07-define-message-enum/hello.html delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-07-define-message-enum/src/bin/main.rs rename src/doc/book/listings/ch20-web-server/{no-listing-07-define-message-enum => no-listing-07-final-code}/404.html (100%) rename src/doc/book/listings/ch20-web-server/{listing-20-04 => no-listing-07-final-code}/Cargo.lock (100%) rename src/doc/book/listings/ch20-web-server/{listing-20-04 => no-listing-07-final-code}/Cargo.toml (100%) rename src/doc/book/listings/ch20-web-server/{listing-20-04 => no-listing-07-final-code}/hello.html (100%) rename src/doc/book/listings/ch20-web-server/{no-listing-07-define-message-enum => no-listing-07-final-code}/src/lib.rs (67%) rename src/doc/book/listings/ch20-web-server/{no-listing-08-final-code/src/bin => no-listing-07-final-code/src}/main.rs (92%) delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-08-final-code/404.html delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-08-final-code/Cargo.lock delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-08-final-code/Cargo.toml delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-08-final-code/hello.html delete mode 100644 src/doc/book/listings/ch20-web-server/no-listing-08-final-code/src/lib.rs create mode 100644 src/doc/book/nostarch/appendix.md create mode 100644 src/doc/book/nostarch/chapter01.md create mode 100644 src/doc/book/nostarch/chapter20.md create mode 100644 src/doc/book/nostarch/introduction.md create mode 100644 src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md delete mode 100644 src/doc/rustc-dev-guide/src/diagnostics/sessiondiagnostic.md create mode 100644 src/doc/rustc-dev-guide/src/diagnostics/translation.md create mode 100644 src/doc/rustc/src/platform-support/apple-watchos.md create mode 100644 src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md create mode 100644 src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md create mode 100644 src/doc/unstable-book/src/compiler-flags/extern-options.md create mode 100644 src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md delete mode 100644 src/doc/unstable-book/src/language-features/crate-visibility-modifier.md delete mode 100644 src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md delete mode 100644 src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md delete mode 100644 src/doc/unstable-book/src/language-features/native-link-modifiers-bundle.md delete mode 100644 src/librustdoc/html/static/images/brush.svg create mode 100644 src/test/codegen/cold-call-declare-and-call.rs create mode 100644 src/test/codegen/debug-alignment.rs create mode 100644 src/test/codegen/issue-96497-slice-size-nowrap.rs create mode 100644 src/test/codegen/noalias-refcell.rs create mode 100644 src/test/codegen/virtual-function-elimination-32bit.rs create mode 100644 src/test/codegen/virtual-function-elimination.rs create mode 100644 src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.natvis create mode 100644 src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.py create mode 100644 src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.rs rename src/test/debuginfo/{msvc-embedded-natvis.natvis => embedded-visualizer-point.natvis} (54%) create mode 100644 src/test/debuginfo/embedded-visualizer-point.py create mode 100644 src/test/debuginfo/embedded-visualizer.natvis create mode 100644 src/test/debuginfo/embedded-visualizer.py create mode 100644 src/test/debuginfo/embedded-visualizer.rs create mode 100644 src/test/debuginfo/lexical-scope-in-if-let.rs delete mode 100644 src/test/debuginfo/msvc-embedded-natvis.rs create mode 100644 src/test/debuginfo/thread-names.rs create mode 100644 src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir create mode 100644 src/test/mir-opt/asm_unwind_panic_abort.rs create mode 100644 src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff create mode 100644 src/test/mir-opt/dead-store-elimination/cycle.rs create mode 100644 src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff create mode 100644 src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff create mode 100644 src/test/mir-opt/dead-store-elimination/provenance_soundness.rs create mode 100644 src/test/mir-opt/derefer_inline_test.main.Derefer.diff create mode 100644 src/test/mir-opt/derefer_inline_test.rs delete mode 100644 src/test/mir-opt/inst_combine_deref.deep_opt.InstCombine.diff delete mode 100644 src/test/mir-opt/inst_combine_deref.do_not_miscompile.InstCombine.diff delete mode 100644 src/test/mir-opt/inst_combine_deref.dont_opt.InstCombine.diff delete mode 100644 src/test/mir-opt/inst_combine_deref.opt_struct.InstCombine.diff delete mode 100644 src/test/mir-opt/inst_combine_deref.simple_opt.InstCombine.diff create mode 100644 src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff rename src/test/mir-opt/{tls_access.main.SimplifyCfg-final.after.mir => tls_access.main.PreCodegen.after.mir} (68%) delete mode 100644 src/test/run-make-fulldeps/static-nobundle/Makefile delete mode 100644 src/test/run-make-fulldeps/static-nobundle/bbb.rs delete mode 100644 src/test/run-make-fulldeps/static-nobundle/ccc.rs delete mode 100644 src/test/run-make-fulldeps/static-nobundle/ddd.rs create mode 100644 src/test/run-make/native-link-modifier-bundle/Makefile create mode 100644 src/test/run-make/native-link-modifier-bundle/bundled.rs create mode 100644 src/test/run-make/native-link-modifier-bundle/cdylib-bundled.rs create mode 100644 src/test/run-make/native-link-modifier-bundle/cdylib-non-bundled.rs rename src/test/{run-make-fulldeps/static-nobundle/aaa.c => run-make/native-link-modifier-bundle/native-staticlib.c} (100%) create mode 100644 src/test/run-make/native-link-modifier-bundle/non-bundled.rs create mode 100644 src/test/run-make/native-link-modifier-whole-archive/directly_linked_test_minus_whole_archive.rs create mode 100644 src/test/run-make/native-link-modifier-whole-archive/directly_linked_test_plus_whole_archive.rs create mode 100644 src/test/run-make/remap-path-prefix-dwarf/Makefile create mode 100644 src/test/run-make/remap-path-prefix-dwarf/src/quux.rs create mode 100644 src/test/rustdoc-js/generics-impl.js create mode 100644 src/test/rustdoc-js/generics-impl.rs create mode 100644 src/test/rustdoc-js/impl-trait.js create mode 100644 src/test/rustdoc-js/impl-trait.rs create mode 100644 src/test/rustdoc-js/raw-pointer.js create mode 100644 src/test/rustdoc-js/raw-pointer.rs create mode 100644 src/test/rustdoc-json/fn_pointer/generics.rs create mode 100644 src/test/rustdoc-json/generic_impl.rs create mode 100644 src/test/rustdoc-json/keyword.rs create mode 100644 src/test/rustdoc-json/output_generics.rs create mode 100644 src/test/rustdoc-json/primitive_overloading.rs create mode 100644 src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs create mode 100644 src/test/rustdoc-ui/doc-comment-multi-line-attr.rs create mode 100644 src/test/rustdoc-ui/doc-comment-multi-line-attr.stdout create mode 100644 src/test/rustdoc-ui/tuple-variadic-check.rs create mode 100644 src/test/rustdoc-ui/tuple-variadic-check.stderr create mode 100644 src/test/rustdoc/anonymous-lifetime.rs create mode 100644 src/test/rustdoc/anonymous-reexport.rs create mode 100644 src/test/rustdoc/auxiliary/issue-100204-aux.rs create mode 100644 src/test/rustdoc/auxiliary/issue-98697-reexport-with-anonymous-lifetime.rs create mode 100644 src/test/rustdoc/auxiliary/issue-99221-aux.rs create mode 100644 src/test/rustdoc/auxiliary/issue-99734-aux.rs create mode 100644 src/test/rustdoc/empty-impl-block.rs create mode 100644 src/test/rustdoc/fn-bound.rs create mode 100644 src/test/rustdoc/impl-box.rs create mode 100644 src/test/rustdoc/inline_cross/auxiliary/implementors_inline.rs create mode 100644 src/test/rustdoc/inline_cross/implementors-js.rs create mode 100644 src/test/rustdoc/issue-100204-inline-impl-through-glob-import.rs create mode 100644 src/test/rustdoc/issue-98697.rs create mode 100644 src/test/rustdoc/issue-99221-multiple-macro-rules-w-same-name-submodule.rs create mode 100644 src/test/rustdoc/issue-99221-multiple-macro-rules-w-same-name.rs create mode 100644 src/test/rustdoc/issue-99221-multiple-structs-w-same-name.rs create mode 100644 src/test/rustdoc/issue-99734-multiple-foreigns-w-same-name.rs create mode 100644 src/test/rustdoc/issue-99734-multiple-mods-w-same-name.rs create mode 100644 src/test/rustdoc/nested-modules.rs create mode 100644 src/test/rustdoc/primitive-slice-auto-trait.rs create mode 100644 src/test/rustdoc/primitive-tuple-auto-trait.rs create mode 100644 src/test/rustdoc/primitive-tuple-variadic.rs create mode 100644 src/test/rustdoc/primitive-unit-auto-trait.rs create mode 100644 src/test/rustdoc/slice-links.link_box_generic.html create mode 100644 src/test/rustdoc/slice-links.link_box_u32.html create mode 100644 src/test/rustdoc/slice-links.link_slice_generic.html create mode 100644 src/test/rustdoc/slice-links.link_slice_u32.html create mode 100644 src/test/rustdoc/slice-links.rs create mode 100644 src/test/rustdoc/strip-enum-variant.no-not-shown.html create mode 100644 src/test/rustdoc/tuples.link1_i32.html create mode 100644 src/test/rustdoc/tuples.link1_t.html create mode 100644 src/test/rustdoc/tuples.link2_i32.html create mode 100644 src/test/rustdoc/tuples.link2_t.html create mode 100644 src/test/rustdoc/tuples.link2_tu.html create mode 100644 src/test/rustdoc/tuples.link_unit.html create mode 100644 src/test/ui-fulldeps/fluent-messages/duplicate-a.ftl create mode 100644 src/test/ui-fulldeps/fluent-messages/duplicate-b.ftl create mode 100644 src/test/ui-fulldeps/fluent-messages/missing-message.ftl create mode 100644 src/test/ui-fulldeps/fluent-messages/test.rs create mode 100644 src/test/ui-fulldeps/fluent-messages/test.stderr create mode 100644 src/test/ui-fulldeps/fluent-messages/valid.ftl create mode 100644 src/test/ui-fulldeps/internal-lints/diagnostics.rs create mode 100644 src/test/ui-fulldeps/internal-lints/diagnostics.stderr create mode 100644 src/test/ui-fulldeps/internal-lints/diagnostics_incorrect.rs create mode 100644 src/test/ui-fulldeps/internal-lints/diagnostics_incorrect.stderr create mode 100644 src/test/ui/argument-suggestions/issue-97484.rs create mode 100644 src/test/ui/argument-suggestions/issue-97484.stderr create mode 100644 src/test/ui/argument-suggestions/issue-98894.rs create mode 100644 src/test/ui/argument-suggestions/issue-98894.stderr create mode 100644 src/test/ui/argument-suggestions/issue-98897.rs create mode 100644 src/test/ui/argument-suggestions/issue-98897.stderr create mode 100644 src/test/ui/asm/aarch64/type-check-2-2.rs create mode 100644 src/test/ui/asm/aarch64/type-check-2-2.stderr create mode 100644 src/test/ui/asm/aarch64/type-check-4.rs create mode 100644 src/test/ui/asm/aarch64/type-check-4.stderr create mode 100644 src/test/ui/asm/generic-const.rs create mode 100644 src/test/ui/asm/issue-97490.rs create mode 100644 src/test/ui/asm/issue-99122-2.rs create mode 100644 src/test/ui/asm/issue-99122.rs create mode 100644 src/test/ui/asm/issue-99122.stderr create mode 100644 src/test/ui/asm/x86_64/type-check-4.rs create mode 100644 src/test/ui/asm/x86_64/type-check-4.stderr create mode 100644 src/test/ui/asm/x86_64/type-check-5.rs create mode 100644 src/test/ui/asm/x86_64/type-check-5.stderr create mode 100644 src/test/ui/associated-consts/issue-93775.rs delete mode 100644 src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr delete mode 100644 src/test/ui/associated-types/associated-types-eq-hr.nll.stderr delete mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.nll.stderr delete mode 100644 src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr delete mode 100644 src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.nll.stderr delete mode 100644 src/test/ui/associated-types/cache/project-fn-ret-contravariant.ok.stderr delete mode 100644 src/test/ui/associated-types/cache/project-fn-ret-contravariant.oneuse.stderr delete mode 100644 src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr delete mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr delete mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.ok.stderr delete mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr delete mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr rename src/test/ui/associated-types/{higher-ranked-projection.bad.nll.stderr => higher-ranked-projection.badbase.stderr} (91%) create mode 100644 src/test/ui/associated-types/higher-ranked-projection.badnll.stderr delete mode 100644 src/test/ui/associated-types/higher-ranked-projection.good.stderr rename src/test/ui/{issues => associated-types}/issue-20825-2.rs (100%) rename src/test/ui/{issues => associated-types}/issue-20825.rs (100%) rename src/test/ui/{issues => associated-types}/issue-20825.stderr (100%) rename src/test/ui/{issues => associated-types}/issue-47139-2.rs (100%) delete mode 100644 src/test/ui/ast-json/ast-json-ice.rs delete mode 100644 src/test/ui/ast-json/ast-json-noexpand-output.rs delete mode 100644 src/test/ui/ast-json/ast-json-noexpand-output.stdout delete mode 100644 src/test/ui/ast-json/ast-json-output.rs delete mode 100644 src/test/ui/ast-json/ast-json-output.stdout create mode 100644 src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr rename src/test/ui/async-await/{issue-70935-complex-spans.stderr => issue-70935-complex-spans.normal.stderr} (81%) delete mode 100644 src/test/ui/async-await/issue-76547.nll.stderr delete mode 100644 src/test/ui/async-await/issues/issue-62097.nll.stderr delete mode 100644 src/test/ui/async-await/issues/issue-63388-1.nll.stderr delete mode 100644 src/test/ui/async-await/issues/issue-72312.nll.stderr create mode 100644 src/test/ui/async-await/issues/issue-95307.rs create mode 100644 src/test/ui/async-await/issues/issue-95307.stderr delete mode 100644 src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr delete mode 100644 src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr delete mode 100644 src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs delete mode 100644 src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr delete mode 100644 src/test/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.nll.stderr delete mode 100644 src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.nll.stderr rename src/test/ui/borrowck/{issue-55492-borrowck-migrate-scans-parents.migrate.stderr => issue-55492-borrowck-migrate-scans-parents.stderr} (84%) create mode 100644 src/test/ui/borrowck/issue-71546.rs create mode 100644 src/test/ui/borrowck/issue-81899.rs create mode 100644 src/test/ui/borrowck/issue-81899.stderr rename src/test/ui/borrowck/{two-phase-nonrecv-autoref.nll.stderr => two-phase-nonrecv-autoref.base.stderr} (87%) delete mode 100644 src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.base.stderr delete mode 100644 src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2015.stderr delete mode 100644 src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll.stderr delete mode 100644 src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2015.stderr delete mode 100644 src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2018.stderr rename src/test/ui/borrowck/{two-phase-reservation-sharing-interference-2.migrate2018.stderr => two-phase-reservation-sharing-interference-2.stderr} (84%) rename src/test/ui/{issues => cast}/issue-10991.rs (100%) rename src/test/ui/{issues => cast}/issue-10991.stderr (100%) create mode 100644 src/test/ui/cfg/cfg-target-compact-errors.rs create mode 100644 src/test/ui/cfg/cfg-target-compact-errors.stderr create mode 100644 src/test/ui/cfg/cfg-target-compact.rs create mode 100644 src/test/ui/check-cfg/compact-names.rs create mode 100644 src/test/ui/check-cfg/compact-names.stderr create mode 100644 src/test/ui/check-cfg/compact-values.rs create mode 100644 src/test/ui/check-cfg/compact-values.stderr delete mode 100644 src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/capture-enum-field.rs create mode 100644 src/test/ui/closures/add_semicolon_non_block_closure.rs create mode 100644 src/test/ui/closures/add_semicolon_non_block_closure.stderr delete mode 100644 src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr delete mode 100644 src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.nll.stderr create mode 100644 src/test/ui/codegen/auxiliary/issue-97708-aux.rs rename src/test/ui/{issues => codegen}/issue-28950.rs (100%) create mode 100644 src/test/ui/codegen/issue-63787.rs create mode 100644 src/test/ui/codegen/issue-97708.rs create mode 100644 src/test/ui/coherence/coherence-with-closure.rs create mode 100644 src/test/ui/coherence/coherence-with-closure.stderr create mode 100644 src/test/ui/coherence/coherence-with-generator.rs create mode 100644 src/test/ui/coherence/coherence-with-generator.stderr create mode 100644 src/test/ui/conditional-compilation/cfg_accessible-bugs.rs create mode 100644 src/test/ui/conditional-compilation/cfg_accessible-bugs.stderr create mode 100644 src/test/ui/conditional-compilation/cfg_accessible-not_sure.edition2015.stderr create mode 100644 src/test/ui/conditional-compilation/cfg_accessible-not_sure.edition2021.stderr create mode 100644 src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs create mode 100644 src/test/ui/conditional-compilation/cfg_accessible-private.rs create mode 100644 src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr create mode 100644 src/test/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr create mode 100644 src/test/ui/const-generics/generic_const_exprs/dependence_lint.rs create mode 100644 src/test/ui/const-generics/generic_const_exprs/no_dependence.rs delete mode 100644 src/test/ui/const-generics/impl-trait-with-const-arguments.stderr delete mode 100644 src/test/ui/const-generics/invariant.nll.stderr create mode 100644 src/test/ui/const-generics/issue-97007.rs create mode 100644 src/test/ui/const-generics/issues/issue-67945-3.full.stderr create mode 100644 src/test/ui/const-generics/issues/issue-67945-3.min.stderr create mode 100644 src/test/ui/const-generics/issues/issue-67945-3.rs create mode 100644 src/test/ui/const-generics/issues/issue-67945-4.full.stderr create mode 100644 src/test/ui/const-generics/issues/issue-67945-4.min.stderr create mode 100644 src/test/ui/const-generics/issues/issue-67945-4.rs rename src/test/ui/const-generics/{min_const_generics/static-reference-array-const-param.stderr => issues/issue-73727-static-reference-array-const-param.min.stderr} (84%) create mode 100644 src/test/ui/const-generics/issues/issue-73727-static-reference-array-const-param.rs create mode 100644 src/test/ui/const-generics/issues/issue-88119.rs create mode 100644 src/test/ui/const-generics/issues/issue-97278.rs create mode 100644 src/test/ui/const-generics/issues/issue-97278.stderr delete mode 100644 src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs create mode 100644 src/test/ui/const-ptr/allowed_slices.rs create mode 100644 src/test/ui/const-ptr/forbidden_slices.32bit.stderr create mode 100644 src/test/ui/const-ptr/forbidden_slices.64bit.stderr create mode 100644 src/test/ui/const-ptr/forbidden_slices.rs create mode 100644 src/test/ui/consts/const-eval/format.rs create mode 100644 src/test/ui/consts/const-eval/format.stderr create mode 100644 src/test/ui/consts/const-fn-ptr.rs create mode 100644 src/test/ui/consts/const-fn-ptr.stderr rename src/test/ui/{issues => consts}/issue-39974.rs (100%) rename src/test/ui/{issues => consts}/issue-39974.stderr (100%) rename src/test/ui/{issues => consts}/issue-54387.rs (100%) create mode 100644 src/test/ui/consts/nested_erroneous_ctfe.rs create mode 100644 src/test/ui/consts/nested_erroneous_ctfe.stderr delete mode 100644 src/test/ui/deprecation/rustc_deprecated.rs delete mode 100644 src/test/ui/deprecation/rustc_deprecated.stderr create mode 100644 src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs create mode 100644 src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr create mode 100644 src/test/ui/derives/issue-97343.rs create mode 100644 src/test/ui/derives/issue-97343.stderr rename src/test/ui/{issues => deriving}/issue-6341.rs (100%) create mode 100644 src/test/ui/did_you_mean/use_instead_of_import.fixed create mode 100644 src/test/ui/did_you_mean/use_instead_of_import.rs create mode 100644 src/test/ui/did_you_mean/use_instead_of_import.stderr create mode 100644 src/test/ui/drop/repeat-drop-2.rs create mode 100644 src/test/ui/drop/repeat-drop-2.stderr create mode 100644 src/test/ui/drop/repeat-drop.rs rename src/test/ui/error-codes/{E0161.edition.stderr => E0161.base.stderr} (90%) delete mode 100644 src/test/ui/error-codes/E0161.migrate.stderr delete mode 100644 src/test/ui/error-codes/E0161.nll.stderr delete mode 100644 src/test/ui/error-codes/E0161.zflags.stderr delete mode 100644 src/test/ui/error-codes/E0490.nll.stderr delete mode 100644 src/test/ui/error-codes/E0490.rs delete mode 100644 src/test/ui/error-codes/E0490.stderr create mode 100644 src/test/ui/expr/if/bad-if-let-suggestion.rs create mode 100644 src/test/ui/expr/if/bad-if-let-suggestion.stderr create mode 100644 src/test/ui/feature-gates/auxiliary/debugger-visualizer.natvis create mode 100644 src/test/ui/feature-gates/feature-gate-cfg-target-compact.rs create mode 100644 src/test/ui/feature-gates/feature-gate-cfg-target-compact.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-crate_visibility_modifier.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-crate_visibility_modifier.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-2.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-nll.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-nll.stderr create mode 100644 src/test/ui/feature-gates/feature-gate-rust_cold_cc.rs create mode 100644 src/test/ui/feature-gates/feature-gate-rust_cold_cc.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-static-nobundle-2.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-static-nobundle-2.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-static-nobundle.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-static-nobundle.stderr delete mode 100644 src/test/ui/fn/implied-bounds-unnorm-associated-type.nll.stderr delete mode 100644 src/test/ui/for-loop-while/label_break_value.stderr delete mode 100644 src/test/ui/generator/auto-trait-regions.nll.stderr create mode 100644 src/test/ui/generator/drop-track-addassign-yield.rs create mode 100644 src/test/ui/generator/drop-tracking-yielding-in-match-guards.rs delete mode 100644 src/test/ui/generator/generator-region-requirements.nll.stderr create mode 100644 src/test/ui/generator/issue-87142.rs delete mode 100644 src/test/ui/generator/resume-arg-late-bound.nll.stderr delete mode 100644 src/test/ui/generic-associated-types/bugs/issue-89352.base.stderr create mode 100644 src/test/ui/generic-associated-types/collectivity-regression.rs create mode 100644 src/test/ui/generic-associated-types/collectivity-regression.stderr delete mode 100644 src/test/ui/generic-associated-types/extended/lending_iterator.base.nll.stderr delete mode 100644 src/test/ui/generic-associated-types/issue-86483.stderr rename src/test/ui/generic-associated-types/{bugs => }/issue-89352.rs (58%) create mode 100644 src/test/ui/generic-associated-types/issue-91139.stderr create mode 100644 src/test/ui/generic-associated-types/issue-92096.stderr delete mode 100644 src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.nll.stderr delete mode 100644 src/test/ui/generic-associated-types/trait-objects.extended.nll.stderr create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr delete mode 100644 src/test/ui/higher-rank-trait-bounds/issue-59311.nll.stderr delete mode 100644 src/test/ui/higher-rank-trait-bounds/issue-88586-hr-self-outlives-in-trait-def.stderr rename src/test/ui/higher-rank-trait-bounds/normalize-under-binder/{issue-71955.nll.stderr => issue-71955.stderr} (70%) create mode 100644 src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90875.rs delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.nll.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.nll.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.nll.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr delete mode 100644 src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.nll.stderr create mode 100644 src/test/ui/hr-subtype/placeholder-pattern-fail.rs create mode 100644 src/test/ui/hr-subtype/placeholder-pattern-fail.stderr create mode 100644 src/test/ui/hr-subtype/placeholder-pattern.rs delete mode 100644 src/test/ui/hrtb/hrtb-conflate-regions.nll.stderr delete mode 100644 src/test/ui/hrtb/hrtb-exists-forall-fn.nll.stderr delete mode 100644 src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.nll.stderr delete mode 100644 src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.nll.stderr delete mode 100644 src/test/ui/hrtb/hrtb-just-for-static.nll.stderr delete mode 100644 src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr delete mode 100644 src/test/ui/hrtb/issue-30786.migrate.stderr rename src/test/ui/hrtb/{issue-30786.nll.stderr => issue-30786.stderr} (69%) delete mode 100644 src/test/ui/hrtb/issue-46989.nll.stderr delete mode 100644 src/test/ui/hygiene/hygienic-labels-in-let.stderr delete mode 100644 src/test/ui/hygiene/hygienic-labels.stderr rename src/test/ui/{issues => hygiene}/issue-32922.rs (100%) delete mode 100644 src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr create mode 100644 src/test/ui/impl-trait/diagnostics/fully-qualified-path-impl-trait.rs create mode 100644 src/test/ui/impl-trait/diagnostics/fully-qualified-path-impl-trait.stderr rename src/test/ui/{const-generics/impl-trait-with-const-arguments.rs => impl-trait/explicit-generic-args-with-impl-trait/const-args.rs} (72%) delete mode 100644 src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs delete mode 100644 src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr rename src/test/ui/{issues => impl-trait}/issue-46959.rs (100%) rename src/test/ui/{issues => impl-trait}/issue-54966.rs (100%) rename src/test/ui/{issues => impl-trait}/issue-54966.stderr (100%) delete mode 100644 src/test/ui/impl-trait/issues/universal-issue-48703.rs delete mode 100644 src/test/ui/impl-trait/issues/universal-issue-48703.stderr delete mode 100644 src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs delete mode 100644 src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr delete mode 100644 src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr create mode 100644 src/test/ui/impl-trait/suggest-calling-rpit-closure.rs create mode 100644 src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr rename src/test/ui/{issues => imports}/issue-24883.rs (100%) rename src/test/ui/{issues => imports}/issue-26873-multifile/A/B.rs (100%) rename src/test/ui/{issues => imports}/issue-26873-multifile/A/C.rs (100%) rename src/test/ui/{issues => imports}/issue-26873-multifile/A/mod.rs (100%) rename src/test/ui/{issues => imports}/issue-26873-multifile/compiletest-ignore-dir (100%) rename src/test/ui/{issues => imports/issue-26873-multifile}/issue-26873-multifile.rs (100%) rename src/test/ui/imports/{ => issue-26873-multifile}/issue-26873-onefile.rs (100%) rename src/test/ui/{issues => imports}/issue-26873-multifile/mod.rs (100%) rename src/test/ui/{issues => imports}/issue-68103.rs (100%) create mode 100644 src/test/ui/imports/unused-imports-in-test-mode.rs create mode 100644 src/test/ui/imports/unused-imports-in-test-mode.stderr create mode 100644 src/test/ui/inference/ambiguous_type_parameter.rs create mode 100644 src/test/ui/inference/ambiguous_type_parameter.stderr rename src/test/ui/{issues => inference}/issue-72690.rs (100%) rename src/test/ui/{issues => inference}/issue-72690.stderr (74%) create mode 100644 src/test/ui/inference/need_type_info/concrete-impl.rs create mode 100644 src/test/ui/inference/need_type_info/concrete-impl.stderr create mode 100644 src/test/ui/inference/need_type_info/self-ty-in-path.rs create mode 100644 src/test/ui/inference/need_type_info/self-ty-in-path.stderr create mode 100644 src/test/ui/inference/need_type_info/type-alias-indirect.rs create mode 100644 src/test/ui/inference/need_type_info/type-alias-indirect.stderr create mode 100644 src/test/ui/inference/need_type_info/type-alias.rs create mode 100644 src/test/ui/inference/need_type_info/type-alias.stderr create mode 100644 src/test/ui/issue-94866.rs create mode 100644 src/test/ui/issue-94866.stderr delete mode 100644 src/test/ui/issues/issue-10291.nll.stderr delete mode 100644 src/test/ui/issues/issue-13058.nll.stderr delete mode 100644 src/test/ui/issues/issue-15034.nll.stderr delete mode 100644 src/test/ui/issues/issue-16683.nll.stderr delete mode 100644 src/test/ui/issues/issue-16922.nll.stderr delete mode 100644 src/test/ui/issues/issue-17728.stderr delete mode 100644 src/test/ui/issues/issue-17758.nll.stderr delete mode 100644 src/test/ui/issues/issue-26217.nll.stderr delete mode 100644 src/test/ui/issues/issue-40000.nll.stderr delete mode 100644 src/test/ui/issues/issue-46983.nll.stderr delete mode 100644 src/test/ui/issues/issue-52533.nll.stderr delete mode 100644 src/test/ui/issues/issue-54302-cases.nll.stderr delete mode 100644 src/test/ui/issues/issue-54943.nll.stderr delete mode 100644 src/test/ui/issues/issue-55731.nll.stderr delete mode 100644 src/test/ui/issues/issue-55796.stderr delete mode 100644 src/test/ui/issues/issue-68091-unicode-ident-after-if.rs delete mode 100644 src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr delete mode 100644 src/test/ui/issues/issue-75777.nll.stderr create mode 100644 src/test/ui/issues/issue-98299.rs create mode 100644 src/test/ui/issues/issue-98299.stderr rename src/test/ui/{issues => iterators}/issue-28098.rs (100%) rename src/test/ui/{issues => iterators}/issue-28098.stderr (100%) create mode 100644 src/test/ui/iterators/vec-on-unimplemented.rs create mode 100644 src/test/ui/iterators/vec-on-unimplemented.stderr delete mode 100644 src/test/ui/json-multiple.nll.stderr delete mode 100644 src/test/ui/json-options.nll.stderr delete mode 100644 src/test/ui/kindck/kindck-impl-type-params.nll.stderr delete mode 100644 src/test/ui/kindck/kindck-send-object1.nll.stderr create mode 100644 src/test/ui/lifetimes/bare-trait-object-borrowck.rs create mode 100644 src/test/ui/lifetimes/bare-trait-object.rs create mode 100644 src/test/ui/lifetimes/elided-lifetime-in-path-in-pat.rs rename src/test/ui/{issues => lifetimes}/issue-17728.rs (98%) rename src/test/ui/{issues/issue-17728.nll.stderr => lifetimes/issue-17728.stderr} (95%) create mode 100644 src/test/ui/lifetimes/issue-54378.rs rename src/test/ui/{issues => lifetimes}/issue-55796.rs (87%) rename src/test/ui/{issues/issue-55796.nll.stderr => lifetimes/issue-55796.stderr} (100%) create mode 100644 src/test/ui/lifetimes/issue-67498.rs delete mode 100644 src/test/ui/lifetimes/issue-79187-2.nll.stderr delete mode 100644 src/test/ui/lifetimes/issue-79187.nll.stderr delete mode 100644 src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr delete mode 100644 src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.nll.stderr create mode 100644 src/test/ui/lifetimes/issue-97193.rs create mode 100644 src/test/ui/lifetimes/issue-97193.stderr create mode 100644 src/test/ui/lifetimes/issue-97194.rs create mode 100644 src/test/ui/lifetimes/issue-97194.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr delete mode 100644 src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr create mode 100644 src/test/ui/lifetimes/re-empty-in-error.rs create mode 100644 src/test/ui/lifetimes/re-empty-in-error.stderr delete mode 100644 src/test/ui/linkage-attr/bad-extern-link-attrs.rs delete mode 100644 src/test/ui/linkage-attr/bad-extern-link-attrs.stderr create mode 100644 src/test/ui/linkage-attr/link-attr-validation-early.rs create mode 100644 src/test/ui/linkage-attr/link-attr-validation-early.stderr create mode 100644 src/test/ui/linkage-attr/link-attr-validation-late.rs create mode 100644 src/test/ui/linkage-attr/link-attr-validation-late.stderr create mode 100644 src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs create mode 100644 src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr rename src/test/ui/{issues => lint}/issue-35075.rs (100%) rename src/test/ui/{issues => lint}/issue-35075.stderr (100%) create mode 100644 src/test/ui/lint/issue-97094.interleaved.stderr create mode 100644 src/test/ui/lint/issue-97094.nointerleaved.stderr create mode 100644 src/test/ui/lint/issue-97094.rs create mode 100644 src/test/ui/lint/no-coverage.rs create mode 100644 src/test/ui/lint/no-coverage.stderr create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/avoid_delayed_good_path_ice.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.stderr create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.rs create mode 100644 src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.stderr delete mode 100644 src/test/ui/lint/unreachable_pub-pub_crate.rs delete mode 100644 src/test/ui/lint/unreachable_pub-pub_crate.stderr create mode 100644 src/test/ui/lint/unused/unused-macro-rules-compile-error.rs create mode 100644 src/test/ui/lint/unused/unused-macro-rules-compile-error.stderr create mode 100644 src/test/ui/lint/unused/unused-macro-rules-malformed-rule.rs create mode 100644 src/test/ui/lint/unused/unused-macro-rules-malformed-rule.stderr create mode 100644 src/test/ui/lint/unused/unused-macros-malformed-rule.rs create mode 100644 src/test/ui/lint/unused/unused-macros-malformed-rule.stderr delete mode 100644 src/test/ui/loops/loops-reject-duplicate-labels-2.rs delete mode 100644 src/test/ui/loops/loops-reject-duplicate-labels-2.stderr delete mode 100644 src/test/ui/loops/loops-reject-duplicate-labels.rs delete mode 100644 src/test/ui/loops/loops-reject-duplicate-labels.stderr delete mode 100644 src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs delete mode 100644 src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.stderr delete mode 100644 src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs delete mode 100644 src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr rename src/test/ui/{issues => lto}/issue-11154.rs (100%) rename src/test/ui/{issues => lto}/issue-11154.stderr (100%) create mode 100644 src/test/ui/lub-glb/empty-binder-future-compat.rs create mode 100644 src/test/ui/lub-glb/empty-binders-err.rs create mode 100644 src/test/ui/lub-glb/empty-binders-err.stderr create mode 100644 src/test/ui/lub-glb/empty-binders.rs create mode 100644 src/test/ui/lub-glb/old-lub-glb-hr-noteq1.baseleak.stderr rename src/test/ui/lub-glb/{old-lub-glb-hr-noteq1.nll.stderr => old-lub-glb-hr-noteq1.basenoleak.stderr} (89%) rename src/test/ui/lub-glb/{old-lub-glb-hr-noteq1.stderr => old-lub-glb-hr-noteq1.leak.stderr} (91%) create mode 100644 src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr create mode 100644 src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr create mode 100644 src/test/ui/lub-glb/old-lub-glb-hr-noteq1.noleak.stderr rename src/test/ui/lub-glb/{old-lub-glb-hr-noteq2.stderr => old-lub-glb-hr-noteq2.leak.stderr} (92%) delete mode 100644 src/test/ui/lub-glb/old-lub-glb-object.nll.stderr rename src/test/ui/macros/{assert-trailing-junk.stderr => assert-trailing-junk.with-generic-asset.stderr} (86%) create mode 100644 src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr rename src/test/ui/macros/{assert.stderr => assert.with-generic-asset.stderr} (87%) create mode 100644 src/test/ui/macros/assert.without-generic-asset.stderr create mode 100644 src/test/ui/macros/format-args-temporaries-async.rs create mode 100644 src/test/ui/macros/format-args-temporaries-in-write.rs create mode 100644 src/test/ui/macros/format-args-temporaries-in-write.stderr create mode 100644 src/test/ui/macros/format-args-temporaries.rs rename src/test/ui/{issues => macros}/issue-33185.rs (100%) rename src/test/ui/{issues => macros}/issue-8851.rs (100%) delete mode 100644 src/test/ui/macros/macro-lifetime-used-with-labels.stderr create mode 100644 src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs create mode 100644 src/test/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs create mode 100644 src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs create mode 100644 src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs create mode 100644 src/test/ui/macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs create mode 100644 src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.rs create mode 100644 src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.stdout create mode 100644 src/test/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs rename src/test/ui/{issues => match}/issue-11319.rs (100%) rename src/test/ui/{issues => match}/issue-11319.stderr (100%) rename src/test/ui/{issues => match}/issue-27021.rs (100%) rename src/test/ui/{issues => match}/issue-46920-byte-array-patterns.rs (100%) delete mode 100644 src/test/ui/match/match-ref-mut-invariance.nll.stderr delete mode 100644 src/test/ui/match/match-ref-mut-let-invariance.nll.stderr delete mode 100644 src/test/ui/mismatched_types/closure-arg-type-mismatch.nll.stderr delete mode 100644 src/test/ui/mismatched_types/closure-mismatch.nll.stderr create mode 100644 src/test/ui/mismatched_types/issue-38371-unfixable.rs create mode 100644 src/test/ui/mismatched_types/issue-38371-unfixable.stderr create mode 100644 src/test/ui/mismatched_types/issue-38371.fixed create mode 100644 src/test/ui/mismatched_types/ref-pat-suggestions.fixed create mode 100644 src/test/ui/mismatched_types/ref-pat-suggestions.rs create mode 100644 src/test/ui/mismatched_types/ref-pat-suggestions.stderr delete mode 100644 src/test/ui/nll/continue-after-missing-main.nll.stderr rename src/test/ui/{borrowck => nll}/issue-27282-move-match-input-into-guard.rs (100%) rename src/test/ui/{borrowck => nll}/issue-27282-move-match-input-into-guard.stderr (100%) rename src/test/ui/{issues => nll}/issue-27282-move-ref-mut-into-guard.rs (100%) rename src/test/ui/{issues => nll}/issue-27282-move-ref-mut-into-guard.stderr (100%) rename src/test/ui/{issues => nll}/issue-27282-mutate-before-diverging-arm-1.rs (100%) rename src/test/ui/{issues => nll}/issue-27282-mutate-before-diverging-arm-1.stderr (100%) rename src/test/ui/{borrowck => nll}/issue-27282-mutate-before-diverging-arm-2.rs (100%) rename src/test/ui/{borrowck => nll}/issue-27282-mutate-before-diverging-arm-2.stderr (100%) rename src/test/ui/{issues => nll}/issue-27282-mutate-before-diverging-arm-3.rs (100%) rename src/test/ui/{issues => nll}/issue-27282-mutate-before-diverging-arm-3.stderr (100%) rename src/test/ui/{borrowck => nll}/issue-27282-mutation-in-guard.rs (100%) rename src/test/ui/{borrowck => nll}/issue-27282-mutation-in-guard.stderr (100%) rename src/test/ui/{borrowck => nll}/issue-27282-reborrow-ref-mut-in-guard.rs (100%) rename src/test/ui/{borrowck => nll}/issue-27282-reborrow-ref-mut-in-guard.stderr (100%) rename src/test/ui/{issues => nll}/issue-46023.rs (100%) rename src/test/ui/{issues => nll}/issue-46023.stderr (100%) delete mode 100644 src/test/ui/nll/issue-50716.base.stderr rename src/test/ui/nll/{issue-50716.nll.stderr => issue-50716.stderr} (90%) rename src/test/ui/{issues => nll}/issue-52057.rs (100%) delete mode 100644 src/test/ui/nll/issue-52213.nll.stderr delete mode 100644 src/test/ui/nll/issue-52533-1.nll.stderr delete mode 100644 src/test/ui/nll/issue-52742.base.stderr rename src/test/ui/nll/{issue-52742.nll.stderr => issue-52742.stderr} (76%) delete mode 100644 src/test/ui/nll/issue-55394.base.stderr rename src/test/ui/nll/{issue-55394.nll.stderr => issue-55394.stderr} (93%) delete mode 100644 src/test/ui/nll/issue-55401.base.stderr rename src/test/ui/nll/{issue-55401.nll.stderr => issue-55401.stderr} (92%) create mode 100644 src/test/ui/nll/issue-57280-1-flipped.rs create mode 100644 src/test/ui/nll/issue-57280-1-flipped.stderr create mode 100644 src/test/ui/nll/issue-97997.rs create mode 100644 src/test/ui/nll/issue-97997.stderr create mode 100644 src/test/ui/nll/issue-98170.rs create mode 100644 src/test/ui/nll/issue-98170.stderr create mode 100644 src/test/ui/nll/issue-98693.rs rename src/test/ui/{impl-trait/type_parameters_captured.nll.stderr => nll/issue-98693.stderr} (50%) delete mode 100644 src/test/ui/nll/lub-if.base.stderr rename src/test/ui/nll/{lub-if.nll.stderr => lub-if.stderr} (91%) delete mode 100644 src/test/ui/nll/lub-match.base.stderr rename src/test/ui/nll/{lub-match.nll.stderr => lub-match.stderr} (90%) create mode 100644 src/test/ui/nll/snocat-regression.rs create mode 100644 src/test/ui/nll/snocat-regression.stderr delete mode 100644 src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.nll.stderr delete mode 100644 src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.nll.stderr delete mode 100644 src/test/ui/nll/type-alias-free-regions.base.stderr rename src/test/ui/nll/{type-alias-free-regions.nll.stderr => type-alias-free-regions.stderr} (90%) create mode 100644 src/test/ui/nll/type-test-universe.rs create mode 100644 src/test/ui/nll/type-test-universe.stderr delete mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.base.stderr rename src/test/ui/nll/user-annotations/{constant-in-expr-inherent-1.nll.stderr => constant-in-expr-inherent-1.stderr} (85%) delete mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-normalize.base.stderr rename src/test/ui/nll/user-annotations/{constant-in-expr-normalize.nll.stderr => constant-in-expr-normalize.stderr} (86%) delete mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.base.stderr rename src/test/ui/nll/user-annotations/{constant-in-expr-trait-item-1.nll.stderr => constant-in-expr-trait-item-1.stderr} (85%) delete mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.base.stderr rename src/test/ui/nll/user-annotations/{constant-in-expr-trait-item-2.nll.stderr => constant-in-expr-trait-item-2.stderr} (85%) delete mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.base.stderr rename src/test/ui/nll/user-annotations/{constant-in-expr-trait-item-3.nll.stderr => constant-in-expr-trait-item-3.stderr} (84%) create mode 100644 src/test/ui/nll/vimwiki-core-regression.rs delete mode 100644 src/test/ui/object-lifetime/object-lifetime-default-elision.nll.stderr delete mode 100644 src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr delete mode 100644 src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.nll.stderr delete mode 100644 src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.nll.stderr delete mode 100644 src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr rename src/test/ui/{issues => overloaded}/issue-14958.rs (100%) create mode 100644 src/test/ui/parser/bad-if-statements.rs create mode 100644 src/test/ui/parser/bad-if-statements.stderr create mode 100644 src/test/ui/parser/else-no-if.rs create mode 100644 src/test/ui/parser/else-no-if.stderr create mode 100644 src/test/ui/parser/if-block-unreachable-expr.rs create mode 100644 src/test/ui/parser/issue-68091-unicode-ident-after-if.rs create mode 100644 src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr rename src/test/ui/{issues => parser}/issue-68092-unicode-ident-after-incomplete-expr.rs (100%) rename src/test/ui/{issues => parser}/issue-68092-unicode-ident-after-incomplete-expr.stderr (100%) create mode 100644 src/test/ui/parser/issue-81804.rs create mode 100644 src/test/ui/parser/issue-81804.stderr create mode 100644 src/test/ui/parser/issue-81827.rs create mode 100644 src/test/ui/parser/issue-81827.stderr create mode 100644 src/test/ui/parser/issues/issue-93867.rs create mode 100644 src/test/ui/parser/issues/issue-93867.stderr create mode 100644 src/test/ui/parser/recover-labeled-non-block-expr.fixed create mode 100644 src/test/ui/parser/unsafe-foreign-mod-2.rs create mode 100644 src/test/ui/parser/unsafe-foreign-mod-2.stderr create mode 100644 src/test/ui/pattern/for-loop-bad-item.rs create mode 100644 src/test/ui/pattern/for-loop-bad-item.stderr rename src/test/ui/{issues => pattern}/issue-27320.rs (100%) create mode 100644 src/test/ui/privacy/auxiliary/ctor_aux.rs create mode 100644 src/test/ui/privacy/ctor.rs create mode 100644 src/test/ui/privacy/macro-private-reexport.rs create mode 100644 src/test/ui/privacy/macro-private-reexport.stderr create mode 100644 src/test/ui/proc-macro/auxiliary/issue-91800-macro.rs create mode 100644 src/test/ui/proc-macro/issue-91800.rs create mode 100644 src/test/ui/proc-macro/issue-91800.stderr rename src/test/ui/{issues => process}/issue-13304.rs (100%) create mode 100644 src/test/ui/process/nofile-limit.rs create mode 100644 src/test/ui/regions/forall-wf-ref-reflexive.rs create mode 100644 src/test/ui/regions/forall-wf-ref-reflexive.stderr create mode 100644 src/test/ui/regions/forall-wf-reflexive.rs delete mode 100644 src/test/ui/regions/issue-28848.base.stderr rename src/test/ui/regions/{issue-28848.nll.stderr => issue-28848.stderr} (92%) rename src/test/ui/regions/{issue-78262.nll.stderr => issue-78262.base.stderr} (94%) delete mode 100644 src/test/ui/regions/issue-78262.default.stderr delete mode 100644 src/test/ui/regions/region-invariant-static-error-reporting.base.stderr rename src/test/ui/regions/{region-invariant-static-error-reporting.nll.stderr => region-invariant-static-error-reporting.stderr} (93%) delete mode 100644 src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.base.stderr delete mode 100644 src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr create mode 100644 src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr delete mode 100644 src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.base.stderr delete mode 100644 src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr create mode 100644 src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr delete mode 100644 src/test/ui/regions/region-object-lifetime-2.base.stderr rename src/test/ui/regions/{region-object-lifetime-2.nll.stderr => region-object-lifetime-2.stderr} (92%) delete mode 100644 src/test/ui/regions/region-object-lifetime-4.base.stderr rename src/test/ui/regions/{region-object-lifetime-4.nll.stderr => region-object-lifetime-4.stderr} (92%) delete mode 100644 src/test/ui/regions/region-object-lifetime-in-coercion.base.stderr rename src/test/ui/regions/{region-object-lifetime-in-coercion.nll.stderr => region-object-lifetime-in-coercion.stderr} (90%) delete mode 100644 src/test/ui/regions/regions-addr-of-self.base.stderr rename src/test/ui/regions/{regions-addr-of-self.nll.stderr => regions-addr-of-self.stderr} (89%) delete mode 100644 src/test/ui/regions/regions-addr-of-upvar-self.base.stderr rename src/test/ui/regions/{regions-addr-of-upvar-self.nll.stderr => regions-addr-of-upvar-self.stderr} (90%) delete mode 100644 src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr rename src/test/ui/regions/{regions-assoc-type-in-supertrait-outlives-container.nll.stderr => regions-assoc-type-in-supertrait-outlives-container.stderr} (98%) delete mode 100644 src/test/ui/regions/regions-bounded-by-trait-requiring-static.base.stderr rename src/test/ui/regions/{regions-bounded-by-trait-requiring-static.nll.stderr => regions-bounded-by-trait-requiring-static.stderr} (84%) delete mode 100644 src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.base.stderr rename src/test/ui/regions/{regions-bounded-method-type-parameters-cross-crate.nll.stderr => regions-bounded-method-type-parameters-cross-crate.stderr} (99%) delete mode 100644 src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.base.stderr rename src/test/ui/regions/{regions-bounded-method-type-parameters-trait-bound.nll.stderr => regions-bounded-method-type-parameters-trait-bound.stderr} (99%) delete mode 100644 src/test/ui/regions/regions-bounded-method-type-parameters.base.stderr rename src/test/ui/regions/{regions-bounded-method-type-parameters.nll.stderr => regions-bounded-method-type-parameters.stderr} (82%) delete mode 100644 src/test/ui/regions/regions-bounds.base.stderr rename src/test/ui/regions/{regions-bounds.nll.stderr => regions-bounds.stderr} (92%) delete mode 100644 src/test/ui/regions/regions-close-associated-type-into-object.base.stderr rename src/test/ui/regions/{regions-close-associated-type-into-object.nll.stderr => regions-close-associated-type-into-object.stderr} (85%) delete mode 100644 src/test/ui/regions/regions-close-object-into-object-2.base.stderr rename src/test/ui/regions/{regions-close-object-into-object-2.nll.stderr => regions-close-object-into-object-2.stderr} (91%) delete mode 100644 src/test/ui/regions/regions-close-object-into-object-4.base.stderr rename src/test/ui/regions/{regions-close-object-into-object-4.nll.stderr => regions-close-object-into-object-4.stderr} (88%) delete mode 100644 src/test/ui/regions/regions-close-object-into-object-5.base.stderr rename src/test/ui/regions/{regions-close-object-into-object-5.nll.stderr => regions-close-object-into-object-5.stderr} (87%) delete mode 100644 src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr rename src/test/ui/regions/{regions-close-over-type-parameter-1.base.stderr => regions-close-over-type-parameter-1.stderr} (89%) delete mode 100644 src/test/ui/regions/regions-close-over-type-parameter-multiple.base.stderr rename src/test/ui/regions/{regions-close-over-type-parameter-multiple.nll.stderr => regions-close-over-type-parameter-multiple.stderr} (90%) delete mode 100644 src/test/ui/regions/regions-close-param-into-object.base.stderr rename src/test/ui/regions/{regions-close-param-into-object.nll.stderr => regions-close-param-into-object.stderr} (87%) delete mode 100644 src/test/ui/regions/regions-creating-enums3.base.stderr rename src/test/ui/regions/{regions-creating-enums3.nll.stderr => regions-creating-enums3.stderr} (91%) delete mode 100644 src/test/ui/regions/regions-creating-enums4.base.stderr rename src/test/ui/regions/{regions-creating-enums4.nll.stderr => regions-creating-enums4.stderr} (92%) delete mode 100644 src/test/ui/regions/regions-early-bound-error-method.base.stderr rename src/test/ui/regions/{regions-early-bound-error-method.nll.stderr => regions-early-bound-error-method.stderr} (90%) delete mode 100644 src/test/ui/regions/regions-early-bound-error.base.stderr rename src/test/ui/regions/{regions-early-bound-error.nll.stderr => regions-early-bound-error.stderr} (91%) delete mode 100644 src/test/ui/regions/regions-fn-subtyping-return-static-fail.base.stderr delete mode 100644 src/test/ui/regions/regions-fn-subtyping-return-static-fail.nll.stderr create mode 100644 src/test/ui/regions/regions-fn-subtyping-return-static-fail.stderr delete mode 100644 src/test/ui/regions/regions-free-region-ordering-callee.base.stderr rename src/test/ui/regions/{regions-free-region-ordering-callee.nll.stderr => regions-free-region-ordering-callee.stderr} (89%) delete mode 100644 src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr rename src/test/ui/regions/{regions-free-region-ordering-caller.nll.stderr => regions-free-region-ordering-caller.stderr} (88%) delete mode 100644 src/test/ui/regions/regions-free-region-ordering-incorrect.base.stderr rename src/test/ui/regions/{regions-free-region-ordering-incorrect.nll.stderr => regions-free-region-ordering-incorrect.stderr} (90%) delete mode 100644 src/test/ui/regions/regions-implied-bounds-projection-gap-1.base.stderr rename src/test/ui/regions/{regions-implied-bounds-projection-gap-1.nll.stderr => regions-implied-bounds-projection-gap-1.stderr} (87%) delete mode 100644 src/test/ui/regions/regions-infer-bound-from-trait-self.base.stderr rename src/test/ui/regions/{regions-infer-bound-from-trait-self.nll.stderr => regions-infer-bound-from-trait-self.stderr} (87%) delete mode 100644 src/test/ui/regions/regions-infer-bound-from-trait.base.stderr rename src/test/ui/regions/{regions-infer-bound-from-trait.nll.stderr => regions-infer-bound-from-trait.stderr} (94%) delete mode 100644 src/test/ui/regions/regions-infer-contravariance-due-to-decl.base.stderr rename src/test/ui/regions/{regions-infer-contravariance-due-to-decl.nll.stderr => regions-infer-contravariance-due-to-decl.stderr} (88%) delete mode 100644 src/test/ui/regions/regions-infer-covariance-due-to-decl.base.stderr rename src/test/ui/regions/{regions-infer-covariance-due-to-decl.nll.stderr => regions-infer-covariance-due-to-decl.stderr} (88%) delete mode 100644 src/test/ui/regions/regions-infer-invariance-due-to-decl.base.stderr rename src/test/ui/regions/{regions-infer-invariance-due-to-decl.nll.stderr => regions-infer-invariance-due-to-decl.stderr} (91%) delete mode 100644 src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.base.stderr rename src/test/ui/regions/{regions-infer-invariance-due-to-mutability-4.nll.stderr => regions-infer-invariance-due-to-mutability-3.stderr} (90%) delete mode 100644 src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.base.stderr rename src/test/ui/regions/{regions-infer-invariance-due-to-mutability-3.nll.stderr => regions-infer-invariance-due-to-mutability-4.stderr} (90%) delete mode 100644 src/test/ui/regions/regions-infer-not-param.base.stderr rename src/test/ui/regions/{regions-infer-not-param.nll.stderr => regions-infer-not-param.stderr} (93%) delete mode 100644 src/test/ui/regions/regions-infer-paramd-indirect.base.stderr rename src/test/ui/regions/{regions-infer-paramd-indirect.nll.stderr => regions-infer-paramd-indirect.stderr} (88%) delete mode 100644 src/test/ui/regions/regions-lifetime-bounds-on-fns.base.stderr delete mode 100644 src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr create mode 100644 src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr delete mode 100644 src/test/ui/regions/regions-nested-fns.base.stderr rename src/test/ui/regions/{regions-nested-fns.nll.stderr => regions-nested-fns.stderr} (91%) delete mode 100644 src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr rename src/test/ui/regions/{regions-outlives-projection-container-hrtb.nll.stderr => regions-outlives-projection-container-hrtb.stderr} (87%) delete mode 100644 src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr rename src/test/ui/regions/{regions-outlives-projection-container-wc.nll.stderr => regions-outlives-projection-container-wc.stderr} (88%) delete mode 100644 src/test/ui/regions/regions-outlives-projection-container.base.stderr rename src/test/ui/regions/{regions-outlives-projection-container.nll.stderr => regions-outlives-projection-container.stderr} (88%) delete mode 100644 src/test/ui/regions/regions-proc-bound-capture.base.stderr rename src/test/ui/regions/{regions-proc-bound-capture.nll.stderr => regions-proc-bound-capture.stderr} (95%) delete mode 100644 src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.base.stderr rename src/test/ui/regions/{regions-reborrow-from-shorter-mut-ref-mut-ref.nll.stderr => regions-reborrow-from-shorter-mut-ref-mut-ref.stderr} (89%) delete mode 100644 src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.base.stderr rename src/test/ui/regions/{regions-reborrow-from-shorter-mut-ref.nll.stderr => regions-reborrow-from-shorter-mut-ref.stderr} (89%) delete mode 100644 src/test/ui/regions/regions-ret-borrowed-1.base.stderr rename src/test/ui/regions/{regions-ret-borrowed-1.nll.stderr => regions-ret-borrowed-1.stderr} (87%) delete mode 100644 src/test/ui/regions/regions-ret-borrowed.base.stderr rename src/test/ui/regions/{regions-ret-borrowed.nll.stderr => regions-ret-borrowed.stderr} (87%) delete mode 100644 src/test/ui/regions/regions-static-bound.base.stderr rename src/test/ui/regions/{regions-static-bound.nll.stderr => regions-static-bound.stderr} (89%) delete mode 100644 src/test/ui/regions/regions-trait-object-subtyping.base.stderr rename src/test/ui/regions/{regions-trait-object-subtyping.nll.stderr => regions-trait-object-subtyping.stderr} (93%) delete mode 100644 src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.base.stderr rename src/test/ui/regions/{regions-variance-contravariant-use-covariant-in-second-position.nll.stderr => regions-variance-contravariant-use-covariant-in-second-position.stderr} (96%) delete mode 100644 src/test/ui/regions/regions-variance-contravariant-use-covariant.base.stderr rename src/test/ui/regions/{regions-variance-contravariant-use-covariant.nll.stderr => regions-variance-contravariant-use-covariant.stderr} (87%) delete mode 100644 src/test/ui/regions/regions-variance-covariant-use-contravariant.base.stderr rename src/test/ui/regions/{regions-variance-covariant-use-contravariant.nll.stderr => regions-variance-covariant-use-contravariant.stderr} (87%) delete mode 100644 src/test/ui/regions/regions-variance-invariant-use-contravariant.base.stderr rename src/test/ui/regions/{regions-variance-invariant-use-contravariant.nll.stderr => regions-variance-invariant-use-contravariant.stderr} (92%) delete mode 100644 src/test/ui/regions/regions-variance-invariant-use-covariant.base.stderr rename src/test/ui/regions/{regions-variance-invariant-use-covariant.nll.stderr => regions-variance-invariant-use-covariant.stderr} (90%) create mode 100644 src/test/ui/resolve/filter-intrinsics.rs create mode 100644 src/test/ui/resolve/filter-intrinsics.stderr create mode 100644 src/test/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs create mode 100644 src/test/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr create mode 100644 src/test/ui/rfc-1717-dllimport/rename-modifiers.rs create mode 100644 src/test/ui/rfc-1717-dllimport/rename-modifiers.stderr delete mode 100644 src/test/ui/rfc-2093-infer-outlives/infer-static.rs delete mode 100644 src/test/ui/rfc-2093-infer-outlives/infer-static.stderr delete mode 100644 src/test/ui/rfc-2632-const-trait-impl/stability.rs delete mode 100644 src/test/ui/rfc-2632-const-trait-impl/stability.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/staged-api-user-crate.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/staged-api-user-crate.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/staged-api.stable.stderr delete mode 100644 src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr delete mode 100644 src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/staged-api.unstable.stderr delete mode 100644 src/test/ui/rfc1623.base.stderr rename src/test/ui/{rfc1623.nll.stderr => rfc1623.stderr} (77%) create mode 100644 src/test/ui/rfcs/rfc-2528-type-changing-struct-update/coerce-in-base-expr.rs create mode 100644 src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs delete mode 100644 src/test/ui/rmeta/emit-artifact-notifications.nll.stderr delete mode 100644 src/test/ui/save-analysis/emit-notifications.nll.stderr rename src/test/ui/{issues => save-analysis}/issue-26459.rs (100%) rename src/test/ui/{issues => save-analysis}/issue-26459.stderr (100%) delete mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.base.stderr rename src/test/ui/self/{arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr => arbitrary_self_types_pin_lifetime_mismatch-async.stderr} (75%) delete mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.base.stderr rename src/test/ui/self/{arbitrary_self_types_pin_lifetime_mismatch.nll.stderr => arbitrary_self_types_pin_lifetime_mismatch.stderr} (90%) delete mode 100644 src/test/ui/self/elision/lt-ref-self-async.base.stderr rename src/test/ui/self/elision/{lt-ref-self-async.nll.stderr => lt-ref-self-async.stderr} (65%) delete mode 100644 src/test/ui/self/elision/lt-ref-self.base.stderr rename src/test/ui/self/elision/{lt-ref-self.nll.stderr => lt-ref-self.stderr} (96%) delete mode 100644 src/test/ui/self/elision/ref-mut-self-async.base.stderr rename src/test/ui/self/elision/{ref-mut-self-async.nll.stderr => ref-mut-self-async.stderr} (65%) delete mode 100644 src/test/ui/self/elision/ref-mut-self.base.stderr rename src/test/ui/self/elision/{ref-mut-self.nll.stderr => ref-mut-self.stderr} (96%) delete mode 100644 src/test/ui/self/elision/ref-mut-struct-async.base.stderr rename src/test/ui/self/elision/{ref-mut-struct-async.nll.stderr => ref-mut-struct-async.stderr} (65%) delete mode 100644 src/test/ui/self/elision/ref-mut-struct.base.stderr rename src/test/ui/self/elision/{ref-mut-struct.nll.stderr => ref-mut-struct.stderr} (96%) delete mode 100644 src/test/ui/self/elision/ref-self-async.base.stderr rename src/test/ui/self/elision/{ref-self-async.nll.stderr => ref-self-async.stderr} (65%) delete mode 100644 src/test/ui/self/elision/ref-self.base.stderr rename src/test/ui/self/elision/{ref-self.nll.stderr => ref-self.stderr} (96%) delete mode 100644 src/test/ui/self/elision/ref-struct-async.base.stderr rename src/test/ui/self/elision/{ref-struct-async.nll.stderr => ref-struct-async.stderr} (65%) delete mode 100644 src/test/ui/self/elision/ref-struct.base.stderr rename src/test/ui/self/elision/{ref-struct.nll.stderr => ref-struct.stderr} (96%) create mode 100644 src/test/ui/span/issue-71363.rs create mode 100644 src/test/ui/span/issue-71363.stderr create mode 100644 src/test/ui/stability-attribute/allow-unstable-reexport.rs create mode 100644 src/test/ui/stability-attribute/allow-unstable-reexport.stderr create mode 100644 src/test/ui/stability-attribute/auxiliary/lint-stability-reexport.rs create mode 100644 src/test/ui/suggestions/args-instead-of-tuple.fixed create mode 100644 src/test/ui/suggestions/enum-method-probe.fixed create mode 100644 src/test/ui/suggestions/enum-method-probe.rs create mode 100644 src/test/ui/suggestions/enum-method-probe.stderr delete mode 100644 src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr delete mode 100644 src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.fixed delete mode 100644 src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.nll.stderr create mode 100644 src/test/ui/suggestions/issue-97677.rs create mode 100644 src/test/ui/suggestions/issue-97677.stderr create mode 100644 src/test/ui/suggestions/issue-97704.fixed create mode 100644 src/test/ui/suggestions/issue-97704.rs create mode 100644 src/test/ui/suggestions/issue-97704.stderr create mode 100644 src/test/ui/suggestions/issue-97760.rs create mode 100644 src/test/ui/suggestions/issue-97760.stderr delete mode 100644 src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.nll.stderr delete mode 100644 src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr delete mode 100644 src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr create mode 100644 src/test/ui/suggestions/missing-bound-in-derive-copy-impl-2.fixed create mode 100644 src/test/ui/suggestions/missing-bound-in-derive-copy-impl-2.rs create mode 100644 src/test/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr create mode 100644 src/test/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed create mode 100644 src/test/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs create mode 100644 src/test/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr create mode 100644 src/test/ui/suggestions/missing-bound-in-derive-copy-impl.rs create mode 100644 src/test/ui/suggestions/missing-bound-in-derive-copy-impl.stderr delete mode 100644 src/test/ui/suggestions/suggest-impl-trait-lifetime.nll.stderr create mode 100644 src/test/ui/suggestions/suggest-std-when-using-type.fixed create mode 100644 src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs create mode 100644 src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr create mode 100644 src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs create mode 100644 src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr rename src/test/ui/{issues => test-attrs}/issue-16597-empty.rs (100%) rename src/test/ui/{issues => test-attrs}/issue-16597.rs (100%) delete mode 100644 src/test/ui/trait-bounds/issue-93008.stderr create mode 100644 src/test/ui/trait-bounds/issue-94680.rs create mode 100644 src/test/ui/trait-bounds/issue-94999.rs create mode 100644 src/test/ui/trait-bounds/issue-95640.rs create mode 100644 src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs create mode 100644 src/test/ui/trait-bounds/select-param-env-instead-of-blanket.stderr rename src/test/ui/{issues => traits}/issue-18400.rs (100%) rename src/test/ui/{issues => traits}/issue-18400.stderr (100%) rename src/test/ui/{issues => traits}/issue-18412.rs (100%) rename src/test/ui/{issues => traits}/issue-35869.rs (100%) rename src/test/ui/{issues => traits}/issue-35869.stderr (100%) rename src/test/ui/{issues => traits}/issue-38033.rs (100%) rename src/test/ui/{issues => traits}/issue-8153.rs (100%) rename src/test/ui/{issues => traits}/issue-8153.stderr (100%) create mode 100644 src/test/ui/traits/issue-82830.rs create mode 100644 src/test/ui/traits/issue-82830.stderr create mode 100644 src/test/ui/traits/issue-91949-hangs-on-recursion.rs create mode 100644 src/test/ui/traits/issue-91949-hangs-on-recursion.stderr create mode 100644 src/test/ui/traits/issue-97576.rs create mode 100644 src/test/ui/traits/issue-97576.stderr create mode 100644 src/test/ui/traits/issue-97695-double-trivial-bound.rs delete mode 100644 src/test/ui/traits/object/supertrait-lifetime-bound.nll.stderr create mode 100644 src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.rs create mode 100644 src/test/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr delete mode 100644 src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.rs delete mode 100644 src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.stderr create mode 100644 src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.rs create mode 100644 src/test/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr create mode 100644 src/test/ui/traits/vtable/issue-97381.rs create mode 100644 src/test/ui/traits/vtable/issue-97381.stderr delete mode 100644 src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr rename src/test/ui/type-alias-impl-trait/{generic_type_does_not_live_long_enough.base.stderr => generic_type_does_not_live_long_enough.stderr} (77%) create mode 100644 src/test/ui/type-alias-impl-trait/issue-53092-2.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-53092-2.stderr create mode 100644 src/test/ui/type-alias-impl-trait/issue-53092.stderr delete mode 100644 src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.base.stderr rename src/test/ui/type-alias-impl-trait/{issue-57611-trait-alias.nll.stderr => issue-57611-trait-alias.stderr} (76%) create mode 100644 src/test/ui/type-alias-impl-trait/issue-90400-1.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-90400-1.stderr create mode 100644 src/test/ui/type-alias-impl-trait/issue-90400-2.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-90400-2.stderr create mode 100644 src/test/ui/type-alias-impl-trait/wf_check_closures.stderr rename src/test/ui/{issues => type-alias}/issue-14933.rs (100%) create mode 100644 src/test/ui/type/type-unsatisfiable.rs create mode 100644 src/test/ui/type/type-unsatisfiable.usage.stderr create mode 100644 src/test/ui/typeck/assign-non-lval-derefmut.fixed create mode 100644 src/test/ui/typeck/assign-non-lval-derefmut.rs create mode 100644 src/test/ui/typeck/assign-non-lval-derefmut.stderr create mode 100644 src/test/ui/typeck/assign-non-lval-mut-ref.fixed create mode 100644 src/test/ui/typeck/assign-non-lval-mut-ref.rs create mode 100644 src/test/ui/typeck/assign-non-lval-mut-ref.stderr rename src/test/ui/{issues => typeck}/auxiliary/issue-36708.rs (100%) rename src/test/ui/{issues => typeck}/issue-10401.rs (100%) rename src/test/ui/{issues => typeck}/issue-10401.stderr (100%) rename src/test/ui/{issues => typeck}/issue-13853-2.rs (100%) rename src/test/ui/{issues => typeck}/issue-13853-2.stderr (100%) rename src/test/ui/{issues => typeck}/issue-13853-5.rs (100%) rename src/test/ui/{issues => typeck}/issue-13853-5.stderr (100%) rename src/test/ui/{issues => typeck}/issue-13853.rs (100%) rename src/test/ui/{issues => typeck}/issue-13853.stderr (73%) rename src/test/ui/{issues => typeck}/issue-29124.rs (100%) rename src/test/ui/{issues => typeck}/issue-29124.stderr (100%) rename src/test/ui/{issues => typeck}/issue-36708.rs (100%) rename src/test/ui/{issues => typeck}/issue-36708.stderr (100%) create mode 100644 src/test/ui/typeck/issue-88643.rs create mode 100644 src/test/ui/typeck/issue-88643.stderr create mode 100644 src/test/ui/typeck/missing-private-fields-in-struct-literal.rs create mode 100644 src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr create mode 100644 src/test/ui/typeck/prim-with-args.fixed create mode 100644 src/test/ui/typeck/remove-extra-argument.fixed delete mode 100644 src/test/ui/unboxed-closures/issue-30906.base.stderr rename src/test/ui/unboxed-closures/{issue-30906.nll.stderr => issue-30906.stderr} (92%) delete mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.base.stderr rename src/test/ui/unboxed-closures/{unboxed-closures-infer-argument-types-two-region-pointers.nll.stderr => unboxed-closures-infer-argument-types-two-region-pointers.stderr} (96%) delete mode 100644 src/test/ui/underscore-lifetime/dyn-trait-underscore.base.stderr rename src/test/ui/underscore-lifetime/{dyn-trait-underscore.nll.stderr => dyn-trait-underscore.stderr} (94%) delete mode 100644 src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.base.stderr rename src/test/ui/underscore-lifetime/{underscore-lifetime-elison-mismatch.nll.stderr => underscore-lifetime-elison-mismatch.stderr} (91%) rename src/test/ui/{issues => unsafe}/issue-3080.mir.stderr (100%) rename src/test/ui/{issues => unsafe}/issue-3080.rs (100%) rename src/test/ui/{issues => unsafe}/issue-3080.thir.stderr (100%) rename src/test/ui/{issues => unsafe}/issue-47412.mir.stderr (100%) rename src/test/ui/{issues => unsafe}/issue-47412.rs (100%) rename src/test/ui/{issues => unsafe}/issue-47412.thir.stderr (100%) rename src/test/ui/{issues => unsized}/issue-40231-1.rs (100%) rename src/test/ui/{issues => unsized}/issue-40231-2.rs (100%) create mode 100644 src/test/ui/unsized/issue-97732.rs delete mode 100644 src/test/ui/variance/variance-associated-types2.base.stderr rename src/test/ui/variance/{variance-associated-types2.nll.stderr => variance-associated-types2.stderr} (87%) delete mode 100644 src/test/ui/variance/variance-btree-invariant-types.base.stderr rename src/test/ui/variance/{variance-btree-invariant-types.nll.stderr => variance-btree-invariant-types.stderr} (91%) delete mode 100644 src/test/ui/variance/variance-cell-is-invariant.base.stderr rename src/test/ui/variance/{variance-cell-is-invariant.nll.stderr => variance-cell-is-invariant.stderr} (93%) delete mode 100644 src/test/ui/variance/variance-contravariant-arg-object.base.stderr rename src/test/ui/variance/{variance-contravariant-arg-object.nll.stderr => variance-contravariant-arg-object.stderr} (83%) delete mode 100644 src/test/ui/variance/variance-contravariant-arg-trait-match.base.stderr rename src/test/ui/variance/{variance-contravariant-arg-trait-match.nll.stderr => variance-contravariant-arg-trait-match.stderr} (88%) delete mode 100644 src/test/ui/variance/variance-contravariant-self-trait-match.base.stderr rename src/test/ui/variance/{variance-contravariant-self-trait-match.nll.stderr => variance-contravariant-self-trait-match.stderr} (87%) delete mode 100644 src/test/ui/variance/variance-covariant-arg-object.base.stderr rename src/test/ui/variance/{variance-invariant-arg-object.nll.stderr => variance-covariant-arg-object.stderr} (84%) delete mode 100644 src/test/ui/variance/variance-covariant-arg-trait-match.base.stderr rename src/test/ui/variance/{variance-invariant-arg-trait-match.nll.stderr => variance-covariant-arg-trait-match.stderr} (89%) delete mode 100644 src/test/ui/variance/variance-covariant-self-trait-match.base.stderr rename src/test/ui/variance/{variance-covariant-self-trait-match.nll.stderr => variance-covariant-self-trait-match.stderr} (88%) delete mode 100644 src/test/ui/variance/variance-invariant-arg-object.base.stderr rename src/test/ui/variance/{variance-covariant-arg-object.nll.stderr => variance-invariant-arg-object.stderr} (84%) delete mode 100644 src/test/ui/variance/variance-invariant-arg-trait-match.base.stderr rename src/test/ui/variance/{variance-covariant-arg-trait-match.nll.stderr => variance-invariant-arg-trait-match.stderr} (89%) delete mode 100644 src/test/ui/variance/variance-invariant-self-trait-match.base.stderr rename src/test/ui/variance/{variance-invariant-self-trait-match.nll.stderr => variance-invariant-self-trait-match.stderr} (88%) delete mode 100644 src/test/ui/variance/variance-trait-matching.base.stderr rename src/test/ui/variance/{variance-trait-matching.nll.stderr => variance-trait-matching.stderr} (89%) delete mode 100644 src/test/ui/variance/variance-use-contravariant-struct-1.base.stderr rename src/test/ui/variance/{variance-use-contravariant-struct-1.nll.stderr => variance-use-contravariant-struct-1.stderr} (88%) delete mode 100644 src/test/ui/variance/variance-use-covariant-struct-1.base.stderr rename src/test/ui/variance/{variance-use-covariant-struct-1.nll.stderr => variance-use-covariant-struct-1.stderr} (89%) delete mode 100644 src/test/ui/variance/variance-use-invariant-struct-1.base.stderr rename src/test/ui/variance/{variance-use-invariant-struct-1.nll.stderr => variance-use-invariant-struct-1.stderr} (93%) create mode 100644 src/test/ui/wf/issue-95665.rs create mode 100644 src/test/ui/wf/issue-95665.stderr delete mode 100644 src/test/ui/wf/wf-static-method.base.stderr rename src/test/ui/wf/{wf-static-method.nll.stderr => wf-static-method.stderr} (92%) delete mode 100644 src/test/ui/where-clauses/where-for-self-2.base.stderr rename src/test/ui/where-clauses/{where-for-self-2.nll.stderr => where-for-self-2.stderr} (90%) create mode 100644 src/tools/clippy/book/README.md create mode 100644 src/tools/clippy/book/book.toml create mode 100644 src/tools/clippy/book/src/README.md create mode 100644 src/tools/clippy/book/src/SUMMARY.md create mode 100644 src/tools/clippy/book/src/configuration.md create mode 100644 src/tools/clippy/book/src/continuous_integration/README.md create mode 100644 src/tools/clippy/book/src/continuous_integration/github_actions.md create mode 100644 src/tools/clippy/book/src/continuous_integration/travis.md create mode 100644 src/tools/clippy/book/src/development/README.md rename src/tools/clippy/{doc => book/src/development}/adding_lints.md (72%) rename src/tools/clippy/{doc => book/src/development}/basics.md (75%) rename src/tools/clippy/{doc => book/src/development}/common_tools_writing_lints.md (70%) create mode 100644 src/tools/clippy/book/src/development/infrastructure/README.md rename src/tools/clippy/{doc => book/src/development/infrastructure}/backport.md (100%) create mode 100644 src/tools/clippy/book/src/development/infrastructure/book.md rename src/tools/clippy/{doc => book/src/development/infrastructure}/changelog_update.md (78%) rename src/tools/clippy/{doc => book/src/development/infrastructure}/release.md (85%) create mode 100644 src/tools/clippy/book/src/development/infrastructure/sync.md create mode 100644 src/tools/clippy/book/src/development/proposals/README.md rename src/tools/clippy/{doc => book/src/development/proposals}/roadmap-2021.md (100%) create mode 100644 src/tools/clippy/book/src/installation.md create mode 100644 src/tools/clippy/book/src/lints.md create mode 100644 src/tools/clippy/book/src/usage.md create mode 100644 src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs create mode 100644 src/tools/clippy/clippy_lints/src/as_underscore.rs create mode 100644 src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs create mode 100644 src/tools/clippy/clippy_lints/src/doc_link_with_quotes.rs create mode 100644 src/tools/clippy/clippy_lints/src/duplicate_mod.rs create mode 100644 src/tools/clippy/clippy_lints/src/get_first.rs delete mode 100644 src/tools/clippy/clippy_lints/src/get_last_with_len.rs delete mode 100644 src/tools/clippy/clippy_lints/src/manual_map.rs delete mode 100644 src/tools/clippy/clippy_lints/src/manual_unwrap_or.rs delete mode 100644 src/tools/clippy/clippy_lints/src/match_on_vec_items.rs rename src/tools/clippy/clippy_lints/src/{ => matches}/collapsible_match.rs (68%) create mode 100644 src/tools/clippy/clippy_lints/src/matches/manual_map.rs create mode 100644 src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs create mode 100644 src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs rename src/tools/clippy/clippy_lints/src/{ => matches}/match_str_case_mismatch.rs (64%) rename src/tools/clippy/clippy_lints/src/{ => matches}/significant_drop_in_scrutinee.rs (60%) create mode 100644 src/tools/clippy/clippy_lints/src/matches/try_err.rs create mode 100644 src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs create mode 100644 src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs create mode 100644 src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs rename src/tools/clippy/clippy_lints/src/{eval_order_dependence.rs => mixed_read_write_in_expression.rs} (96%) create mode 100644 src/tools/clippy/clippy_lints/src/needless_parens_on_range_literals.rs rename src/tools/clippy/clippy_lints/src/{arithmetic.rs => numeric_arithmetic.rs} (97%) create mode 100644 src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs create mode 100644 src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs create mode 100644 src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs delete mode 100644 src/tools/clippy/clippy_lints/src/try_err.rs create mode 100644 src/tools/clippy/clippy_lints/src/unused_rounding.rs create mode 100644 src/tools/clippy/lintcheck/src/config.rs rename src/{doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26 => tools/clippy/tests/ui-cargo/duplicate_mod/fail}/Cargo.toml (53%) create mode 100644 src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/src/a.rs create mode 100644 src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/src/b.rs create mode 100644 src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/src/c.rs create mode 100644 src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/src/from_other_module.rs create mode 100644 src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/src/main.rs create mode 100644 src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/src/main.stderr create mode 100644 src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/src/other_module/mod.rs create mode 100644 src/tools/clippy/tests/ui-toml/blacklisted_names_append/blacklisted_names.rs create mode 100644 src/tools/clippy/tests/ui-toml/blacklisted_names_append/blacklisted_names.stderr create mode 100644 src/tools/clippy/tests/ui-toml/blacklisted_names_append/clippy.toml create mode 100644 src/tools/clippy/tests/ui-toml/blacklisted_names_replace/blacklisted_names.rs create mode 100644 src/tools/clippy/tests/ui-toml/blacklisted_names_replace/blacklisted_names.stderr create mode 100644 src/tools/clippy/tests/ui-toml/blacklisted_names_replace/clippy.toml create mode 100644 src/tools/clippy/tests/ui-toml/dbg_macro/clippy.toml create mode 100644 src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs create mode 100644 src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr create mode 100644 src/tools/clippy/tests/ui-toml/doc_valid_idents_append/clippy.toml create mode 100644 src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.rs create mode 100644 src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr create mode 100644 src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/clippy.toml create mode 100644 src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs create mode 100644 src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr create mode 100644 src/tools/clippy/tests/ui-toml/expect_used/clippy.toml create mode 100644 src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs create mode 100644 src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr create mode 100644 src/tools/clippy/tests/ui-toml/unwrap_used/clippy.toml create mode 100644 src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs create mode 100644 src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr create mode 100644 src/tools/clippy/tests/ui/almost_complete_letter_range.fixed create mode 100644 src/tools/clippy/tests/ui/almost_complete_letter_range.rs create mode 100644 src/tools/clippy/tests/ui/almost_complete_letter_range.stderr create mode 100644 src/tools/clippy/tests/ui/as_underscore.fixed create mode 100644 src/tools/clippy/tests/ui/as_underscore.rs create mode 100644 src/tools/clippy/tests/ui/as_underscore.stderr create mode 100644 src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed create mode 100644 src/tools/clippy/tests/ui/borrow_deref_ref.fixed create mode 100644 src/tools/clippy/tests/ui/borrow_deref_ref.rs create mode 100644 src/tools/clippy/tests/ui/borrow_deref_ref.stderr create mode 100644 src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.rs create mode 100644 src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr create mode 100644 src/tools/clippy/tests/ui/crashes/ice-8821.rs create mode 100644 src/tools/clippy/tests/ui/crashes/ice-8821.stderr create mode 100644 src/tools/clippy/tests/ui/crashes/ice-8850.rs create mode 100644 src/tools/clippy/tests/ui/crashes/ice-8850.stderr create mode 100644 src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed create mode 100644 src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs create mode 100644 src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr create mode 100644 src/tools/clippy/tests/ui/doc_link_with_quotes.rs create mode 100644 src/tools/clippy/tests/ui/doc_link_with_quotes.stderr create mode 100644 src/tools/clippy/tests/ui/get_first.fixed create mode 100644 src/tools/clippy/tests/ui/get_first.rs create mode 100644 src/tools/clippy/tests/ui/get_first.stderr create mode 100644 src/tools/clippy/tests/ui/identity_op.fixed create mode 100644 src/tools/clippy/tests/ui/implicit_clone.fixed create mode 100644 src/tools/clippy/tests/ui/issue_2356.fixed create mode 100644 src/tools/clippy/tests/ui/match_ref_pats.fixed create mode 100644 src/tools/clippy/tests/ui/match_str_case_mismatch.fixed create mode 100644 src/tools/clippy/tests/ui/mismatching_type_param_order.rs create mode 100644 src/tools/clippy/tests/ui/mismatching_type_param_order.stderr rename src/tools/clippy/tests/ui/{eval_order_dependence.rs => mixed_read_write_in_expression.rs} (97%) rename src/tools/clippy/tests/ui/{eval_order_dependence.stderr => mixed_read_write_in_expression.stderr} (63%) create mode 100644 src/tools/clippy/tests/ui/needless_late_init.fixed delete mode 100644 src/tools/clippy/tests/ui/needless_late_init_fixable.fixed delete mode 100644 src/tools/clippy/tests/ui/needless_late_init_fixable.rs delete mode 100644 src/tools/clippy/tests/ui/needless_late_init_fixable.stderr create mode 100644 src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed create mode 100644 src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs create mode 100644 src/tools/clippy/tests/ui/needless_parens_on_range_literals.stderr create mode 100644 src/tools/clippy/tests/ui/no_effect_replace.rs create mode 100644 src/tools/clippy/tests/ui/no_effect_replace.stderr create mode 100644 src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed create mode 100644 src/tools/clippy/tests/ui/rc_buffer.fixed create mode 100644 src/tools/clippy/tests/ui/rc_buffer_arc.fixed create mode 100644 src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.rs create mode 100644 src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr create mode 100644 src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.rs create mode 100644 src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr create mode 100644 src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.rs create mode 100644 src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr create mode 100644 src/tools/clippy/tests/ui/read_zero_byte_vec.rs create mode 100644 src/tools/clippy/tests/ui/read_zero_byte_vec.stderr create mode 100644 src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed create mode 100644 src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed create mode 100644 src/tools/clippy/tests/ui/swap_ptr_to_ref.rs create mode 100644 src/tools/clippy/tests/ui/swap_ptr_to_ref.stderr create mode 100644 src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.rs create mode 100644 src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.stderr create mode 100644 src/tools/clippy/tests/ui/unicode.fixed create mode 100644 src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed create mode 100644 src/tools/clippy/tests/ui/unnecessary_cast.fixed delete mode 100644 src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed delete mode 100644 src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs delete mode 100644 src/tools/clippy/tests/ui/unnecessary_cast_fixable.stderr create mode 100644 src/tools/clippy/tests/ui/unused_rounding.fixed create mode 100644 src/tools/clippy/tests/ui/unused_rounding.rs create mode 100644 src/tools/clippy/tests/ui/unused_rounding.stderr create mode 100644 src/tools/compiletest/src/read2/tests.rs create mode 100755 src/tools/rustfmt/ci/build_and_test.bat create mode 100755 src/tools/rustfmt/ci/build_and_test.sh delete mode 100644 src/tools/rustfmt/src/config/license.rs delete mode 100644 src/tools/rustfmt/src/issues.rs delete mode 100644 src/tools/rustfmt/tests/config/issue-3802.toml delete mode 100644 src/tools/rustfmt/tests/license-template/lt.txt create mode 100644 src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/100.rs create mode 100644 src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/100_greater_max_width.rs create mode 100644 src/tools/rustfmt/tests/source/configs/doc_comment_code_block_width/50.rs create mode 100644 src/tools/rustfmt/tests/source/configs/group_imports/StdExternalCrate-non_consecutive.rs rename src/tools/rustfmt/tests/source/{ => imports}/imports-impl-only-use.rs (100%) rename src/tools/rustfmt/tests/source/{ => imports}/imports-reorder-lines-and-items.rs (100%) rename src/tools/rustfmt/tests/source/{ => imports}/imports-reorder-lines.rs (100%) rename src/tools/rustfmt/tests/source/{ => imports}/imports-reorder.rs (100%) rename src/tools/rustfmt/tests/source/{ => imports}/imports.rs (100%) rename src/tools/rustfmt/tests/source/{ => imports}/imports_block_indent.rs (100%) rename src/tools/rustfmt/tests/source/{ => imports}/imports_granularity_crate.rs (57%) create mode 100644 src/tools/rustfmt/tests/source/imports/imports_granularity_default-with-dups.rs create mode 100644 src/tools/rustfmt/tests/source/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs create mode 100644 src/tools/rustfmt/tests/source/imports/imports_granularity_item-with-dups.rs create mode 100644 src/tools/rustfmt/tests/source/imports/imports_granularity_item.rs create mode 100644 src/tools/rustfmt/tests/source/imports/imports_granularity_module.rs delete mode 100644 src/tools/rustfmt/tests/source/imports_granularity_item.rs delete mode 100644 src/tools/rustfmt/tests/source/imports_granularity_module.rs create mode 100644 src/tools/rustfmt/tests/source/imports_raw_identifiers/version_One.rs create mode 100644 src/tools/rustfmt/tests/source/imports_raw_identifiers/version_Two.rs create mode 100644 src/tools/rustfmt/tests/source/issue-5030.rs create mode 100644 src/tools/rustfmt/tests/source/issue-5260.rs delete mode 100644 src/tools/rustfmt/tests/source/license-templates/empty_license_path.rs delete mode 100644 src/tools/rustfmt/tests/source/license-templates/license.rs create mode 100644 src/tools/rustfmt/tests/source/struct_field_doc_comment.rs create mode 100644 src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/100.rs create mode 100644 src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/100_greater_max_width.rs create mode 100644 src/tools/rustfmt/tests/target/configs/doc_comment_code_block_width/50.rs create mode 100644 src/tools/rustfmt/tests/target/configs/group_imports/StdExternalCrate-non_consecutive.rs rename src/tools/rustfmt/tests/target/{ => imports}/import-fencepost-length.rs (100%) rename src/tools/rustfmt/tests/target/{ => imports}/imports-impl-only-use.rs (100%) rename src/tools/rustfmt/tests/target/{ => imports}/imports-reorder-lines-and-items.rs (100%) rename src/tools/rustfmt/tests/target/{ => imports}/imports-reorder-lines.rs (100%) rename src/tools/rustfmt/tests/target/{ => imports}/imports-reorder.rs (100%) rename src/tools/rustfmt/tests/target/{ => imports}/imports.rs (100%) rename src/tools/rustfmt/tests/target/{ => imports}/imports_2021_edition.rs (100%) rename src/tools/rustfmt/tests/target/{ => imports}/imports_block_indent.rs (100%) rename src/tools/rustfmt/tests/target/{ => imports}/imports_granularity_crate.rs (50%) create mode 100644 src/tools/rustfmt/tests/target/imports/imports_granularity_default-with-dups.rs create mode 100644 src/tools/rustfmt/tests/target/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs create mode 100644 src/tools/rustfmt/tests/target/imports/imports_granularity_item-with-dups.rs create mode 100644 src/tools/rustfmt/tests/target/imports/imports_granularity_item.rs create mode 100644 src/tools/rustfmt/tests/target/imports/imports_granularity_module.rs delete mode 100644 src/tools/rustfmt/tests/target/imports_granularity_item.rs delete mode 100644 src/tools/rustfmt/tests/target/imports_granularity_module.rs create mode 100644 src/tools/rustfmt/tests/target/imports_raw_identifiers/version_One.rs create mode 100644 src/tools/rustfmt/tests/target/imports_raw_identifiers/version_Two.rs create mode 100644 src/tools/rustfmt/tests/target/issue-5030.rs create mode 100644 src/tools/rustfmt/tests/target/issue-5260.rs create mode 100644 src/tools/rustfmt/tests/target/issue_3937.rs create mode 100644 src/tools/rustfmt/tests/target/issue_4573.rs create mode 100644 src/tools/rustfmt/tests/target/issue_5399.rs delete mode 100644 src/tools/rustfmt/tests/target/license-templates/empty_license_path.rs delete mode 100644 src/tools/rustfmt/tests/target/license-templates/license.rs create mode 100644 src/tools/rustfmt/tests/target/struct_field_doc_comment.rs create mode 100644 vendor/annotate-snippets-0.8.0/.cargo-checksum.json create mode 100644 vendor/annotate-snippets-0.8.0/CHANGELOG.md create mode 100644 vendor/annotate-snippets-0.8.0/Cargo.lock create mode 100644 vendor/annotate-snippets-0.8.0/Cargo.toml rename vendor/{structopt-derive => annotate-snippets-0.8.0}/LICENSE-APACHE (100%) create mode 100644 vendor/annotate-snippets-0.8.0/LICENSE-MIT create mode 100644 vendor/annotate-snippets-0.8.0/README.md create mode 100644 vendor/annotate-snippets-0.8.0/benches/simple.rs create mode 100644 vendor/annotate-snippets-0.8.0/examples/expected_type.rs create mode 100644 vendor/annotate-snippets-0.8.0/examples/footer.rs create mode 100644 vendor/annotate-snippets-0.8.0/examples/format.rs create mode 100644 vendor/annotate-snippets-0.8.0/examples/multislice.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/display_list/from_snippet.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/display_list/mod.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/display_list/structs.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/formatter/mod.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/formatter/style.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/lib.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/snippet.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/stylesheets/color.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/stylesheets/mod.rs create mode 100644 vendor/annotate-snippets-0.8.0/src/stylesheets/no_color.rs create mode 100644 vendor/annotate-snippets-0.8.0/tests/diff/mod.rs create mode 100644 vendor/annotate-snippets-0.8.0/tests/dl_from_snippet.rs create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.toml create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.txt create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.toml create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.txt create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.toml create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.txt create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.toml create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.txt create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.toml create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.txt create mode 100644 vendor/annotate-snippets-0.8.0/tests/fixtures_test.rs create mode 100644 vendor/annotate-snippets-0.8.0/tests/formatter.rs create mode 100644 vendor/annotate-snippets-0.8.0/tests/snippet/mod.rs create mode 100644 vendor/annotate-snippets/tests/fixtures/no-color/issue_9.toml create mode 100644 vendor/annotate-snippets/tests/fixtures/no-color/issue_9.txt create mode 100644 vendor/annotate-snippets/tests/fixtures/no-color/strip_line.toml create mode 100644 vendor/annotate-snippets/tests/fixtures/no-color/strip_line.txt create mode 100644 vendor/annotate-snippets/tests/fixtures/no-color/strip_line_char.toml create mode 100644 vendor/annotate-snippets/tests/fixtures/no-color/strip_line_char.txt create mode 100644 vendor/annotate-snippets/tests/fixtures/no-color/strip_line_non_ws.toml create mode 100644 vendor/annotate-snippets/tests/fixtures/no-color/strip_line_non_ws.txt create mode 100644 vendor/camino/src/proptest_impls.rs delete mode 100644 vendor/clap/benches/01_default.rs delete mode 100644 vendor/clap/benches/02_simple.rs delete mode 100644 vendor/clap/benches/03_complex.rs delete mode 100644 vendor/clap/benches/04_new_help.rs delete mode 100644 vendor/clap/benches/05_ripgrep.rs delete mode 100644 vendor/clap/benches/06_rustup.rs create mode 100644 vendor/clap/examples/derive_ref/augment_args.rs create mode 100644 vendor/clap/examples/derive_ref/augment_subcommands.rs create mode 100644 vendor/clap/examples/derive_ref/flatten_hand_args.rs create mode 100644 vendor/clap/examples/derive_ref/hand_subcommand.rs create mode 100644 vendor/clap/examples/derive_ref/interop_tests.md delete mode 100644 vendor/clap/examples/keyvalue-derive.md create mode 100644 vendor/clap/examples/repl.rs create mode 100644 vendor/clap/examples/tutorial_derive/03_04_subcommands_alt.rs create mode 100644 vendor/clap/examples/typed-derive.md rename vendor/clap/examples/{keyvalue-derive.rs => typed-derive.rs} (52%) create mode 100644 vendor/clap/src/bin/stdio-fixture.rs delete mode 100644 vendor/clap/src/build/mod.rs create mode 100644 vendor/clap/src/builder/action.rs rename vendor/clap/src/{build => builder}/app_settings.rs (71%) rename vendor/clap/src/{build => builder}/arg.rs (87%) rename vendor/clap/src/{build => builder}/arg_group.rs (96%) rename vendor/clap/src/{build => builder}/arg_predicate.rs (100%) rename vendor/clap/src/{build => builder}/arg_settings.rs (69%) rename vendor/clap/src/{build => builder}/command.rs (87%) rename vendor/clap/src/{build => builder}/debug_asserts.rs (74%) rename vendor/clap/src/{build => builder}/macros.rs (100%) create mode 100644 vendor/clap/src/builder/mod.rs rename vendor/clap/src/{build => builder}/possible_value.rs (77%) rename vendor/clap/src/{build => builder}/regex.rs (100%) rename vendor/clap/src/{build => builder}/tests.rs (98%) rename vendor/clap/src/{build => builder}/usage_parser.rs (99%) rename vendor/clap/src/{build => builder}/value_hint.rs (98%) create mode 100644 vendor/clap/src/builder/value_parser.rs delete mode 100644 vendor/clap/src/parse/arg_matcher.rs delete mode 100644 vendor/clap/src/parse/matches/matched_arg.rs delete mode 100644 vendor/clap/src/parse/matches/mod.rs delete mode 100644 vendor/clap/src/parse/mod.rs delete mode 100644 vendor/clap/src/parse/parser.rs create mode 100644 vendor/clap/src/parser/arg_matcher.rs create mode 100644 vendor/clap/src/parser/error.rs rename vendor/clap/src/{parse => parser}/features/mod.rs (100%) rename vendor/clap/src/{parse => parser}/features/suggestions.rs (97%) create mode 100644 vendor/clap/src/parser/matches/any_value.rs rename vendor/clap/src/{parse => parser}/matches/arg_matches.rs (56%) create mode 100644 vendor/clap/src/parser/matches/matched_arg.rs create mode 100644 vendor/clap/src/parser/matches/mod.rs rename vendor/clap/src/{parse => parser}/matches/value_source.rs (100%) create mode 100644 vendor/clap/src/parser/mod.rs create mode 100644 vendor/clap/src/parser/parser.rs rename vendor/clap/src/{parse => parser}/validator.rs (68%) create mode 100644 vendor/clap_derive/.cargo-checksum.json create mode 100644 vendor/clap_derive/Cargo.toml rename vendor/{structopt => clap_derive}/LICENSE-APACHE (100%) rename vendor/{rustfix-0.5.1 => clap_derive}/LICENSE-MIT (96%) create mode 100644 vendor/clap_derive/README.md create mode 100644 vendor/clap_derive/src/attrs.rs create mode 100644 vendor/clap_derive/src/derives/args.rs create mode 100644 vendor/clap_derive/src/derives/into_app.rs create mode 100644 vendor/clap_derive/src/derives/mod.rs create mode 100644 vendor/clap_derive/src/derives/parser.rs create mode 100644 vendor/clap_derive/src/derives/subcommand.rs create mode 100644 vendor/clap_derive/src/derives/value_enum.rs create mode 100644 vendor/clap_derive/src/dummies.rs create mode 100644 vendor/clap_derive/src/lib.rs rename vendor/{structopt-derive => clap_derive}/src/parse.rs (62%) rename vendor/{structopt-derive/src => clap_derive/src/utils}/doc_comments.rs (91%) create mode 100644 vendor/clap_derive/src/utils/mod.rs rename vendor/{structopt-derive/src => clap_derive/src/utils}/spanned.rs (86%) rename vendor/{structopt-derive/src => clap_derive/src/utils}/ty.rs (73%) create mode 100644 vendor/clap_lex/.cargo-checksum.json create mode 100644 vendor/clap_lex/Cargo.toml rename vendor/{rustfix-0.5.1 => clap_lex}/LICENSE-APACHE (99%) rename vendor/{structopt-derive => clap_lex}/LICENSE-MIT (92%) create mode 100644 vendor/clap_lex/README.md create mode 100644 vendor/clap_lex/src/lib.rs rename vendor/compiler_builtins/src/{riscv32.rs => riscv.rs} (57%) create mode 100644 vendor/core-foundation-sys/.cargo-checksum.json create mode 100644 vendor/core-foundation-sys/Cargo.toml rename vendor/{env_logger-0.8.4 => core-foundation-sys}/LICENSE-APACHE (100%) rename vendor/{term-0.6.1 => core-foundation-sys}/LICENSE-MIT (95%) rename vendor/{structopt/tests/ui/tuple_struct.rs => core-foundation-sys/build.rs} (54%) create mode 100644 vendor/core-foundation-sys/src/array.rs create mode 100644 vendor/core-foundation-sys/src/attributed_string.rs create mode 100644 vendor/core-foundation-sys/src/base.rs create mode 100644 vendor/core-foundation-sys/src/bundle.rs create mode 100644 vendor/core-foundation-sys/src/characterset.rs create mode 100644 vendor/core-foundation-sys/src/data.rs create mode 100644 vendor/core-foundation-sys/src/date.rs create mode 100644 vendor/core-foundation-sys/src/dictionary.rs create mode 100644 vendor/core-foundation-sys/src/error.rs create mode 100644 vendor/core-foundation-sys/src/filedescriptor.rs create mode 100644 vendor/core-foundation-sys/src/lib.rs create mode 100644 vendor/core-foundation-sys/src/messageport.rs create mode 100644 vendor/core-foundation-sys/src/number.rs create mode 100644 vendor/core-foundation-sys/src/propertylist.rs create mode 100644 vendor/core-foundation-sys/src/runloop.rs create mode 100644 vendor/core-foundation-sys/src/set.rs create mode 100644 vendor/core-foundation-sys/src/string.rs create mode 100644 vendor/core-foundation-sys/src/timezone.rs create mode 100644 vendor/core-foundation-sys/src/url.rs create mode 100644 vendor/core-foundation-sys/src/uuid.rs rename vendor/{env_logger-0.8.4 => env_logger}/.cargo-checksum.json (70%) rename vendor/{env_logger-0.8.4 => env_logger}/CHANGELOG.md (100%) rename vendor/{env_logger-0.8.4 => env_logger}/Cargo.toml (98%) rename vendor/{hashbrown-0.11.2 => env_logger}/LICENSE-APACHE (100%) rename vendor/{env_logger-0.8.4 => env_logger}/LICENSE-MIT (100%) rename vendor/{env_logger-0.8.4 => env_logger}/README.md (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/filter/mod.rs (99%) rename vendor/{env_logger-0.8.4 => env_logger}/src/filter/regex.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/filter/string.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/fmt/humantime/extern_impl.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/fmt/humantime/mod.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/fmt/humantime/shim_impl.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/fmt/mod.rs (83%) rename vendor/{env_logger-0.8.4 => env_logger}/src/fmt/writer/atty.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/fmt/writer/mod.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/fmt/writer/termcolor/extern_impl.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/fmt/writer/termcolor/mod.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/fmt/writer/termcolor/shim_impl.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/src/lib.rs (97%) rename vendor/{env_logger-0.8.4 => env_logger}/tests/init-twice-retains-filter.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/tests/log-in-log.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/tests/log_tls_dtors.rs (100%) rename vendor/{env_logger-0.8.4 => env_logger}/tests/regexp_filter.rs (100%) delete mode 100644 vendor/hashbrown-0.11.2/.cargo-checksum.json delete mode 100644 vendor/hashbrown-0.11.2/CHANGELOG.md delete mode 100644 vendor/hashbrown-0.11.2/Cargo.toml delete mode 100644 vendor/hashbrown-0.11.2/README.md delete mode 100644 vendor/hashbrown-0.11.2/benches/bench.rs delete mode 100644 vendor/hashbrown-0.11.2/clippy.toml delete mode 100644 vendor/hashbrown-0.11.2/src/external_trait_impls/mod.rs delete mode 100644 vendor/hashbrown-0.11.2/src/external_trait_impls/rayon/helpers.rs delete mode 100644 vendor/hashbrown-0.11.2/src/external_trait_impls/rayon/map.rs delete mode 100644 vendor/hashbrown-0.11.2/src/external_trait_impls/rayon/mod.rs delete mode 100644 vendor/hashbrown-0.11.2/src/external_trait_impls/rayon/raw.rs delete mode 100644 vendor/hashbrown-0.11.2/src/external_trait_impls/rayon/set.rs delete mode 100644 vendor/hashbrown-0.11.2/src/external_trait_impls/serde.rs delete mode 100644 vendor/hashbrown-0.11.2/src/lib.rs delete mode 100644 vendor/hashbrown-0.11.2/src/macros.rs delete mode 100644 vendor/hashbrown-0.11.2/src/map.rs delete mode 100644 vendor/hashbrown-0.11.2/src/raw/alloc.rs delete mode 100644 vendor/hashbrown-0.11.2/src/raw/bitmask.rs delete mode 100644 vendor/hashbrown-0.11.2/src/raw/generic.rs delete mode 100644 vendor/hashbrown-0.11.2/src/raw/mod.rs delete mode 100644 vendor/hashbrown-0.11.2/src/raw/sse2.rs delete mode 100644 vendor/hashbrown-0.11.2/src/rustc_entry.rs delete mode 100644 vendor/hashbrown-0.11.2/src/scopeguard.rs delete mode 100644 vendor/hashbrown-0.11.2/src/set.rs delete mode 100644 vendor/hashbrown-0.11.2/tests/hasher.rs delete mode 100644 vendor/hashbrown-0.11.2/tests/rayon.rs delete mode 100644 vendor/hashbrown-0.11.2/tests/serde.rs delete mode 100644 vendor/hashbrown-0.11.2/tests/set.rs create mode 100644 vendor/heck-0.3.3/.cargo-checksum.json rename vendor/{macro-utils => heck-0.3.3}/Cargo.toml (52%) rename vendor/{term-0.6.1 => heck-0.3.3}/LICENSE-APACHE (100%) create mode 100644 vendor/heck-0.3.3/LICENSE-MIT create mode 100644 vendor/heck-0.3.3/README.md rename vendor/{heck => heck-0.3.3}/src/camel.rs (100%) create mode 100644 vendor/heck-0.3.3/src/kebab.rs create mode 100644 vendor/heck-0.3.3/src/lib.rs rename vendor/{heck => heck-0.3.3}/src/mixed.rs (100%) create mode 100644 vendor/heck-0.3.3/src/shouty_kebab.rs create mode 100644 vendor/heck-0.3.3/src/shouty_snake.rs create mode 100644 vendor/heck-0.3.3/src/snake.rs create mode 100644 vendor/heck-0.3.3/src/title.rs create mode 100644 vendor/heck/CHANGELOG.md create mode 100644 vendor/heck/src/lower_camel.rs create mode 100644 vendor/heck/src/upper_camel.rs create mode 100644 vendor/indexmap/README.md delete mode 100644 vendor/indexmap/README.rst create mode 100644 vendor/indexmap/RELEASES.md delete mode 100644 vendor/indexmap/RELEASES.rst delete mode 100644 vendor/macro-utils/.cargo-checksum.json delete mode 100644 vendor/macro-utils/README.md delete mode 100644 vendor/macro-utils/appveyor.yml delete mode 100644 vendor/macro-utils/src/if_match.rs delete mode 100644 vendor/macro-utils/src/lib.rs delete mode 100644 vendor/macro-utils/src/tern_c.rs delete mode 100644 vendor/macro-utils/src/tern_haskell.rs delete mode 100644 vendor/macro-utils/src/tern_python.rs create mode 100644 vendor/memchr/src/memmem/prefilter/wasm.rs create mode 100644 vendor/memchr/src/memmem/wasm.rs create mode 100644 vendor/ntapi/.cargo-checksum.json create mode 100644 vendor/ntapi/Cargo.toml create mode 100644 vendor/ntapi/LICENSE-APACHE rename vendor/{structopt => ntapi}/LICENSE-MIT (82%) create mode 100644 vendor/ntapi/README.md create mode 100644 vendor/ntapi/build.rs create mode 100644 vendor/ntapi/src/lib.rs create mode 100644 vendor/ntapi/src/macros.rs create mode 100644 vendor/ntapi/src/ntapi_base.rs create mode 100644 vendor/ntapi/src/ntdbg.rs create mode 100644 vendor/ntapi/src/ntexapi.rs create mode 100644 vendor/ntapi/src/ntgdi.rs create mode 100644 vendor/ntapi/src/ntioapi.rs create mode 100644 vendor/ntapi/src/ntkeapi.rs create mode 100644 vendor/ntapi/src/ntldr.rs create mode 100644 vendor/ntapi/src/ntlpcapi.rs create mode 100644 vendor/ntapi/src/ntmisc.rs create mode 100644 vendor/ntapi/src/ntmmapi.rs create mode 100644 vendor/ntapi/src/ntnls.rs create mode 100644 vendor/ntapi/src/ntobapi.rs create mode 100644 vendor/ntapi/src/ntpebteb.rs create mode 100644 vendor/ntapi/src/ntpfapi.rs create mode 100644 vendor/ntapi/src/ntpnpapi.rs create mode 100644 vendor/ntapi/src/ntpoapi.rs create mode 100644 vendor/ntapi/src/ntpsapi.rs create mode 100644 vendor/ntapi/src/ntregapi.rs create mode 100644 vendor/ntapi/src/ntrtl.rs create mode 100644 vendor/ntapi/src/ntsam.rs create mode 100644 vendor/ntapi/src/ntseapi.rs create mode 100644 vendor/ntapi/src/ntsmss.rs create mode 100644 vendor/ntapi/src/nttmapi.rs create mode 100644 vendor/ntapi/src/nttp.rs create mode 100644 vendor/ntapi/src/ntwow64.rs create mode 100644 vendor/ntapi/src/ntxcapi.rs create mode 100644 vendor/ntapi/src/ntzwapi.rs create mode 100644 vendor/ntapi/src/string.rs create mode 100644 vendor/ntapi/src/subprocesstag.rs create mode 100644 vendor/ntapi/src/winapi_local.rs create mode 100644 vendor/ntapi/src/winapi_local/um.rs create mode 100644 vendor/ntapi/src/winapi_local/um/winioctl.rs create mode 100644 vendor/ntapi/src/winapi_local/um/winnt.rs create mode 100644 vendor/ntapi/src/winsta.rs rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/.cargo-checksum.json (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/CHANGELOG.md (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/Cargo.lock (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/Cargo.toml (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/LICENSE-APACHE (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/LICENSE-MIT (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/README.md (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/examples/pretty_assertion.png (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/examples/pretty_assertion.rs (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/examples/pretty_assertion_v0_6_1.png (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/examples/standard_assertion.png (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/examples/standard_assertion.rs (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/scripts/check (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/scripts/install (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/scripts/publish (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/src/lib.rs (100%) rename vendor/{pretty_assertions => pretty_assertions-0.7.2}/src/printer.rs (100%) create mode 100644 vendor/rustc-rayon-core/src/sleep/counters.rs delete mode 100644 vendor/rustc-rayon-core/src/util.rs create mode 100644 vendor/rustc-rayon/build.rs create mode 100644 vendor/rustc-rayon/src/array.rs create mode 100644 vendor/rustc-rayon/src/iter/flat_map_iter.rs create mode 100644 vendor/rustc-rayon/src/iter/flatten_iter.rs create mode 100644 vendor/rustc-rayon/src/iter/positions.rs create mode 100644 vendor/rustc-rayon/src/iter/step_by.rs create mode 100644 vendor/rustc-rayon/src/slice/chunks.rs create mode 100644 vendor/rustc-rayon/src/slice/rchunks.rs create mode 100644 vendor/rustc-rayon/src/string.rs create mode 100644 vendor/rustc-rayon/tests/chars.rs create mode 100644 vendor/rustc-rayon/tests/collect.rs create mode 100644 vendor/rustc-rayon/tests/cross-pool.rs delete mode 100644 vendor/rustfix-0.5.1/.cargo-checksum.json delete mode 100644 vendor/rustfix-0.5.1/Cargo.toml delete mode 100644 vendor/rustfix-0.5.1/Changelog.md delete mode 100644 vendor/rustfix-0.5.1/Readme.md delete mode 100644 vendor/rustfix-0.5.1/proptest-regressions/replace.txt delete mode 100644 vendor/rustfix-0.5.1/src/diagnostics.rs delete mode 100644 vendor/rustfix-0.5.1/src/lib.rs delete mode 100644 vendor/rustfix-0.5.1/src/replace.rs create mode 100644 vendor/semver/tests/test_autotrait.rs delete mode 100644 vendor/structopt-derive/.cargo-checksum.json delete mode 100644 vendor/structopt-derive/Cargo.toml delete mode 100644 vendor/structopt-derive/src/attrs.rs delete mode 100644 vendor/structopt-derive/src/lib.rs delete mode 100644 vendor/structopt/.cargo-checksum.json delete mode 100644 vendor/structopt/CHANGELOG.md delete mode 100644 vendor/structopt/Cargo.lock delete mode 100644 vendor/structopt/Cargo.toml delete mode 100644 vendor/structopt/README.md delete mode 100644 vendor/structopt/examples/README.md delete mode 100644 vendor/structopt/examples/after_help.rs delete mode 100644 vendor/structopt/examples/at_least_two.rs delete mode 100644 vendor/structopt/examples/basic.rs delete mode 100644 vendor/structopt/examples/deny_missing_docs.rs delete mode 100644 vendor/structopt/examples/doc_comments.rs delete mode 100644 vendor/structopt/examples/enum_in_args.rs delete mode 100644 vendor/structopt/examples/enum_in_args_with_strum.rs delete mode 100644 vendor/structopt/examples/enum_tuple.rs delete mode 100644 vendor/structopt/examples/env.rs delete mode 100644 vendor/structopt/examples/example.rs delete mode 100644 vendor/structopt/examples/flatten.rs delete mode 100644 vendor/structopt/examples/gen_completions.rs delete mode 100644 vendor/structopt/examples/git.rs delete mode 100644 vendor/structopt/examples/group.rs delete mode 100644 vendor/structopt/examples/keyvalue.rs delete mode 100644 vendor/structopt/examples/negative_flag.rs delete mode 100644 vendor/structopt/examples/no_version.rs delete mode 100644 vendor/structopt/examples/rename_all.rs delete mode 100644 vendor/structopt/examples/required_if.rs delete mode 100644 vendor/structopt/examples/skip.rs delete mode 100644 vendor/structopt/examples/subcommand_aliases.rs delete mode 100644 vendor/structopt/examples/true_or_false.rs delete mode 100644 vendor/structopt/src/lib.rs delete mode 100644 vendor/structopt/tests/argument_naming.rs delete mode 100644 vendor/structopt/tests/arguments.rs delete mode 100644 vendor/structopt/tests/author_version_about.rs delete mode 100644 vendor/structopt/tests/custom-string-parsers.rs delete mode 100644 vendor/structopt/tests/default_value.rs delete mode 100644 vendor/structopt/tests/deny-warnings.rs delete mode 100644 vendor/structopt/tests/doc-comments-help.rs delete mode 100644 vendor/structopt/tests/explicit_name_no_renaming.rs delete mode 100644 vendor/structopt/tests/flags.rs delete mode 100644 vendor/structopt/tests/flatten.rs delete mode 100644 vendor/structopt/tests/generics.rs delete mode 100644 vendor/structopt/tests/issues.rs delete mode 100644 vendor/structopt/tests/macro-errors.rs delete mode 100644 vendor/structopt/tests/nested-subcommands.rs delete mode 100644 vendor/structopt/tests/non_literal_attributes.rs delete mode 100644 vendor/structopt/tests/options.rs delete mode 100644 vendor/structopt/tests/privacy.rs delete mode 100644 vendor/structopt/tests/raw_bool_literal.rs delete mode 100644 vendor/structopt/tests/raw_idents.rs delete mode 100644 vendor/structopt/tests/regressions.rs delete mode 100644 vendor/structopt/tests/rename_all_env.rs delete mode 100644 vendor/structopt/tests/skip.rs delete mode 100644 vendor/structopt/tests/special_types.rs delete mode 100644 vendor/structopt/tests/subcommands.rs delete mode 100644 vendor/structopt/tests/ui/bool_default_value.rs delete mode 100644 vendor/structopt/tests/ui/bool_default_value.stderr delete mode 100644 vendor/structopt/tests/ui/bool_required.rs delete mode 100644 vendor/structopt/tests/ui/bool_required.stderr delete mode 100644 vendor/structopt/tests/ui/enum_flatten.rs delete mode 100644 vendor/structopt/tests/ui/enum_flatten.stderr delete mode 100644 vendor/structopt/tests/ui/external_subcommand_wrong_type.rs delete mode 100644 vendor/structopt/tests/ui/external_subcommand_wrong_type.stderr delete mode 100644 vendor/structopt/tests/ui/flatten_and_methods.rs delete mode 100644 vendor/structopt/tests/ui/flatten_and_methods.stderr delete mode 100644 vendor/structopt/tests/ui/flatten_and_parse.rs delete mode 100644 vendor/structopt/tests/ui/flatten_and_parse.stderr delete mode 100644 vendor/structopt/tests/ui/multiple_external_subcommand.rs delete mode 100644 vendor/structopt/tests/ui/multiple_external_subcommand.stderr delete mode 100644 vendor/structopt/tests/ui/non_existent_attr.rs delete mode 100644 vendor/structopt/tests/ui/non_existent_attr.stderr delete mode 100644 vendor/structopt/tests/ui/opt_opt_nonpositional.rs delete mode 100644 vendor/structopt/tests/ui/opt_opt_nonpositional.stderr delete mode 100644 vendor/structopt/tests/ui/opt_vec_nonpositional.rs delete mode 100644 vendor/structopt/tests/ui/opt_vec_nonpositional.stderr delete mode 100644 vendor/structopt/tests/ui/option_default_value.rs delete mode 100644 vendor/structopt/tests/ui/option_default_value.stderr delete mode 100644 vendor/structopt/tests/ui/option_required.rs delete mode 100644 vendor/structopt/tests/ui/option_required.stderr delete mode 100644 vendor/structopt/tests/ui/parse_empty_try_from_os.rs delete mode 100644 vendor/structopt/tests/ui/parse_empty_try_from_os.stderr delete mode 100644 vendor/structopt/tests/ui/parse_function_is_not_path.rs delete mode 100644 vendor/structopt/tests/ui/parse_function_is_not_path.stderr delete mode 100644 vendor/structopt/tests/ui/parse_literal_spec.rs delete mode 100644 vendor/structopt/tests/ui/parse_literal_spec.stderr delete mode 100644 vendor/structopt/tests/ui/parse_not_zero_args.rs delete mode 100644 vendor/structopt/tests/ui/parse_not_zero_args.stderr delete mode 100644 vendor/structopt/tests/ui/positional_bool.rs delete mode 100644 vendor/structopt/tests/ui/positional_bool.stderr delete mode 100644 vendor/structopt/tests/ui/raw.rs delete mode 100644 vendor/structopt/tests/ui/raw.stderr delete mode 100644 vendor/structopt/tests/ui/rename_all_wrong_casing.rs delete mode 100644 vendor/structopt/tests/ui/rename_all_wrong_casing.stderr delete mode 100644 vendor/structopt/tests/ui/skip_flatten.rs delete mode 100644 vendor/structopt/tests/ui/skip_flatten.stderr delete mode 100644 vendor/structopt/tests/ui/skip_subcommand.rs delete mode 100644 vendor/structopt/tests/ui/skip_subcommand.stderr delete mode 100644 vendor/structopt/tests/ui/skip_with_other_options.rs delete mode 100644 vendor/structopt/tests/ui/skip_with_other_options.stderr delete mode 100644 vendor/structopt/tests/ui/skip_without_default.rs delete mode 100644 vendor/structopt/tests/ui/skip_without_default.stderr delete mode 100644 vendor/structopt/tests/ui/struct_parse.rs delete mode 100644 vendor/structopt/tests/ui/struct_parse.stderr delete mode 100644 vendor/structopt/tests/ui/struct_subcommand.rs delete mode 100644 vendor/structopt/tests/ui/struct_subcommand.stderr delete mode 100644 vendor/structopt/tests/ui/structopt_empty_attr.rs delete mode 100644 vendor/structopt/tests/ui/structopt_empty_attr.stderr delete mode 100644 vendor/structopt/tests/ui/structopt_name_value_attr.rs delete mode 100644 vendor/structopt/tests/ui/structopt_name_value_attr.stderr delete mode 100644 vendor/structopt/tests/ui/subcommand_and_flatten.rs delete mode 100644 vendor/structopt/tests/ui/subcommand_and_flatten.stderr delete mode 100644 vendor/structopt/tests/ui/subcommand_and_methods.rs delete mode 100644 vendor/structopt/tests/ui/subcommand_and_methods.stderr delete mode 100644 vendor/structopt/tests/ui/subcommand_and_parse.rs delete mode 100644 vendor/structopt/tests/ui/subcommand_and_parse.stderr delete mode 100644 vendor/structopt/tests/ui/subcommand_opt_opt.rs delete mode 100644 vendor/structopt/tests/ui/subcommand_opt_opt.stderr delete mode 100644 vendor/structopt/tests/ui/subcommand_opt_vec.rs delete mode 100644 vendor/structopt/tests/ui/subcommand_opt_vec.stderr delete mode 100644 vendor/structopt/tests/ui/tuple_struct.stderr delete mode 100644 vendor/structopt/tests/utils.rs delete mode 100644 vendor/structopt/tests/we_need_syn_full.rs create mode 100644 vendor/sysinfo/.cargo-checksum.json create mode 100644 vendor/sysinfo/ADDING_NEW_PLATFORMS.md create mode 100644 vendor/sysinfo/CHANGELOG.md create mode 100644 vendor/sysinfo/Cargo.lock create mode 100644 vendor/sysinfo/Cargo.toml rename vendor/{macro-utils => sysinfo}/LICENSE (94%) create mode 100644 vendor/sysinfo/Makefile create mode 100644 vendor/sysinfo/README.md create mode 100644 vendor/sysinfo/benches/basic.rs create mode 100644 vendor/sysinfo/build.rs create mode 100644 vendor/sysinfo/examples/simple.c create mode 100644 vendor/sysinfo/examples/simple.rs create mode 100644 vendor/sysinfo/md_doc/component.md create mode 100644 vendor/sysinfo/md_doc/cpu.md create mode 100644 vendor/sysinfo/md_doc/disk.md create mode 100644 vendor/sysinfo/md_doc/network_data.md create mode 100644 vendor/sysinfo/md_doc/networks.md create mode 100644 vendor/sysinfo/md_doc/pid.md create mode 100644 vendor/sysinfo/md_doc/process.md create mode 100644 vendor/sysinfo/md_doc/system.md create mode 100644 vendor/sysinfo/src/apple/app_store/component.rs create mode 100644 vendor/sysinfo/src/apple/app_store/mod.rs create mode 100644 vendor/sysinfo/src/apple/app_store/process.rs create mode 100644 vendor/sysinfo/src/apple/component.rs create mode 100644 vendor/sysinfo/src/apple/cpu.rs create mode 100644 vendor/sysinfo/src/apple/disk.rs create mode 100644 vendor/sysinfo/src/apple/ffi.rs create mode 100644 vendor/sysinfo/src/apple/ios.rs create mode 100644 vendor/sysinfo/src/apple/macos/component.rs create mode 100644 vendor/sysinfo/src/apple/macos/disk.rs create mode 100644 vendor/sysinfo/src/apple/macos/ffi.rs create mode 100644 vendor/sysinfo/src/apple/macos/mod.rs create mode 100644 vendor/sysinfo/src/apple/macos/process.rs create mode 100644 vendor/sysinfo/src/apple/macos/system.rs create mode 100644 vendor/sysinfo/src/apple/mod.rs create mode 100644 vendor/sysinfo/src/apple/network.rs create mode 100644 vendor/sysinfo/src/apple/process.rs create mode 100644 vendor/sysinfo/src/apple/system.rs create mode 100644 vendor/sysinfo/src/apple/users.rs create mode 100644 vendor/sysinfo/src/apple/utils.rs create mode 100644 vendor/sysinfo/src/c_interface.rs create mode 100644 vendor/sysinfo/src/common.rs create mode 100644 vendor/sysinfo/src/debug.rs create mode 100644 vendor/sysinfo/src/freebsd/component.rs create mode 100644 vendor/sysinfo/src/freebsd/cpu.rs create mode 100644 vendor/sysinfo/src/freebsd/disk.rs create mode 100644 vendor/sysinfo/src/freebsd/mod.rs create mode 100644 vendor/sysinfo/src/freebsd/network.rs create mode 100644 vendor/sysinfo/src/freebsd/process.rs create mode 100644 vendor/sysinfo/src/freebsd/system.rs create mode 100644 vendor/sysinfo/src/freebsd/utils.rs create mode 100644 vendor/sysinfo/src/lib.rs create mode 100644 vendor/sysinfo/src/linux/component.rs create mode 100644 vendor/sysinfo/src/linux/cpu.rs create mode 100644 vendor/sysinfo/src/linux/disk.rs create mode 100644 vendor/sysinfo/src/linux/mod.rs create mode 100644 vendor/sysinfo/src/linux/network.rs create mode 100644 vendor/sysinfo/src/linux/process.rs create mode 100644 vendor/sysinfo/src/linux/system.rs create mode 100644 vendor/sysinfo/src/linux/utils.rs create mode 100644 vendor/sysinfo/src/macros.rs create mode 100644 vendor/sysinfo/src/sysinfo.h create mode 100644 vendor/sysinfo/src/system.rs create mode 100644 vendor/sysinfo/src/traits.rs create mode 100644 vendor/sysinfo/src/unknown/component.rs create mode 100644 vendor/sysinfo/src/unknown/cpu.rs create mode 100644 vendor/sysinfo/src/unknown/disk.rs create mode 100644 vendor/sysinfo/src/unknown/mod.rs create mode 100644 vendor/sysinfo/src/unknown/network.rs create mode 100644 vendor/sysinfo/src/unknown/process.rs create mode 100644 vendor/sysinfo/src/unknown/system.rs create mode 100644 vendor/sysinfo/src/users.rs create mode 100644 vendor/sysinfo/src/utils.rs create mode 100644 vendor/sysinfo/src/windows/component.rs create mode 100644 vendor/sysinfo/src/windows/cpu.rs create mode 100644 vendor/sysinfo/src/windows/disk.rs create mode 100644 vendor/sysinfo/src/windows/macros.rs create mode 100644 vendor/sysinfo/src/windows/mod.rs create mode 100644 vendor/sysinfo/src/windows/network.rs create mode 100644 vendor/sysinfo/src/windows/process.rs create mode 100644 vendor/sysinfo/src/windows/system.rs create mode 100644 vendor/sysinfo/src/windows/tools.rs create mode 100644 vendor/sysinfo/src/windows/users.rs create mode 100644 vendor/sysinfo/src/windows/utils.rs create mode 100644 vendor/sysinfo/tests/code_checkers/docs.rs create mode 100644 vendor/sysinfo/tests/code_checkers/headers.rs create mode 100644 vendor/sysinfo/tests/code_checkers/mod.rs create mode 100644 vendor/sysinfo/tests/code_checkers/signals.rs create mode 100644 vendor/sysinfo/tests/code_checkers/utils.rs create mode 100644 vendor/sysinfo/tests/cpu.rs create mode 100644 vendor/sysinfo/tests/disk_list.rs create mode 100644 vendor/sysinfo/tests/extras.rs create mode 100644 vendor/sysinfo/tests/network.rs create mode 100644 vendor/sysinfo/tests/process.rs create mode 100644 vendor/sysinfo/tests/send_sync.rs create mode 100644 vendor/sysinfo/tests/uptime.rs create mode 100644 vendor/tendril/Cargo.lock delete mode 100644 vendor/term-0.6.1/.cargo-checksum.json delete mode 100644 vendor/term-0.6.1/Cargo.toml delete mode 100644 vendor/term-0.6.1/README.md delete mode 100644 vendor/term-0.6.1/rustfmt.toml delete mode 100644 vendor/term-0.6.1/src/lib.rs delete mode 100644 vendor/term-0.6.1/src/terminfo/mod.rs delete mode 100644 vendor/term-0.6.1/src/terminfo/parm.rs delete mode 100644 vendor/term-0.6.1/src/terminfo/parser/compiled.rs delete mode 100644 vendor/term-0.6.1/src/terminfo/parser/names.rs delete mode 100644 vendor/term-0.6.1/src/terminfo/searcher.rs delete mode 100644 vendor/term-0.6.1/src/win.rs delete mode 100644 vendor/term-0.6.1/tests/data/dumb delete mode 100644 vendor/term-0.6.1/tests/data/linux delete mode 100644 vendor/term-0.6.1/tests/data/linux-16color delete mode 100644 vendor/term-0.6.1/tests/data/linux-basic delete mode 100644 vendor/term-0.6.1/tests/data/linux-c delete mode 100644 vendor/term-0.6.1/tests/data/linux-c-nc delete mode 100644 vendor/term-0.6.1/tests/data/linux-koi8 delete mode 100644 vendor/term-0.6.1/tests/data/linux-koi8r delete mode 100644 vendor/term-0.6.1/tests/data/linux-lat delete mode 100644 vendor/term-0.6.1/tests/data/linux-m delete mode 100644 vendor/term-0.6.1/tests/data/linux-nic delete mode 100644 vendor/term-0.6.1/tests/data/linux-vt delete mode 100644 vendor/term-0.6.1/tests/data/linux2.2 delete mode 100644 vendor/term-0.6.1/tests/data/linux2.6 delete mode 100644 vendor/term-0.6.1/tests/data/linux2.6.26 delete mode 100644 vendor/term-0.6.1/tests/data/linux3.0 delete mode 100644 vendor/term-0.6.1/tests/data/rxvt delete mode 100644 vendor/term-0.6.1/tests/data/rxvt-16color delete mode 100644 vendor/term-0.6.1/tests/data/rxvt-256color delete mode 100644 vendor/term-0.6.1/tests/data/rxvt-88color delete mode 100644 vendor/term-0.6.1/tests/data/rxvt-basic delete mode 100644 vendor/term-0.6.1/tests/data/rxvt-color delete mode 100644 vendor/term-0.6.1/tests/data/rxvt-cygwin delete mode 100644 vendor/term-0.6.1/tests/data/rxvt-cygwin-native delete mode 100644 vendor/term-0.6.1/tests/data/rxvt-xpm delete mode 100644 vendor/term-0.6.1/tests/data/screen delete mode 100644 vendor/term-0.6.1/tests/data/screen-256color delete mode 100644 vendor/term-0.6.1/tests/data/vt100 delete mode 100644 vendor/term-0.6.1/tests/data/xterm delete mode 100644 vendor/term-0.6.1/tests/data/xterm-256color delete mode 100644 vendor/term-0.6.1/tests/terminfo.rs create mode 100644 vendor/textwrap/Cargo.lock create mode 100644 vendor/textwrap/rustfmt.toml delete mode 100644 vendor/textwrap/tests/traits.rs create mode 100644 vendor/tracing-attributes/tests/follows_from.rs create mode 100644 vendor/tracing-attributes/tests/parents.rs delete mode 100644 vendor/tracing-attributes/tests/support.rs create mode 100644 vendor/tracing-log/benches/logging.rs create mode 100644 vendor/tracing-log/src/interest_cache.rs create mode 100644 vendor/tracing/tests/register_callsite_deadlock.rs create mode 100644 vendor/unicode-bidi/src/data_source.rs create mode 100644 vendor/unicode-ident/.cargo-checksum.json create mode 100644 vendor/unicode-ident/Cargo.toml create mode 100644 vendor/unicode-ident/LICENSE-APACHE rename vendor/{hashbrown-0.11.2 => unicode-ident}/LICENSE-MIT (96%) create mode 100644 vendor/unicode-ident/README.md create mode 100644 vendor/unicode-ident/benches/xid.rs create mode 100644 vendor/unicode-ident/src/lib.rs create mode 100644 vendor/unicode-ident/src/tables.rs create mode 100644 vendor/unicode-ident/tests/compare.rs create mode 100644 vendor/unicode-ident/tests/fst/mod.rs create mode 100644 vendor/unicode-ident/tests/fst/xid_continue.fst create mode 100644 vendor/unicode-ident/tests/fst/xid_start.fst create mode 100644 vendor/unicode-ident/tests/roaring/mod.rs create mode 100644 vendor/unicode-ident/tests/static_size.rs create mode 100644 vendor/unicode-ident/tests/trie/mod.rs create mode 100644 vendor/unicode-ident/tests/trie/trie.rs create mode 100644 vendor/windows-sys/readme.md delete mode 100644 vendor/windows-sys/src/Windows/Win32/System/SqlLite/mod.rs diff --git a/Cargo.lock b/Cargo.lock index a186e173cc..5db3c6d554 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,7 +72,14 @@ name = "annotate-snippets" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d78ea013094e5ea606b1c05fe35f1dd7ea1eb1ea259908d040b25bd5ec677ee5" + +[[package]] +name = "annotate-snippets" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b9d411ecbaf79885c6df4d75fff75858d5995ff25385657a28af47e82f9c36" dependencies = [ + "unicode-width", "yansi-term", ] @@ -216,16 +223,20 @@ dependencies = [ "cmake", "filetime", "getopts", + "hex 0.4.2", "ignore", "libc", "num_cpus", "once_cell", "opener", - "pretty_assertions", + "pretty_assertions 0.7.2", "serde", "serde_json", + "sha2", + "sysinfo", "tar", "toml", + "walkdir", "winapi", "xz2", ] @@ -313,7 +324,7 @@ dependencies = [ [[package]] name = "cargo" -version = "0.63.0" +version = "0.64.0" dependencies = [ "anyhow", "atty", @@ -322,7 +333,7 @@ dependencies = [ "cargo-test-macro", "cargo-test-support", "cargo-util", - "clap 3.1.1", + "clap 3.2.5", "crates-io", "crossbeam-utils", "curl", @@ -356,7 +367,7 @@ dependencies = [ "percent-encoding 2.1.0", "pretty_env_logger", "rustc-workspace-hack", - "rustfix 0.6.0", + "rustfix", "semver", "serde", "serde_ignored", @@ -460,7 +471,7 @@ dependencies = [ [[package]] name = "cargo-util" -version = "0.1.3" +version = "0.2.1" dependencies = [ "anyhow", "core-foundation", @@ -605,18 +616,19 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.1" +version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d76c22c9b9b215eeb8d016ad3a90417bd13cb24cf8142756e6472445876cab7" +checksum = "d53da17d37dba964b9b3ecb5c5a1f193a2762c700e6829201e645b9381c99dc7" dependencies = [ "atty", "bitflags", + "clap_derive", + "clap_lex", "indexmap", - "lazy_static", - "os_str_bytes", + "once_cell", "strsim 0.10.0", "termcolor", - "textwrap 0.14.2", + "textwrap 0.15.0", ] [[package]] @@ -625,12 +637,34 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df6f3613c0a3cddfd78b41b10203eb322cb29b600cbdf808a7d3db95691b8e25" dependencies = [ - "clap 3.1.1", + "clap 3.2.5", +] + +[[package]] +name = "clap_derive" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" +dependencies = [ + "os_str_bytes", ] [[package]] name = "clippy" -version = "0.1.62" +version = "0.1.63" dependencies = [ "clippy_lints", "clippy_utils", @@ -640,7 +674,7 @@ dependencies = [ "futures 0.3.19", "if_chain", "itertools", - "parking_lot", + "parking_lot 0.12.1", "quote", "regex", "rustc-semver", @@ -650,6 +684,7 @@ dependencies = [ "serde", "syn", "tempfile", + "termize", "tester", "tokio", ] @@ -659,7 +694,7 @@ name = "clippy_dev" version = "0.0.1" dependencies = [ "aho-corasick", - "clap 2.34.0", + "clap 3.2.5", "indoc", "itertools", "opener", @@ -670,9 +705,10 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.1.62" +version = "0.1.63" dependencies = [ "cargo_metadata", + "clippy_dev", "clippy_utils", "if_chain", "itertools", @@ -683,6 +719,7 @@ dependencies = [ "semver", "serde", "serde_json", + "tempfile", "toml", "unicode-normalization", "unicode-script", @@ -691,7 +728,7 @@ dependencies = [ [[package]] name = "clippy_utils" -version = "0.1.62" +version = "0.1.63" dependencies = [ "arrayvec", "if_chain", @@ -748,9 +785,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.71" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "163437f05ca8f29d7e9128ea728dedf5eb620e445fbca273641d3a3050305f23" +checksum = "71b72fde1d7792ca3bd654f7c3ea4508f9e4d0c826e24179eabb7fcc97a90bc3" dependencies = [ "cc", "rustc-std-workspace-core", @@ -768,7 +805,7 @@ dependencies = [ "libc", "miow", "regex", - "rustfix 0.6.0", + "rustfix", "serde", "serde_json", "tracing", @@ -780,9 +817,9 @@ dependencies = [ [[package]] name = "compiletest_rs" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29843cb8d351febf86557681d049d1e1652b81a086a190fa1173c07fd17fbf83" +checksum = "262134ef87408da1ddfe45e33daa0ca43b75286d6b1076446e602d264cf9847e" dependencies = [ "diff", "filetime", @@ -792,7 +829,7 @@ dependencies = [ "log", "miow", "regex", - "rustfix 0.5.1", + "rustfix", "serde", "serde_derive", "serde_json", @@ -885,6 +922,20 @@ dependencies = [ "cfg-if 0.1.10", ] +[[package]] +name = "crossbeam" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + [[package]] name = "crossbeam-channel" version = "0.5.4" @@ -919,6 +970,16 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.8" @@ -972,9 +1033,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.41" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc6d233563261f8db6ffb83bbaad5a73837a6e6b28868e926337ebbdece0be3" +checksum = "37d855aeef205b43f65a5001e0997d81f8efca7badad4fad7d897aa7f0d0651f" dependencies = [ "curl-sys", "libc", @@ -987,9 +1048,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.51+curl-7.80.0" +version = "0.4.55+curl-7.83.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d130987e6a6a34fe0889e1083022fa48cd90e6709a84be3fb8dd95801de5af20" +checksum = "23734ec77368ec583c2e61dd3f0b0e5c98b93abe6d2a004ca06b91dd7e3e2762" dependencies = [ "cc", "libc", @@ -1071,11 +1132,10 @@ dependencies = [ [[package]] name = "dirs" -version = "2.0.2" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "cfg-if 0.1.10", "dirs-sys", ] @@ -1191,19 +1251,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" -dependencies = [ - "atty", - "humantime 2.0.1", - "log", - "regex", - "termcolor", -] - [[package]] name = "env_logger" version = "0.9.0" @@ -1381,9 +1428,9 @@ checksum = "d79238883cf0307100b90aba4a755d8051a3182305dfe7f649a1e9dc0517006f" [[package]] name = "futf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" dependencies = [ "mac", "new_debug_unreachable", @@ -1653,19 +1700,11 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758" -dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", "rustc-std-workspace-core", @@ -1680,6 +1719,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1819,12 +1864,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", - "hashbrown 0.11.2", + "hashbrown", "rustc-rayon", "serde", ] @@ -1899,6 +1944,17 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +[[package]] +name = "jemalloc-sys" +version = "0.5.0+5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f655c3ecfa6b0d03634595b4b54551d4bd5ac208b9e0124873949a7ab168f70b" +dependencies = [ + "cc", + "fs_extra", + "libc", +] + [[package]] name = "jobserver" version = "0.1.24" @@ -2007,7 +2063,7 @@ dependencies = [ "jsonrpc-server-utils", "log", "parity-tokio-ipc", - "parking_lot", + "parking_lot 0.11.2", "tower-service", ] @@ -2021,7 +2077,7 @@ dependencies = [ "jsonrpc-core", "lazy_static", "log", - "parking_lot", + "parking_lot 0.11.2", "rand 0.7.3", "serde", ] @@ -2067,9 +2123,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" dependencies = [ "rustc-std-workspace-core", ] @@ -2169,10 +2225,11 @@ version = "0.1.0" [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] @@ -2226,12 +2283,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -[[package]] -name = "macro-utils" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e72f7deb758fea9ea7d290aebfa788763d0bffae12caa6406a25baaf8fa68a8" - [[package]] name = "maplit" version = "1.0.2" @@ -2285,7 +2336,7 @@ dependencies = [ "ammonia", "anyhow", "chrono", - "clap 3.1.1", + "clap 3.2.5", "clap_complete", "elasticlunr-rs", "env_logger 0.7.1", @@ -2313,7 +2364,7 @@ checksum = "78f7a41bc6f856a2cf0e95094ad5121f82500e2d9a0f3c0171d98f6566d8117d" dependencies = [ "log", "memmap2", - "parking_lot", + "parking_lot 0.11.2", "perf-event-open-sys", "rustc-hash", "smallvec", @@ -2327,7 +2378,7 @@ checksum = "bd460fad6e55ca82fa0cd9dab0d315294188fd9ec6efbf4105e5635d4872ef9c" dependencies = [ "log", "memmap2", - "parking_lot", + "parking_lot 0.11.2", "perf-event-open-sys", "rustc-hash", "smallvec", @@ -2363,12 +2414,9 @@ dependencies = [ [[package]] name = "minifier" -version = "0.0.43" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d81352bda6f4d04af1720afaa762054f66e16caffd93c1f86461a1c0ac4e695e" -dependencies = [ - "macro-utils", -] +checksum = "ac96d1e7a65f206443f95afff6de8f1690c77c97d6fc9c9bb2d2cd0662e9ff9f" [[package]] name = "minimal-lexical" @@ -2415,17 +2463,18 @@ name = "miri" version = "0.1.0" dependencies = [ "colored", - "compiletest_rs", "env_logger 0.9.0", "getrandom 0.2.0", + "lazy_static", "libc", "log", "measureme 9.1.2", "rand 0.8.5", + "regex", "rustc-workspace-hack", - "rustc_version", "shell-escape", "smallvec", + "ui_test", ] [[package]] @@ -2503,13 +2552,13 @@ dependencies = [ [[package]] name = "object" -version = "0.28.4" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ "crc32fast", "flate2", - "hashbrown 0.11.2", + "hashbrown", "indexmap", "memchr", ] @@ -2525,9 +2574,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" [[package]] name = "opaque-debug" @@ -2610,9 +2659,6 @@ name = "os_str_bytes" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] [[package]] name = "output_vt100" @@ -2678,7 +2724,17 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core", + "parking_lot_core 0.8.5", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.3", ] [[package]] @@ -2695,6 +2751,19 @@ dependencies = [ "winapi", ] +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + [[package]] name = "pathdiff" version = "0.2.1" @@ -2866,6 +2935,18 @@ dependencies = [ "output_vt100", ] +[[package]] +name = "pretty_assertions" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89f989ac94207d048d92db058e4f6ec7342b0971fc58d1271ca148b799b3563" +dependencies = [ + "ansi_term", + "ctor", + "diff", + "output_vt100", +] + [[package]] name = "pretty_env_logger" version = "0.4.0" @@ -2999,7 +3080,6 @@ name = "racer" version = "2.2.2" dependencies = [ "bitflags", - "clap 2.34.0", "derive_more", "env_logger 0.7.1", "humantime 2.0.1", @@ -3126,9 +3206,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ "autocfg", "crossbeam-deque", @@ -3138,14 +3218,13 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", "num_cpus", ] @@ -3224,7 +3303,7 @@ dependencies = [ "difference", "env_logger 0.9.0", "futures 0.3.19", - "heck", + "heck 0.4.0", "home", "itertools", "jsonrpc-core", @@ -3371,17 +3450,19 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" name = "rustc-main" version = "0.0.0" dependencies = [ + "jemalloc-sys", "rustc_codegen_ssa", "rustc_driver", - "tikv-jemalloc-sys", + "rustc_smir", ] [[package]] name = "rustc-rayon" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9974ab223660e61c1b4e7b43b827379df286736ca988308ce7e16f59f2d89246" +checksum = "1a79f0b0b2609e2eacf9758013f50e7176cb4b29fd6436a747b14a5362c8727a" dependencies = [ + "autocfg", "crossbeam-deque", "either", "rustc-rayon-core", @@ -3389,13 +3470,13 @@ dependencies = [ [[package]] name = "rustc-rayon-core" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "564bfd27be8db888d0fa76aa4335e7851aaed0c2c11ad1e93aeb9349f6b88500" +checksum = "02269144a0db9bb55cf5d4a41a5a0e95b334b0b78b08269018ca9b0250718c30" dependencies = [ + "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", "num_cpus", ] @@ -3432,6 +3513,7 @@ version = "1.0.0" dependencies = [ "bstr", "byteorder", + "clap 3.2.5", "crossbeam-utils", "libc", "libz-sys", @@ -3487,6 +3569,7 @@ dependencies = [ "rustc_errors", "rustc_hir", "rustc_index", + "rustc_middle", "rustc_query_system", "rustc_session", "rustc_span", @@ -3577,6 +3660,7 @@ dependencies = [ "rustc_feature", "rustc_lexer", "rustc_lint_defs", + "rustc_macros", "rustc_parse", "rustc_parse_format", "rustc_session", @@ -3596,7 +3680,6 @@ dependencies = [ "libloading", "measureme 10.0.0", "rustc-demangle", - "rustc_arena", "rustc_ast", "rustc_attr", "rustc_codegen_ssa", @@ -3613,6 +3696,7 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", + "rustc_symbol_mangling", "rustc_target", "smallvec", "tracing", @@ -3627,7 +3711,7 @@ dependencies = [ "itertools", "jobserver", "libc", - "object 0.28.4", + "object 0.29.0", "pathdiff", "regex", "rustc_apfloat", @@ -3649,6 +3733,7 @@ dependencies = [ "rustc_span", "rustc_symbol_mangling", "rustc_target", + "serde_json", "smallvec", "snap", "tempfile", @@ -3676,6 +3761,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", + "rustc_type_ir", "tracing", ] @@ -3692,7 +3778,7 @@ dependencies = [ "libc", "measureme 10.0.0", "memmap2", - "parking_lot", + "parking_lot 0.11.2", "rustc-hash", "rustc-rayon", "rustc-rayon-core", @@ -3716,7 +3802,6 @@ dependencies = [ "rustc_ast", "rustc_ast_pretty", "rustc_codegen_ssa", - "rustc_const_eval", "rustc_data_structures", "rustc_error_codes", "rustc_errors", @@ -3731,11 +3816,11 @@ dependencies = [ "rustc_parse", "rustc_plugin_impl", "rustc_save_analysis", - "rustc_serialize", "rustc_session", "rustc_span", "rustc_target", "rustc_typeck", + "serde_json", "tracing", "winapi", ] @@ -3763,7 +3848,7 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ - "annotate-snippets", + "annotate-snippets 0.8.0", "atty", "rustc_data_structures", "rustc_error_messages", @@ -3771,6 +3856,8 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", + "serde", + "serde_json", "termcolor", "termize", "tracing", @@ -3824,7 +3911,6 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_error_messages", - "rustc_feature", "rustc_index", "rustc_macros", "rustc_serialize", @@ -3885,7 +3971,6 @@ dependencies = [ "rustc_macros", "rustc_middle", "rustc_serialize", - "rustc_session", "rustc_span", "rustc_target", "smallvec", @@ -3969,6 +4054,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", + "rustc_type_ir", "tracing", "unicode-security", ] @@ -3985,6 +4071,7 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", + "serde", ] [[package]] @@ -4010,10 +4097,14 @@ dependencies = [ name = "rustc_macros" version = "0.1.0" dependencies = [ + "annotate-snippets 0.8.0", + "fluent-bundle", + "fluent-syntax", "proc-macro2", "quote", "syn", "synstructure", + "unic-langid", ] [[package]] @@ -4037,6 +4128,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", + "rustc_type_ir", "smallvec", "snap", "tracing", @@ -4112,7 +4204,6 @@ dependencies = [ "rustc_index", "rustc_middle", "rustc_serialize", - "rustc_session", "rustc_span", "rustc_target", "smallvec", @@ -4134,7 +4225,6 @@ dependencies = [ "rustc_index", "rustc_middle", "rustc_mir_dataflow", - "rustc_query_system", "rustc_serialize", "rustc_session", "rustc_span", @@ -4149,7 +4239,6 @@ name = "rustc_monomorphize" version = "0.0.0" dependencies = [ "rustc_data_structures", - "rustc_errors", "rustc_hir", "rustc_index", "rustc_middle", @@ -4190,6 +4279,7 @@ dependencies = [ name = "rustc_passes" version = "0.0.0" dependencies = [ + "itertools", "rustc_ast", "rustc_ast_pretty", "rustc_attr", @@ -4201,7 +4291,6 @@ dependencies = [ "rustc_index", "rustc_lexer", "rustc_middle", - "rustc_parse", "rustc_serialize", "rustc_session", "rustc_span", @@ -4216,10 +4305,8 @@ dependencies = [ "libloading", "rustc_ast", "rustc_errors", - "rustc_hir", "rustc_lint", "rustc_metadata", - "rustc_middle", "rustc_session", "rustc_span", ] @@ -4265,7 +4352,7 @@ dependencies = [ name = "rustc_query_system" version = "0.0.0" dependencies = [ - "parking_lot", + "parking_lot 0.11.2", "rustc-rayon-core", "rustc_arena", "rustc_ast", @@ -4290,7 +4377,6 @@ dependencies = [ "bitflags", "rustc_arena", "rustc_ast", - "rustc_ast_lowering", "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", @@ -4356,6 +4442,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "rustc_smir" +version = "0.0.0" +dependencies = [ + "rustc_borrowck", + "rustc_driver", + "rustc_hir", + "rustc_interface", + "rustc_middle", + "rustc_mir_dataflow", + "rustc_mir_transform", + "rustc_serialize", + "rustc_trait_selection", +] + [[package]] name = "rustc_span" version = "0.0.0" @@ -4383,7 +4484,6 @@ dependencies = [ "rustc_data_structures", "rustc_hir", "rustc_middle", - "rustc_query_system", "rustc_session", "rustc_span", "rustc_target", @@ -4400,6 +4500,7 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", + "serde_json", "tracing", ] @@ -4469,6 +4570,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", + "rustc_type_ir", "tracing", ] @@ -4481,6 +4583,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_serialize", + "smallvec", ] [[package]] @@ -4506,6 +4609,7 @@ dependencies = [ "rustc_target", "rustc_trait_selection", "rustc_ty_utils", + "rustc_type_ir", "smallvec", "tracing", ] @@ -4564,21 +4668,9 @@ dependencies = [ [[package]] name = "rustfix" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c50b74badcddeb8f7652fa8323ce440b95286f8e4b64ebfd871c609672704e" -dependencies = [ - "anyhow", - "log", - "serde", - "serde_json", -] - -[[package]] -name = "rustfix" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0be05fc0675ef4f47119dc39cfc46636bb77d4fc4ef1bd851b9c3f7697f32a" +checksum = "ecd2853d9e26988467753bd9912c3a126f642d05d229a4b53f5752ee36c56481" dependencies = [ "anyhow", "log", @@ -4598,16 +4690,17 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.4.38" +version = "1.5.1" dependencies = [ - "annotate-snippets", + "annotate-snippets 0.9.1", "anyhow", "bytecount", "cargo_metadata", + "clap 3.2.5", "derive-new", "diff", "dirs", - "env_logger 0.8.4", + "env_logger 0.9.0", "getopts", "ignore", "itertools", @@ -4618,8 +4711,7 @@ dependencies = [ "rustfmt-config_proc_macro", "serde", "serde_json", - "structopt", - "term 0.6.1", + "term", "thiserror", "toml", "unicode-segmentation", @@ -4854,9 +4946,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" +checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2" [[package]] name = "snap" @@ -4934,7 +5026,7 @@ dependencies = [ "core", "dlmalloc", "fortanix-sgx-abi", - "hashbrown 0.12.0", + "hashbrown", "hermit-abi 0.2.0", "libc", "miniz_oxide", @@ -4968,7 +5060,7 @@ checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26" dependencies = [ "lazy_static", "new_debug_unreachable", - "parking_lot", + "parking_lot 0.11.2", "phf_shared", "precomputed-hash", "serde", @@ -5007,30 +5099,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "structopt" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" -dependencies = [ - "clap 2.34.0", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "strum" version = "0.18.0" @@ -5043,7 +5111,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" dependencies = [ - "heck", + "heck 0.3.1", "proc-macro2", "quote", "syn", @@ -5072,11 +5140,26 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "sysinfo" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a8e71535da31837213ac114531d31def75d7aebd133264e420a3451fa7f703" +dependencies = [ + "cfg-if 1.0.0", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "winapi", +] + [[package]] name = "tar" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" dependencies = [ "filetime", "libc", @@ -5099,25 +5182,15 @@ dependencies = [ [[package]] name = "tendril" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707feda9f2582d5d680d733e38755547a3e8fb471e7ba11452ecfd9ce93a5d3b" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" dependencies = [ "futf", "mac", "utf-8", ] -[[package]] -name = "term" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" -dependencies = [ - "dirs", - "winapi", -] - [[package]] name = "term" version = "0.7.0" @@ -5172,7 +5245,7 @@ dependencies = [ "getopts", "libc", "num_cpus", - "term 0.7.0", + "term", ] [[package]] @@ -5186,9 +5259,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" @@ -5212,13 +5285,13 @@ dependencies = [ [[package]] name = "thorin-dwp" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd95b4559c196987c8451b4e14d08a4c796c2844f9adf4d2a2dbc9b3142843be" +checksum = "e6cb0c7868d7f90407531108ab03263d9452a8811b7cdd87675343a40d4aa254" dependencies = [ "gimli 0.26.1", - "hashbrown 0.11.2", - "object 0.28.4", + "hashbrown", + "object 0.29.0", "tracing", ] @@ -5246,17 +5319,6 @@ dependencies = [ name = "tier-check" version = "0.1.0" -[[package]] -name = "tikv-jemalloc-sys" -version = "0.4.1+5.2.1-patched" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a26331b05179d4cb505c8d6814a7e18d298972f0a551b0e3cefccff927f86d3" -dependencies = [ - "cc", - "fs_extra", - "libc", -] - [[package]] name = "time" version = "0.1.43" @@ -5408,7 +5470,7 @@ dependencies = [ "ansi_term", "lazy_static", "matchers", - "parking_lot", + "parking_lot 0.11.2", "regex", "sharded-slab", "smallvec", @@ -5462,6 +5524,20 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +[[package]] +name = "ui_test" +version = "0.1.0" +dependencies = [ + "colored", + "crossbeam", + "lazy_static", + "pretty_assertions 1.2.1", + "regex", + "rustc_version", + "serde", + "serde_json", +] + [[package]] name = "unic-char-property" version = "0.9.0" @@ -5598,9 +5674,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] name = "unicode-width" @@ -5796,6 +5872,49 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "xattr" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index a82389492b..4e78399606 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,6 @@ members = [ "src/tools/cargo/crates/credential/cargo-credential-wincred", "src/tools/rustdoc", "src/tools/rls", - "src/tools/rls/racer/metadata", - "src/tools/rls/racer/interner", "src/tools/rustfmt", "src/tools/miri", "src/tools/miri/cargo-miri", diff --git a/README.md b/README.md index 78edac9d12..26613314a1 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ by running it with the `--help` flag or reading the [rustc dev guide][rustcguide If you plan to use `x.py install` to create an installation, it is recommended that you set the `prefix` value in the `[install]` section to a directory. - Create install directory if you are not installing in default directory + Create install directory if you are not installing in default directory. 4. Build and install: diff --git a/RELEASES.md b/RELEASES.md index fa82077e65..e66bf60b7f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,189 @@ +Version 1.63.0 (2022-08-11) +========================== + +Language +-------- +- [Remove migrate borrowck mode for pre-NLL errors.][95565] +- [Modify MIR building to drop repeat expressions with length zero.][95953] +- [Remove label/lifetime shadowing warnings.][96296] +- [Allow explicit generic arguments in the presence of `impl Trait` args.][96868] +- [Make `cenum_impl_drop_cast` warnings deny-by-default.][97652] +- [Prevent unwinding when `-C panic=abort` is used regardless of declared ABI.][96959] +- [lub: don't bail out due to empty binders.][97867] + +Compiler +-------- +- [Stabilize the `bundle` native library modifier,][95818] also removing the + deprecated `static-nobundle` linking kind. +- [Add Apple WatchOS compile targets\*.][95243] +- [Add a Windows application manifest to rustc-main.][96737] + +\* Refer to Rust's [platform support page][platform-support-doc] for more + information on Rust's tiered platform support. + +Libraries +--------- +- [Implement `Copy`, `Clone`, `PartialEq` and `Eq` for `core::fmt::Alignment`.][94530] +- [Extend `ptr::null` and `null_mut` to all thin (including extern) types.][94954] +- [`impl Read and Write for VecDeque`.][95632] +- [STD support for the Nintendo 3DS.][95897] +- [Make write/print macros eagerly drop temporaries.][96455] +- [Implement internal traits that enable `[OsStr]::join`.][96881] +- [Implement `Hash` for `core::alloc::Layout`.][97034] +- [Add capacity documentation for `OsString`.][97202] +- [Put a bound on collection misbehavior.][97316] +- [Make `std::mem::needs_drop` accept `?Sized`.][97675] +- [`impl Termination for Infallible` and then make the `Result` impls of `Termination` more generic.][97803] +- [Document Rust's stance on `/proc/self/mem`.][97837] + +Stabilized APIs +--------------- + +- [`array::from_fn`] +- [`Box::into_pin`] +- [`BinaryHeap::try_reserve`] +- [`BinaryHeap::try_reserve_exact`] +- [`OsString::try_reserve`] +- [`OsString::try_reserve_exact`] +- [`PathBuf::try_reserve`] +- [`PathBuf::try_reserve_exact`] +- [`Path::try_exists`] +- [`Ref::filter_map`] +- [`RefMut::filter_map`] +- [`NonNull::<[T]>::len`][`NonNull::::len`] +- [`ToOwned::clone_into`] +- [`Ipv6Addr::to_ipv4_mapped`] +- [`unix::io::AsFd`] +- [`unix::io::BorrowedFd<'fd>`] +- [`unix::io::OwnedFd`] +- [`windows::io::AsHandle`] +- [`windows::io::BorrowedHandle<'handle>`] +- [`windows::io::OwnedHandle`] +- [`windows::io::HandleOrInvalid`] +- [`windows::io::HandleOrNull`] +- [`windows::io::InvalidHandleError`] +- [`windows::io::NullHandleError`] +- [`windows::io::AsSocket`] +- [`windows::io::BorrowedSocket<'handle>`] +- [`windows::io::OwnedSocket`] +- [`thread::scope`] +- [`thread::Scope`] +- [`thread::ScopedJoinHandle`] + +These APIs are now usable in const contexts: + +- [`array::from_ref`] +- [`slice::from_ref`] +- [`intrinsics::copy`] +- [`intrinsics::copy_nonoverlapping`] +- [`<*const T>::copy_to`] +- [`<*const T>::copy_to_nonoverlapping`] +- [`<*mut T>::copy_to`] +- [`<*mut T>::copy_to_nonoverlapping`] +- [`<*mut T>::copy_from`] +- [`<*mut T>::copy_from_nonoverlapping`] +- [`str::from_utf8`] +- [`Utf8Error::error_len`] +- [`Utf8Error::valid_up_to`] +- [`Condvar::new`] +- [`Mutex::new`] +- [`RwLock::new`] + +Cargo +----- +- [Stabilize the `--config path` command-line argument.][cargo/10755] +- [Expose rust-version in the environment as `CARGO_PKG_RUST_VERSION`.][cargo/10713] + +Compatibility Notes +------------------- + +- [`#[link]` attributes are now checked more strictly,][96885] which may introduce + errors for invalid attribute arguments that were previously ignored. + +Internal Changes +---------------- + +These changes provide no direct user facing benefits, but represent significant +improvements to the internals and overall performance of rustc +and related tools. + +- [Prepare Rust for LLVM opaque pointers.][94214] + +[94214]: https://github.com/rust-lang/rust/pull/94214/ +[94530]: https://github.com/rust-lang/rust/pull/94530/ +[94954]: https://github.com/rust-lang/rust/pull/94954/ +[95243]: https://github.com/rust-lang/rust/pull/95243/ +[95565]: https://github.com/rust-lang/rust/pull/95565/ +[95632]: https://github.com/rust-lang/rust/pull/95632/ +[95818]: https://github.com/rust-lang/rust/pull/95818/ +[95897]: https://github.com/rust-lang/rust/pull/95897/ +[95953]: https://github.com/rust-lang/rust/pull/95953/ +[96296]: https://github.com/rust-lang/rust/pull/96296/ +[96455]: https://github.com/rust-lang/rust/pull/96455/ +[96737]: https://github.com/rust-lang/rust/pull/96737/ +[96868]: https://github.com/rust-lang/rust/pull/96868/ +[96881]: https://github.com/rust-lang/rust/pull/96881/ +[96885]: https://github.com/rust-lang/rust/pull/96885/ +[96959]: https://github.com/rust-lang/rust/pull/96959/ +[97034]: https://github.com/rust-lang/rust/pull/97034/ +[97202]: https://github.com/rust-lang/rust/pull/97202/ +[97316]: https://github.com/rust-lang/rust/pull/97316/ +[97652]: https://github.com/rust-lang/rust/pull/97652/ +[97675]: https://github.com/rust-lang/rust/pull/97675/ +[97803]: https://github.com/rust-lang/rust/pull/97803/ +[97837]: https://github.com/rust-lang/rust/pull/97837/ +[97867]: https://github.com/rust-lang/rust/pull/97867/ +[cargo/10713]: https://github.com/rust-lang/cargo/pull/10713/ +[cargo/10755]: https://github.com/rust-lang/cargo/pull/10755/ + +[`array::from_fn`]: https://doc.rust-lang.org/stable/std/array/fn.from_fn.html +[`Box::into_pin`]: https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.into_pin +[`BinaryHeap::try_reserve_exact`]: https://doc.rust-lang.org/stable/alloc/collections/binary_heap/struct.BinaryHeap.html#method.try_reserve_exact +[`BinaryHeap::try_reserve`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.try_reserve +[`OsString::try_reserve`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.try_reserve +[`OsString::try_reserve_exact`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.try_reserve_exact +[`PathBuf::try_reserve`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.try_reserve +[`PathBuf::try_reserve_exact`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.try_reserve_exact +[`Path::try_exists`]: https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.try_exists +[`Ref::filter_map`]: https://doc.rust-lang.org/stable/std/cell/struct.Ref.html#method.filter_map +[`RefMut::filter_map`]: https://doc.rust-lang.org/stable/std/cell/struct.RefMut.html#method.filter_map +[`NonNull::::len`]: https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.len +[`ToOwned::clone_into`]: https://doc.rust-lang.org/stable/std/borrow/trait.ToOwned.html#method.clone_into +[`Ipv6Addr::to_ipv4_mapped`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.to_ipv4_mapped +[`unix::io::AsFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsFd.html +[`unix::io::BorrowedFd<'fd>`]: https://doc.rust-lang.org/stable/std/os/unix/io/struct.BorrowedFd.html +[`unix::io::OwnedFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/struct.OwnedFd.html +[`windows::io::AsHandle`]: https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsHandle.html +[`windows::io::BorrowedHandle<'handle>`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.BorrowedHandle.html +[`windows::io::OwnedHandle`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html +[`windows::io::HandleOrInvalid`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.HandleOrInvalid.html +[`windows::io::HandleOrNull`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.HandleOrNull.html +[`windows::io::InvalidHandleError`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.InvalidHandleError.html +[`windows::io::NullHandleError`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.NullHandleError.html +[`windows::io::AsSocket`]: https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsSocket.html +[`windows::io::BorrowedSocket<'handle>`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.BorrowedSocket.html +[`windows::io::OwnedSocket`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedSocket.html +[`thread::scope`]: https://doc.rust-lang.org/stable/std/thread/fn.scope.html +[`thread::Scope`]: https://doc.rust-lang.org/stable/std/thread/struct.Scope.html +[`thread::ScopedJoinHandle`]: https://doc.rust-lang.org/stable/std/thread/struct.ScopedJoinHandle.html + +[`array::from_ref`]: https://doc.rust-lang.org/stable/std/array/fn.from_ref.html +[`slice::from_ref`]: https://doc.rust-lang.org/stable/std/slice/fn.from_ref.html +[`intrinsics::copy`]: https://doc.rust-lang.org/stable/std/intrinsics/fn.copy.html +[`intrinsics::copy_nonoverlapping`]: https://doc.rust-lang.org/stable/std/intrinsics/fn.copy_nonoverlapping.html +[`<*const T>::copy_to`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_to +[`<*const T>::copy_to_nonoverlapping`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_to_nonoverlapping +[`<*mut T>::copy_to`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_to-1 +[`<*mut T>::copy_to_nonoverlapping`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_to_nonoverlapping-1 +[`<*mut T>::copy_from`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_from +[`<*mut T>::copy_from_nonoverlapping`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_from_nonoverlapping +[`str::from_utf8`]: https://doc.rust-lang.org/stable/std/str/fn.from_utf8.html +[`Utf8Error::error_len`]: https://doc.rust-lang.org/stable/std/str/struct.Utf8Error.html#method.error_len +[`Utf8Error::valid_up_to`]: https://doc.rust-lang.org/stable/std/str/struct.Utf8Error.html#method.valid_up_to +[`Condvar::new`]: https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html#method.new +[`Mutex::new`]: https://doc.rust-lang.org/stable/std/sync/struct.Mutex.html#method.new +[`RwLock::new`]: https://doc.rust-lang.org/stable/std/sync/struct.RwLock.html#method.new + Version 1.62.1 (2022-07-19) ========================== @@ -23,7 +209,7 @@ Language -------- - [Stabilize `#[derive(Default)]` on enums with a `#[default]` variant][94457] -- [Stop validating some checks in dead code after functions with uninhabited return types][93313] +- [Teach flow sensitive checks that visibly uninhabited call expressions never return][93313] - [Fix constants not getting dropped if part of a diverging expression][94775] - [Support unit struct/enum variant in destructuring assignment][95380] - [Remove mutable_borrow_reservation_conflict lint and allow the code pattern][96268] @@ -47,7 +233,6 @@ Compiler Libraries --------- -- [Move `CStr` to libcore, and `CString` to liballoc][94079] - [Windows: Use a pipe relay for chaining pipes][95841] - [Replace Linux Mutex and Condvar with futex based ones.][95035] - [Replace RwLock by a futex based one on Linux][95801] @@ -94,8 +279,11 @@ Compatibility Notes - `cargo test` now passes `--target` to `rustdoc` if the specified target is the same as the host target. [#10594](https://github.com/rust-lang/cargo/pull/10594) +- [rustdoc: doctests are now run on unexported `macro_rules!` macros, matching other private items][96630] - [rustdoc: Remove .woff font files][96279] - [Enforce Copy bounds for repeat elements while considering lifetimes][95819] +- [Windows: Fix potentinal unsoundness by aborting if `File` reads or writes cannot + complete synchronously][95469]. Internal Changes ---------------- @@ -108,7 +296,6 @@ and related tools. [93313]: https://github.com/rust-lang/rust/pull/93313/ [93969]: https://github.com/rust-lang/rust/pull/93969/ -[94079]: https://github.com/rust-lang/rust/pull/94079/ [94206]: https://github.com/rust-lang/rust/pull/94206/ [94457]: https://github.com/rust-lang/rust/pull/94457/ [94775]: https://github.com/rust-lang/rust/pull/94775/ @@ -118,6 +305,7 @@ and related tools. [95372]: https://github.com/rust-lang/rust/pull/95372/ [95380]: https://github.com/rust-lang/rust/pull/95380/ [95431]: https://github.com/rust-lang/rust/pull/95431/ +[95469]: https://github.com/rust-lang/rust/pull/95469/ [95705]: https://github.com/rust-lang/rust/pull/95705/ [95801]: https://github.com/rust-lang/rust/pull/95801/ [95819]: https://github.com/rust-lang/rust/pull/95819/ @@ -129,6 +317,7 @@ and related tools. [96393]: https://github.com/rust-lang/rust/pull/96393/ [96436]: https://github.com/rust-lang/rust/pull/96436/ [96557]: https://github.com/rust-lang/rust/pull/96557/ +[96630]: https://github.com/rust-lang/rust/pull/96630/ [`bool::then_some`]: https://doc.rust-lang.org/stable/std/primitive.bool.html#method.then_some [`f32::total_cmp`]: https://doc.rust-lang.org/stable/std/primitive.f32.html#method.total_cmp diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index b642e89195..27ee3dd2ae 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -9,14 +9,17 @@ rustc_driver = { path = "../rustc_driver" } # Make sure rustc_codegen_ssa ends up in the sysroot, because this # crate is intended to be used by codegen backends, which may not be in-tree. rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } +# Make sure rustc_smir ends up in the sysroot, because this +# crate is intended to be used by stable MIR consumers, which are not in-tree +rustc_smir = { path = "../rustc_smir" } -[dependencies.tikv-jemalloc-sys] -version = '0.4.0' +[dependencies.jemalloc-sys] +version = "0.5.0" optional = true features = ['unprefixed_malloc_on_supported_platforms'] [features] -jemalloc = ['tikv-jemalloc-sys'] +jemalloc = ['jemalloc-sys'] llvm = ['rustc_driver/llvm'] max_level_info = ['rustc_driver/max_level_info'] rustc_use_parallel_compiler = ['rustc_driver/rustc_use_parallel_compiler'] diff --git a/compiler/rustc/Windows Manifest.xml b/compiler/rustc/Windows Manifest.xml new file mode 100644 index 0000000000..b37a2fd4c7 --- /dev/null +++ b/compiler/rustc/Windows Manifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + UTF-8 + + + + + + true + + + diff --git a/compiler/rustc/build.rs b/compiler/rustc/build.rs new file mode 100644 index 0000000000..24c06c0ddb --- /dev/null +++ b/compiler/rustc/build.rs @@ -0,0 +1,24 @@ +use std::env; + +fn main() { + let target_os = env::var("CARGO_CFG_TARGET_OS"); + let target_env = env::var("CARGO_CFG_TARGET_ENV"); + if Ok("windows") == target_os.as_deref() && Ok("msvc") == target_env.as_deref() { + set_windows_exe_options(); + } +} + +// Add a manifest file to rustc.exe. +fn set_windows_exe_options() { + static WINDOWS_MANIFEST_FILE: &str = "Windows Manifest.xml"; + + let mut manifest = env::current_dir().unwrap(); + manifest.push(WINDOWS_MANIFEST_FILE); + + println!("cargo:rerun-if-changed={}", WINDOWS_MANIFEST_FILE); + // Embed the Windows application manifest file. + println!("cargo:rustc-link-arg-bin=rustc-main=/MANIFEST:EMBED"); + println!("cargo:rustc-link-arg-bin=rustc-main=/MANIFESTINPUT:{}", manifest.to_str().unwrap()); + // Turn linker warnings into errors. + println!("cargo:rustc-link-arg-bin=rustc-main=/WX"); +} diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index 4edd095af1..0de1a78191 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -22,12 +22,10 @@ // The two crates we link to here, `std` and `rustc_driver`, are both dynamic // libraries. So we must reference jemalloc symbols one way or another, because // this file is the only object code in the rustc executable. -#[cfg(feature = "tikv-jemalloc-sys")] -use tikv_jemalloc_sys as jemalloc_sys; fn main() { // See the comment at the top of this file for an explanation of this. - #[cfg(feature = "tikv-jemalloc-sys")] + #[cfg(feature = "jemalloc-sys")] { use std::os::raw::{c_int, c_void}; diff --git a/compiler/rustc_apfloat/src/lib.rs b/compiler/rustc_apfloat/src/lib.rs index 143c6f7610..cfc3d5b15a 100644 --- a/compiler/rustc_apfloat/src/lib.rs +++ b/compiler/rustc_apfloat/src/lib.rs @@ -33,7 +33,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![no_std] #![forbid(unsafe_code)] -#![feature(nll)] #[macro_use] extern crate alloc; diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5a4c997ed9..e5b61d7000 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -23,15 +23,15 @@ pub use GenericArgs::*; pub use UnsafeSource::*; use crate::ptr::P; -use crate::token::{self, CommentKind, Delimiter, Token, TokenKind}; -use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree}; +use crate::token::{self, CommentKind, Delimiter}; +use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lrc; use rustc_data_structures::thin_vec::ThinVec; use rustc_macros::HashStable_Generic; -use rustc_serialize::{self, Decoder, Encoder}; +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -41,9 +41,6 @@ use std::convert::TryFrom; use std::fmt; use std::mem; -#[cfg(test)] -mod tests; - /// A "Label" is an identifier of some point in sources, /// e.g. in the following code: /// @@ -444,8 +441,7 @@ impl Default for Generics { pub struct WhereClause { /// `true` if we ate a `where` token: this can happen /// if we parsed no predicates (e.g. `struct Foo where {}`). - /// This allows us to accurately pretty-print - /// in `nt_to_tokenstream` + /// This allows us to pretty-print accurately. pub has_where_token: bool, pub predicates: Vec, pub span: Span, @@ -1282,6 +1278,22 @@ impl Expr { }, ) } + + // To a first-order approximation, is this a pattern + pub fn is_approximately_pattern(&self) -> bool { + match &self.peel_parens().kind { + ExprKind::Box(_) + | ExprKind::Array(_) + | ExprKind::Call(_, _) + | ExprKind::Tup(_) + | ExprKind::Lit(_) + | ExprKind::Range(_, _, _) + | ExprKind::Underscore + | ExprKind::Path(_, _) + | ExprKind::Struct(_) => true, + _ => false, + } + } } /// Limit types of a range (inclusive or exclusive) @@ -1571,20 +1583,7 @@ impl MacArgs { match self { MacArgs::Empty => TokenStream::default(), MacArgs::Delimited(.., tokens) => tokens.clone(), - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => { - // Currently only literals are allowed here. If more complex expression kinds are - // allowed in the future, then `nt_to_tokenstream` should be used to extract the - // token stream. This will require some cleverness, perhaps with a function - // pointer, because `nt_to_tokenstream` is not directly usable from this crate. - // It will also require changing the `parse_expr` call in `parse_mac_args_common` - // to `parse_expr_force_collect`. - if let ExprKind::Lit(lit) = &expr.kind { - let token = Token::new(TokenKind::Literal(lit.token), lit.span); - TokenTree::Token(token).into() - } else { - unreachable!("couldn't extract literal when getting inner tokens: {:?}", expr) - } - } + MacArgs::Eq(_, MacArgsEq::Ast(expr)) => TokenStream::from_ast(expr), MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { unreachable!("in literal form when getting inner tokens: {:?}", lit) } @@ -1976,6 +1975,8 @@ pub struct BareFnTy { pub ext: Extern, pub generic_params: Vec, pub decl: P, + /// Span of the `fn(...) -> ...` part. + pub decl_span: Span, } /// The various kinds of type recognized by the compiler. @@ -2487,13 +2488,11 @@ rustc_index::newtype_index! { } } -impl rustc_serialize::Encodable for AttrId { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_unit() - } +impl Encodable for AttrId { + fn encode(&self, _s: &mut S) {} } -impl rustc_serialize::Decodable for AttrId { +impl Decodable for AttrId { fn decode(_: &mut D) -> AttrId { crate::attr::mk_attr_id() } @@ -2564,15 +2563,6 @@ impl PolyTraitRef { } } -#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)] -pub enum CrateSugar { - /// Source is `pub(crate)`. - PubCrate, - - /// Source is (just) `crate`. - JustCrate, -} - #[derive(Clone, Encodable, Decodable, Debug)] pub struct Visibility { pub kind: VisibilityKind, @@ -2583,7 +2573,6 @@ pub struct Visibility { #[derive(Clone, Encodable, Decodable, Debug)] pub enum VisibilityKind { Public, - Crate(CrateSugar), Restricted { path: P, id: NodeId }, Inherited, } diff --git a/compiler/rustc_ast/src/ast/tests.rs b/compiler/rustc_ast/src/ast/tests.rs deleted file mode 100644 index 8ba55bf037..0000000000 --- a/compiler/rustc_ast/src/ast/tests.rs +++ /dev/null @@ -1,11 +0,0 @@ -use super::*; - -// Are ASTs encodable? -#[test] -fn check_asts_encodable() { - fn assert_encodable< - T: for<'a> rustc_serialize::Encodable>, - >() { - } - assert_encodable::(); -} diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index bd401ddbbe..5c30a75a14 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -108,7 +108,7 @@ macro_rules! impl_has_span { }; } -impl_has_span!(AssocItem, Expr, ForeignItem, Item, Stmt); +impl_has_span!(AssocItem, Block, Expr, ForeignItem, Item, Pat, Path, Stmt, Ty, Visibility); impl> HasSpan for T { fn span(&self) -> Span { @@ -116,6 +116,12 @@ impl> HasSpan for T { } } +impl HasSpan for AttrItem { + fn span(&self) -> Span { + self.span() + } +} + /// A trait for AST nodes having (or not having) collected tokens. pub trait HasTokens { fn tokens(&self) -> Option<&LazyTokenStream>; diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 84654a9f73..988918b050 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -340,7 +340,7 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem { NestedMetaItem::MetaItem(mk_word_item(ident)) } -crate fn mk_attr_id() -> AttrId { +pub(crate) fn mk_attr_id() -> AttrId { use std::sync::atomic::AtomicU32; use std::sync::atomic::Ordering; @@ -552,7 +552,7 @@ impl MetaItemKind { ) -> Option { match tokens.next() { Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => { - MetaItemKind::name_value_from_tokens(&mut inner_tokens.trees()) + MetaItemKind::name_value_from_tokens(&mut inner_tokens.into_trees()) } Some(TokenTree::Token(token)) => { Lit::from_token(&token).ok().map(MetaItemKind::NameValue) diff --git a/compiler/rustc_ast/src/entry.rs b/compiler/rustc_ast/src/entry.rs index c0a837985f..3370146193 100644 --- a/compiler/rustc_ast/src/entry.rs +++ b/compiler/rustc_ast/src/entry.rs @@ -2,7 +2,7 @@ pub enum EntryPointType { None, MainNamed, - MainAttr, + RustcMainAttr, Start, OtherMain, // Not an entry point, but some other function named main } diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 1246716919..4b94ec0d6d 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -12,13 +12,11 @@ #![feature(box_patterns)] #![feature(const_default_impls)] #![feature(const_trait_impl)] -#![feature(crate_visibility_modifier)] #![feature(if_let_guard)] #![feature(label_break_value)] #![feature(let_chains)] #![feature(min_specialization)] #![feature(negative_impls)] -#![feature(nll)] #![feature(slice_internals)] #![feature(stmt_expr_attributes)] #![recursion_limit = "256"] diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index b425b5e2cc..85bb529648 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -460,10 +460,11 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { vis.visit_mt(mt); } TyKind::BareFn(bft) => { - let BareFnTy { unsafety, ext: _, generic_params, decl } = bft.deref_mut(); + let BareFnTy { unsafety, ext: _, generic_params, decl, decl_span } = bft.deref_mut(); visit_unsafety(unsafety, vis); generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_fn_decl(decl); + vis.visit_span(decl_span); } TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)), TyKind::Paren(ty) => vis.visit_ty(ty), @@ -1468,7 +1469,7 @@ pub fn noop_flat_map_stmt_kind( pub fn noop_visit_vis(visibility: &mut Visibility, vis: &mut T) { match &mut visibility.kind { - VisibilityKind::Public | VisibilityKind::Crate(_) | VisibilityKind::Inherited => {} + VisibilityKind::Public | VisibilityKind::Inherited => {} VisibilityKind::Restricted { path, id } => { vis.visit_path(path); vis.visit_id(id); diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 89a0857992..30481eddf9 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -10,7 +10,7 @@ //! //! * **Immutability**: `P` disallows mutating its inner `T`, unlike `Box` //! (unless it contains an `Unsafe` interior, but that may be denied later). -//! This mainly prevents mistakes, but can also enforces a kind of "purity". +//! This mainly prevents mistakes, but also enforces a kind of "purity". //! //! * **Efficiency**: folding can reuse allocation space for `P` and `Vec`, //! the latter even when the input and output types differ (as it would be the @@ -121,8 +121,8 @@ impl> Decodable for P { } impl> Encodable for P { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (**self).encode(s) + fn encode(&self, s: &mut S) { + (**self).encode(s); } } @@ -191,8 +191,8 @@ impl<'a, T> IntoIterator for &'a P<[T]> { } impl> Encodable for P<[T]> { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - Encodable::encode(&**self, s) + fn encode(&self, s: &mut S) { + Encodable::encode(&**self, s); } } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 72dd44a4b4..85d9687c60 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -133,7 +133,7 @@ impl LitKind { } } - crate fn may_have_suffix(self) -> bool { + pub(crate) fn may_have_suffix(self) -> bool { matches!(self, Integer | Float | Err) } } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index a8f29f3340..37de90d64c 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -13,7 +13,9 @@ //! and a borrowed `TokenStream` is sufficient to build an owned `TokenStream` without taking //! ownership of the original. -use crate::token::{self, Delimiter, Token, TokenKind}; +use crate::ast::StmtKind; +use crate::ast_traits::{HasAttrs, HasSpan, HasTokens}; +use crate::token::{self, Delimiter, Nonterminal, Token, TokenKind}; use crate::AttrVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -23,7 +25,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::{Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; -use std::{fmt, iter, mem}; +use std::{fmt, iter}; /// When the main Rust parser encounters a syntax-extension invocation, it /// parses the arguments to the invocation as a token tree. This is a very @@ -45,12 +47,6 @@ pub enum TokenTree { Delimited(DelimSpan, Delimiter, TokenStream), } -#[derive(Copy, Clone)] -pub enum CanSynthesizeMissingTokens { - Yes, - No, -} - // Ensure all fields of `TokenTree` is `Send` and `Sync`. #[cfg(parallel_compiler)] fn _dummy() @@ -146,9 +142,9 @@ impl fmt::Debug for LazyTokenStream { } impl Encodable for LazyTokenStream { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { + fn encode(&self, s: &mut S) { // Used by AST json printing. - Encodable::encode(&self.create_token_stream(), s) + Encodable::encode(&self.create_token_stream(), s); } } @@ -403,47 +399,8 @@ impl TokenStream { self.0.len() } - pub fn from_streams(mut streams: SmallVec<[TokenStream; 2]>) -> TokenStream { - match streams.len() { - 0 => TokenStream::default(), - 1 => streams.pop().unwrap(), - _ => { - // We are going to extend the first stream in `streams` with - // the elements from the subsequent streams. This requires - // using `make_mut()` on the first stream, and in practice this - // doesn't cause cloning 99.9% of the time. - // - // One very common use case is when `streams` has two elements, - // where the first stream has any number of elements within - // (often 1, but sometimes many more) and the second stream has - // a single element within. - - // Determine how much the first stream will be extended. - // Needed to avoid quadratic blow up from on-the-fly - // reallocations (#57735). - let num_appends = streams.iter().skip(1).map(|ts| ts.len()).sum(); - - // Get the first stream. If it's `None`, create an empty - // stream. - let mut iter = streams.drain(..); - let mut first_stream_lrc = iter.next().unwrap().0; - - // Append the elements to the first stream, after reserving - // space for them. - let first_vec_mut = Lrc::make_mut(&mut first_stream_lrc); - first_vec_mut.reserve(num_appends); - for stream in iter { - first_vec_mut.extend(stream.0.iter().cloned()); - } - - // Create the final `TokenStream`. - TokenStream(first_stream_lrc) - } - } - } - - pub fn trees(&self) -> Cursor { - self.clone().into_trees() + pub fn trees(&self) -> CursorRef<'_> { + CursorRef::new(self) } pub fn into_trees(self) -> Cursor { @@ -471,6 +428,89 @@ impl TokenStream { .collect(), )) } + + fn opt_from_ast(node: &(impl HasAttrs + HasTokens)) -> Option { + let tokens = node.tokens()?; + let attrs = node.attrs(); + let attr_annotated = if attrs.is_empty() { + tokens.create_token_stream() + } else { + let attr_data = AttributesData { attrs: attrs.to_vec().into(), tokens: tokens.clone() }; + AttrAnnotatedTokenStream::new(vec![( + AttrAnnotatedTokenTree::Attributes(attr_data), + Spacing::Alone, + )]) + }; + Some(attr_annotated.to_tokenstream()) + } + + pub fn from_ast(node: &(impl HasAttrs + HasSpan + HasTokens + fmt::Debug)) -> TokenStream { + TokenStream::opt_from_ast(node) + .unwrap_or_else(|| panic!("missing tokens for node at {:?}: {:?}", node.span(), node)) + } + + pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream { + match nt { + Nonterminal::NtIdent(ident, is_raw) => { + TokenTree::token(token::Ident(ident.name, *is_raw), ident.span).into() + } + Nonterminal::NtLifetime(ident) => { + TokenTree::token(token::Lifetime(ident.name), ident.span).into() + } + Nonterminal::NtItem(item) => TokenStream::from_ast(item), + Nonterminal::NtBlock(block) => TokenStream::from_ast(block), + Nonterminal::NtStmt(stmt) if let StmtKind::Empty = stmt.kind => { + // FIXME: Properly collect tokens for empty statements. + TokenTree::token(token::Semi, stmt.span).into() + } + Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt), + Nonterminal::NtPat(pat) => TokenStream::from_ast(pat), + Nonterminal::NtTy(ty) => TokenStream::from_ast(ty), + Nonterminal::NtMeta(attr) => TokenStream::from_ast(attr), + Nonterminal::NtPath(path) => TokenStream::from_ast(path), + Nonterminal::NtVis(vis) => TokenStream::from_ast(vis), + Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr), + } + } + + fn flatten_token(token: &Token) -> TokenTree { + match &token.kind { + token::Interpolated(nt) if let token::NtIdent(ident, is_raw) = **nt => { + TokenTree::token(token::Ident(ident.name, is_raw), ident.span) + } + token::Interpolated(nt) => TokenTree::Delimited( + DelimSpan::from_single(token.span), + Delimiter::Invisible, + TokenStream::from_nonterminal_ast(&nt).flattened(), + ), + _ => TokenTree::Token(token.clone()), + } + } + + fn flatten_token_tree(tree: &TokenTree) -> TokenTree { + match tree { + TokenTree::Token(token) => TokenStream::flatten_token(token), + TokenTree::Delimited(span, delim, tts) => { + TokenTree::Delimited(*span, *delim, tts.flattened()) + } + } + } + + #[must_use] + pub fn flattened(&self) -> TokenStream { + fn can_skip(stream: &TokenStream) -> bool { + stream.trees().all(|tree| match tree { + TokenTree::Token(token) => !matches!(token.kind, token::Interpolated(_)), + TokenTree::Delimited(_, _, inner) => can_skip(inner), + }) + } + + if can_skip(self) { + return self.clone(); + } + + self.trees().map(|tree| TokenStream::flatten_token_tree(tree)).collect() + } } // 99.5%+ of the time we have 1 or 2 elements in this vector. @@ -483,50 +523,65 @@ impl TokenStreamBuilder { } pub fn push>(&mut self, stream: T) { - let mut stream = stream.into(); - - // If `self` is not empty and the last tree within the last stream is a - // token tree marked with `Joint`... - if let Some(TokenStream(ref mut last_stream_lrc)) = self.0.last_mut() - && let Some((TokenTree::Token(last_token), Spacing::Joint)) = last_stream_lrc.last() - // ...and `stream` is not empty and the first tree within it is - // a token tree... - && let TokenStream(ref mut stream_lrc) = stream - && let Some((TokenTree::Token(token), spacing)) = stream_lrc.first() - // ...and the two tokens can be glued together... - && let Some(glued_tok) = last_token.glue(&token) - { - // ...then do so, by overwriting the last token - // tree in `self` and removing the first token tree - // from `stream`. This requires using `make_mut()` - // on the last stream in `self` and on `stream`, - // and in practice this doesn't cause cloning 99.9% - // of the time. - - // Overwrite the last token tree with the merged - // token. - let last_vec_mut = Lrc::make_mut(last_stream_lrc); - *last_vec_mut.last_mut().unwrap() = (TokenTree::Token(glued_tok), *spacing); - - // Remove the first token tree from `stream`. (This - // is almost always the only tree in `stream`.) - let stream_vec_mut = Lrc::make_mut(stream_lrc); - stream_vec_mut.remove(0); - - // Don't push `stream` if it's empty -- that could - // block subsequent token gluing, by getting - // between two token trees that should be glued - // together. - if !stream.is_empty() { - self.0.push(stream); - } - return; - } - self.0.push(stream); + self.0.push(stream.into()); } pub fn build(self) -> TokenStream { - TokenStream::from_streams(self.0) + let mut streams = self.0; + match streams.len() { + 0 => TokenStream::default(), + 1 => streams.pop().unwrap(), + _ => { + // We will extend the first stream in `streams` with the + // elements from the subsequent streams. This requires using + // `make_mut()` on the first stream, and in practice this + // doesn't cause cloning 99.9% of the time. + // + // One very common use case is when `streams` has two elements, + // where the first stream has any number of elements within + // (often 1, but sometimes many more) and the second stream has + // a single element within. + + // Determine how much the first stream will be extended. + // Needed to avoid quadratic blow up from on-the-fly + // reallocations (#57735). + let num_appends = streams.iter().skip(1).map(|ts| ts.len()).sum(); + + // Get the first stream, which will become the result stream. + // If it's `None`, create an empty stream. + let mut iter = streams.drain(..); + let mut res_stream_lrc = iter.next().unwrap().0; + + // Append the subsequent elements to the result stream, after + // reserving space for them. + let res_vec_mut = Lrc::make_mut(&mut res_stream_lrc); + res_vec_mut.reserve(num_appends); + for stream in iter { + let stream_iter = stream.0.iter().cloned(); + + // If (a) `res_mut_vec` is not empty and the last tree + // within it is a token tree marked with `Joint`, and (b) + // `stream` is not empty and the first tree within it is a + // token tree, and (c) the two tokens can be glued + // together... + if let Some((TokenTree::Token(last_tok), Spacing::Joint)) = res_vec_mut.last() + && let Some((TokenTree::Token(tok), spacing)) = stream.0.first() + && let Some(glued_tok) = last_tok.glue(&tok) + { + // ...then overwrite the last token tree in + // `res_vec_mut` with the glued token, and skip the + // first token tree from `stream`. + *res_vec_mut.last_mut().unwrap() = (TokenTree::Token(glued_tok), *spacing); + res_vec_mut.extend(stream_iter.skip(1)); + } else { + // Append all of `stream`. + res_vec_mut.extend(stream_iter); + } + } + + TokenStream(res_stream_lrc) + } + } } } @@ -538,12 +593,21 @@ pub struct CursorRef<'t> { } impl<'t> CursorRef<'t> { + fn new(stream: &'t TokenStream) -> Self { + CursorRef { stream, index: 0 } + } + + #[inline] fn next_with_spacing(&mut self) -> Option<&'t TreeAndSpacing> { self.stream.0.get(self.index).map(|tree| { self.index += 1; tree }) } + + pub fn look_ahead(&self, n: usize) -> Option<&TokenTree> { + self.stream.0[self.index..].get(n).map(|(tree, _)| tree) + } } impl<'t> Iterator for CursorRef<'t> { @@ -591,20 +655,6 @@ impl Cursor { }) } - pub fn index(&self) -> usize { - self.index - } - - pub fn append(&mut self, new_stream: TokenStream) { - if new_stream.is_empty() { - return; - } - let index = self.index; - let stream = mem::take(&mut self.stream); - *self = TokenStream::from_streams(smallvec![stream, new_stream]).into_trees(); - self.index = index; - } - pub fn look_ahead(&self, n: usize) -> Option<&TokenTree> { self.stream.0[self.index..].get(n).map(|(tree, _)| tree) } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index cc772ac74f..2ce8590d77 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -89,6 +89,16 @@ impl<'a> FnKind<'a> { } } +#[derive(Copy, Clone, Debug)] +pub enum LifetimeCtxt { + /// Appears in a reference type. + Rptr, + /// Appears as a bound on a type or another lifetime. + Bound, + /// Appears as a generic argument. + GenericArg, +} + /// Each method of the `Visitor` trait is a hook to be potentially /// overridden. Each method's default implementation recursively visits /// the substructure of the input via the corresponding `walk` method; @@ -184,7 +194,7 @@ pub trait Visitor<'ast>: Sized { fn visit_label(&mut self, label: &'ast Label) { walk_label(self, label) } - fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { + fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) { walk_lifetime(self, lifetime) } fn visit_mac_call(&mut self, mac: &'ast MacCall) { @@ -326,7 +336,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { ItemKind::ForeignMod(ref foreign_module) => { walk_list!(visitor, visit_foreign_item, &foreign_module.items); } - ItemKind::GlobalAsm(ref asm) => walk_inline_asm(visitor, asm), + ItemKind::GlobalAsm(ref asm) => visitor.visit_inline_asm(asm), ItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); @@ -414,7 +424,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { TyKind::Slice(ref ty) | TyKind::Paren(ref ty) => visitor.visit_ty(ty), TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty), TyKind::Rptr(ref opt_lifetime, ref mutable_type) => { - walk_list!(visitor, visit_lifetime, opt_lifetime); + walk_list!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Rptr); visitor.visit_ty(&mutable_type.ty) } TyKind::Tup(ref tuple_element_types) => { @@ -507,7 +517,7 @@ where V: Visitor<'a>, { match generic_arg { - GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt), + GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg), GenericArg::Type(ty) => visitor.visit_ty(ty), GenericArg::Const(ct) => visitor.visit_anon_const(ct), } @@ -599,7 +609,9 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) { match *bound { GenericBound::Trait(ref typ, ref modifier) => visitor.visit_poly_trait_ref(typ, modifier), - GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), + GenericBound::Outlives(ref lifetime) => { + visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound) + } } } @@ -639,7 +651,7 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a WherePredicate::RegionPredicate(WhereRegionPredicate { ref lifetime, ref bounds, .. }) => { - visitor.visit_lifetime(lifetime); + visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => { @@ -897,7 +909,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { } ExprKind::MacCall(ref mac) => visitor.visit_mac_call(mac), ExprKind::Paren(ref subexpression) => visitor.visit_expr(subexpression), - ExprKind::InlineAsm(ref asm) => walk_inline_asm(visitor, asm), + ExprKind::InlineAsm(ref asm) => visitor.visit_inline_asm(asm), ExprKind::Yield(ref optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 7989af24d9..e344d8a763 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -14,6 +14,7 @@ rustc_hir = { path = "../rustc_hir" } rustc_target = { path = "../rustc_target" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } +rustc_middle = { path = "../rustc_middle" } rustc_query_system = { path = "../rustc_query_system" } rustc_span = { path = "../rustc_span" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index ae3e367596..aab9b90e4b 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -1,4 +1,4 @@ -use crate::{ImplTraitContext, ImplTraitPosition, ParamMode}; +use crate::{ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt}; use super::LoweringContext; @@ -11,13 +11,17 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::definitions::DefPathData; use rustc_session::parse::feature_err; -use rustc_span::{sym, ExpnId, Span}; +use rustc_span::{sym, Span}; use rustc_target::asm; use std::collections::hash_map::Entry; use std::fmt::Write; impl<'a, 'hir> LoweringContext<'a, 'hir> { - crate fn lower_inline_asm(&mut self, sp: Span, asm: &InlineAsm) -> &'hir hir::InlineAsm<'hir> { + pub(crate) fn lower_inline_asm( + &mut self, + sp: Span, + asm: &InlineAsm, + ) -> &'hir hir::InlineAsm<'hir> { // Rustdoc needs to support asm! from foreign architectures: don't try // lowering the register constraints in this case. let asm_arch = if self.sess.opts.actually_rustdoc { None } else { self.sess.asm_arch }; @@ -238,14 +242,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Wrap the expression in an AnonConst. let parent_def_id = self.current_hir_id_owner; - let node_id = self.resolver.next_node_id(); - self.resolver.create_def( - parent_def_id, - node_id, - DefPathData::AnonConst, - ExpnId::root(), - *op_sp, - ); + let node_id = self.next_node_id(); + self.create_def(parent_def_id, node_id, DefPathData::AnonConst); let anon_const = AnonConst { id: node_id, value: P(expr) }; hir::InlineAsmOperand::SymFn { anon_const: self.lower_anon_const(&anon_const), diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 410ed3f0bd..3babe73030 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,6 +1,6 @@ -use crate::{FnDeclKind, ImplTraitPosition}; - +use super::ResolverAstLoweringExt; use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}; +use crate::{FnDeclKind, ImplTraitPosition}; use rustc_ast::attr; use rustc_ast::ptr::P as AstP; @@ -11,7 +11,6 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::definitions::DefPathData; -use rustc_span::hygiene::ExpnId; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; use rustc_span::symbol::{sym, Ident}; use rustc_span::DUMMY_SP; @@ -41,7 +40,22 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), ExprKind::Call(ref f, ref args) => { - if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) { + if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) { + if let [inner] = &args[..] && e.attrs.len() == 1 { + let kind = hir::ExprKind::Box(self.lower_expr(&inner)); + let hir_id = self.lower_node_id(e.id); + return hir::Expr { hir_id, kind, span: self.lower_span(e.span) }; + } else { + self.sess + .struct_span_err( + e.span, + "#[rustc_box] requires precisely one argument \ + and no other attributes are allowed", + ) + .emit(); + hir::ExprKind::Err + } + } else if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) { self.lower_legacy_const_generics((**f).clone(), args.clone(), &legacy_args) } else { let f = self.lower_expr(f); @@ -151,6 +165,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if let Async::Yes { closure_id, .. } = asyncness { self.lower_expr_async_closure( capture_clause, + e.id, closure_id, decl, body, @@ -159,6 +174,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } else { self.lower_expr_closure( capture_clause, + e.id, movability, decl, body, @@ -340,16 +356,10 @@ impl<'hir> LoweringContext<'_, 'hir> { for (idx, arg) in args.into_iter().enumerate() { if legacy_args_idx.contains(&idx) { let parent_def_id = self.current_hir_id_owner; - let node_id = self.resolver.next_node_id(); + let node_id = self.next_node_id(); // Add a definition for the in-band const def. - self.resolver.create_def( - parent_def_id, - node_id, - DefPathData::AnonConst, - ExpnId::root(), - arg.span, - ); + self.create_def(parent_def_id, node_id, DefPathData::AnonConst); let anon_const = AnonConst { id: node_id, value: arg }; generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const))); @@ -505,8 +515,14 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { let pat = self.lower_pat(&arm.pat); let guard = arm.guard.as_ref().map(|cond| { - if let ExprKind::Let(ref pat, ref scrutinee, _) = cond.kind { - hir::Guard::IfLet(self.lower_pat(pat), self.lower_expr(scrutinee)) + if let ExprKind::Let(ref pat, ref scrutinee, span) = cond.kind { + hir::Guard::IfLet(self.arena.alloc(hir::Let { + hir_id: self.next_id(), + span: self.lower_span(span), + pat: self.lower_pat(pat), + ty: None, + init: self.lower_expr(scrutinee), + })) } else { hir::Guard::If(self.lower_expr(cond)) } @@ -556,7 +572,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }; // The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`. - let decl = self.arena.alloc(hir::FnDecl { + let fn_decl = self.arena.alloc(hir::FnDecl { inputs: arena_vec![self; input_ty], output, c_variadic: false, @@ -577,7 +593,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }; let params = arena_vec![self; param]; - let body_id = self.lower_body(move |this| { + let body = self.lower_body(move |this| { this.generator_kind = Some(hir::GeneratorKind::Async(async_gen_kind)); let old_ctx = this.task_context; @@ -588,13 +604,14 @@ impl<'hir> LoweringContext<'_, 'hir> { }); // `static |_task_context| -> { body }`: - let generator_kind = hir::ExprKind::Closure( + let generator_kind = hir::ExprKind::Closure { capture_clause, - decl, - body_id, - self.lower_span(span), - Some(hir::Movability::Static), - ); + bound_generic_params: &[], + fn_decl, + body, + fn_decl_span: self.lower_span(span), + movability: Some(hir::Movability::Static), + }; let generator = hir::Expr { hir_id: self.lower_node_id(closure_node_id), kind: generator_kind, @@ -703,7 +720,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }; // `::std::task::Poll::Ready(result) => break result` - let loop_node_id = self.resolver.next_node_id(); + let loop_node_id = self.next_node_id(); let loop_hir_id = self.lower_node_id(loop_node_id); let ready_arm = { let x_ident = Ident::with_dummy_span(sym::result); @@ -814,12 +831,13 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_expr_closure( &mut self, capture_clause: CaptureBy, + closure_id: NodeId, movability: Movability, decl: &FnDecl, body: &Expr, fn_decl_span: Span, ) -> hir::ExprKind<'hir> { - let (body_id, generator_option) = self.with_new_scopes(move |this| { + let (body, generator_option) = self.with_new_scopes(move |this| { let prev = this.current_item; this.current_item = Some(fn_decl_span); let mut generator_kind = None; @@ -834,16 +852,19 @@ impl<'hir> LoweringContext<'_, 'hir> { (body_id, generator_option) }); - // Lower outside new scope to preserve `is_in_loop_condition`. - let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None); - - hir::ExprKind::Closure( - capture_clause, - fn_decl, - body_id, - self.lower_span(fn_decl_span), - generator_option, - ) + self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| { + // Lower outside new scope to preserve `is_in_loop_condition`. + let fn_decl = this.lower_fn_decl(decl, None, FnDeclKind::Closure, None); + + hir::ExprKind::Closure { + capture_clause, + bound_generic_params, + fn_decl, + body, + fn_decl_span: this.lower_span(fn_decl_span), + movability: generator_option, + } + }) } fn generator_movability_for_fn( @@ -883,6 +904,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, capture_clause: CaptureBy, closure_id: NodeId, + inner_closure_id: NodeId, decl: &FnDecl, body: &Expr, fn_decl_span: Span, @@ -890,7 +912,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let outer_decl = FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) }; - let body_id = self.with_new_scopes(|this| { + let body = self.with_new_scopes(|this| { // FIXME(cramertj): allow `async` non-`move` closures with arguments. if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() { struct_span_err!( @@ -913,7 +935,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None }; let async_body = this.make_async_expr( capture_clause, - closure_id, + inner_closure_id, async_ret_ty, body.span, hir::AsyncGeneratorKind::Closure, @@ -924,18 +946,21 @@ impl<'hir> LoweringContext<'_, 'hir> { body_id }); - // We need to lower the declaration outside the new scope, because we - // have to conserve the state of being inside a loop condition for the - // closure argument types. - let fn_decl = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None); - - hir::ExprKind::Closure( - capture_clause, - fn_decl, - body_id, - self.lower_span(fn_decl_span), - None, - ) + self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| { + // We need to lower the declaration outside the new scope, because we + // have to conserve the state of being inside a loop condition for the + // closure argument types. + let fn_decl = this.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None); + + hir::ExprKind::Closure { + capture_clause, + bound_generic_params, + fn_decl, + body, + fn_decl_span: this.lower_span(fn_decl_span), + movability: None, + } + }) } /// Destructure the LHS of complex assignments. @@ -1147,7 +1172,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .span_suggestion( e.span, "consider removing the trailing pattern", - String::new(), + "", rustc_errors::Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index c506360aa8..4be22020ba 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -6,6 +6,7 @@ use rustc_hir::definitions; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::*; use rustc_index::vec::{Idx, IndexVec}; +use rustc_middle::span_bug; use rustc_session::Session; use rustc_span::source_map::SourceMap; use rustc_span::{Span, DUMMY_SP}; @@ -75,7 +76,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { // owner of that node. if cfg!(debug_assertions) { if hir_id.owner != self.owner { - panic!( + span_bug!( + span, "inconsistent DepNode at `{:?}` for `{:?}`: \ current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})", self.source_map.span_to_diagnostic_string(span), @@ -313,6 +315,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { }); } + fn visit_assoc_type_binding(&mut self, type_binding: &'hir TypeBinding<'hir>) { + self.insert(type_binding.span, type_binding.hir_id, Node::TypeBinding(type_binding)); + self.with_parent(type_binding.hir_id, |this| { + intravisit::walk_assoc_type_binding(this, type_binding) + }) + } + fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) { // Do not visit the duplicate information in TraitItemRef. We want to // map the actual nodes, not the duplicate ones in the *Ref. diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index cf97b270ed..0ef2137169 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1,4 +1,5 @@ -use super::{AstOwner, ImplTraitContext, ImplTraitPosition, ResolverAstLowering}; +use super::ResolverAstLoweringExt; +use super::{AstOwner, ImplTraitContext, ImplTraitPosition}; use super::{LoweringContext, ParamMode}; use crate::{Arena, FnDeclKind}; @@ -11,23 +12,26 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; +use rustc_hir::definitions::Definitions; use rustc_hir::PredicateOrigin; use rustc_index::vec::{Idx, IndexVec}; -use rustc_session::utils::NtToTokenstream; +use rustc_middle::ty::{ResolverAstLowering, ResolverOutputs}; +use rustc_session::cstore::CrateStoreDyn; use rustc_session::Session; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use rustc_target::spec::abi; use smallvec::{smallvec, SmallVec}; -use tracing::debug; use std::iter; pub(super) struct ItemLowerer<'a, 'hir> { pub(super) sess: &'a Session, - pub(super) resolver: &'a mut dyn ResolverAstLowering, - pub(super) nt_to_tokenstream: NtToTokenstream, + pub(super) definitions: &'a mut Definitions, + pub(super) cstore: &'a CrateStoreDyn, + pub(super) resolutions: &'a ResolverOutputs, + pub(super) resolver: &'a mut ResolverAstLowering, pub(super) arena: &'hir Arena<'hir>, pub(super) ast_index: &'a IndexVec>, pub(super) owners: &'a mut IndexVec>>, @@ -62,8 +66,10 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { let mut lctx = LoweringContext { // Pseudo-globals. sess: &self.sess, + definitions: self.definitions, + cstore: self.cstore, + resolutions: self.resolutions, resolver: self.resolver, - nt_to_tokenstream: self.nt_to_tokenstream, arena: self.arena, // HirId handling. @@ -86,6 +92,8 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { task_context: None, current_item: None, captured_lifetimes: None, + impl_trait_defs: Vec::new(), + impl_trait_bounds: Vec::new(), allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()), allow_gen_future: Some([sym::gen_future][..].into()), allow_into_future: Some([sym::into_future][..].into()), @@ -118,9 +126,9 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { self.owners[def_id] } + #[instrument(level = "debug", skip(self, c))] fn lower_crate(&mut self, c: &Crate) { - debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID); - + debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID); self.with_lctx(CRATE_NODE_ID, |lctx| { let module = lctx.lower_mod(&c.items, &c.spans); lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs); @@ -128,15 +136,16 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { }) } + #[instrument(level = "debug", skip(self))] fn lower_item(&mut self, item: &Item) { self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item))) } fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) { - let def_id = self.resolver.local_def_id(item.id); + let def_id = self.resolver.node_id_to_def_id[&item.id]; let parent_id = { - let parent = self.resolver.definitions().def_key(def_id).parent; + let parent = self.definitions.def_key(def_id).parent; let local_def_index = parent.unwrap(); LocalDefId { local_def_index } }; @@ -177,7 +186,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> { - let mut node_ids = smallvec![hir::ItemId { def_id: self.resolver.local_def_id(i.id) }]; + let mut node_ids = smallvec![hir::ItemId { def_id: self.local_def_id(i.id) }]; if let ItemKind::Use(ref use_tree) = &i.kind { self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids); } @@ -193,7 +202,7 @@ impl<'hir> LoweringContext<'_, 'hir> { match tree.kind { UseTreeKind::Nested(ref nested_vec) => { for &(ref nested, id) in nested_vec { - vec.push(hir::ItemId { def_id: self.resolver.local_def_id(id) }); + vec.push(hir::ItemId { def_id: self.local_def_id(id) }); self.lower_item_id_use_tree(nested, id, vec); } } @@ -202,7 +211,7 @@ impl<'hir> LoweringContext<'_, 'hir> { for (_, &id) in iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2]) { - vec.push(hir::ItemId { def_id: self.resolver.local_def_id(id) }); + vec.push(hir::ItemId { def_id: self.local_def_id(id) }); } } } @@ -267,16 +276,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let body_id = this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref()); - let (generics, decl) = - this.add_implicit_generics(generics, id, |this, idty, idpb| { - let ret_id = asyncness.opt_return_id(); - this.lower_fn_decl( - &decl, - Some((id, idty, idpb)), - FnDeclKind::Fn, - ret_id, - ) - }); + let itctx = ImplTraitContext::Universal; + let (generics, decl) = this.lower_generics(generics, id, itctx, |this| { + let ret_id = asyncness.opt_return_id(); + this.lower_fn_decl(&decl, Some(id), FnDeclKind::Fn, ret_id) + }); let sig = hir::FnSig { decl, header: this.lower_fn_header(header), @@ -314,57 +318,59 @@ impl<'hir> LoweringContext<'_, 'hir> { // // type Foo = Foo1 // opaque type Foo1: Trait - let ty = self.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy); let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, where_clauses, true); - let generics = self.lower_generics( + let (generics, ty) = self.lower_generics( &generics, + id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| this.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy), ); hir::ItemKind::TyAlias(ty, generics) } ItemKind::TyAlias(box TyAlias { ref generics, ref where_clauses, ty: None, .. }) => { - let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err)); let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, *where_clauses, true); - let generics = self.lower_generics( + let (generics, ty) = self.lower_generics( &generics, + id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| this.arena.alloc(this.ty(span, hir::TyKind::Err)), ); hir::ItemKind::TyAlias(ty, generics) } - ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum( - hir::EnumDef { - variants: self.arena.alloc_from_iter( - enum_definition.variants.iter().map(|x| self.lower_variant(x)), - ), - }, - self.lower_generics( + ItemKind::Enum(ref enum_definition, ref generics) => { + let (generics, variants) = self.lower_generics( generics, + id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - ), + |this| { + this.arena.alloc_from_iter( + enum_definition.variants.iter().map(|x| this.lower_variant(x)), + ) + }, + ); + hir::ItemKind::Enum(hir::EnumDef { variants }, generics) + } ItemKind::Struct(ref struct_def, ref generics) => { - let struct_def = self.lower_variant_data(hir_id, struct_def); - hir::ItemKind::Struct( - struct_def, - self.lower_generics( - generics, - ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - ) + let (generics, struct_def) = self.lower_generics( + generics, + id, + ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| this.lower_variant_data(hir_id, struct_def), + ); + hir::ItemKind::Struct(struct_def, generics) } ItemKind::Union(ref vdata, ref generics) => { - let vdata = self.lower_variant_data(hir_id, vdata); - hir::ItemKind::Union( - vdata, - self.lower_generics( - generics, - ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - ) + let (generics, vdata) = self.lower_generics( + generics, + id, + ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| this.lower_variant_data(hir_id, vdata), + ); + hir::ItemKind::Union(vdata, generics) } ItemKind::Impl(box Impl { unsafety, @@ -389,8 +395,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // method, it will not be considered an in-band // lifetime to be added, but rather a reference to a // parent lifetime. + let itctx = ImplTraitContext::Universal; let (generics, (trait_ref, lowered_ty)) = - self.add_implicit_generics(ast_generics, id, |this, _, _| { + self.lower_generics(ast_generics, id, itctx, |this| { let trait_ref = trait_ref.as_ref().map(|trait_ref| { this.lower_trait_ref( trait_ref, @@ -435,37 +442,41 @@ impl<'hir> LoweringContext<'_, 'hir> { ref bounds, ref items, }) => { - let bounds = self.lower_param_bounds( - bounds, - ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + let (generics, (unsafety, items, bounds)) = self.lower_generics( + generics, + id, + ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| { + let bounds = this.lower_param_bounds( + bounds, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + ); + let items = this.arena.alloc_from_iter( + items.iter().map(|item| this.lower_trait_item_ref(item)), + ); + let unsafety = this.lower_unsafety(unsafety); + (unsafety, items, bounds) + }, ); - let items = self - .arena - .alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item))); - hir::ItemKind::Trait( - is_auto, - self.lower_unsafety(unsafety), - self.lower_generics( - generics, - ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - bounds, - items, - ) + hir::ItemKind::Trait(is_auto, unsafety, generics, bounds, items) } - ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias( - self.lower_generics( + ItemKind::TraitAlias(ref generics, ref bounds) => { + let (generics, bounds) = self.lower_generics( generics, + id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - self.lower_param_bounds( - bounds, - ImplTraitContext::Disallowed(ImplTraitPosition::Bound), - ), - ), + |this| { + this.lower_param_bounds( + bounds, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + ) + }, + ); + hir::ItemKind::TraitAlias(generics, bounds) + } ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { let body = P(self.lower_mac_args(body)); - let macro_kind = self.resolver.decl_macro_kind(self.resolver.local_def_id(id)); + let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id)); hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind) } ItemKind::MacCall(..) => { @@ -484,6 +495,7 @@ impl<'hir> LoweringContext<'_, 'hir> { (ty, self.lower_const_body(span, body)) } + #[instrument(level = "debug", skip(self))] fn lower_use_tree( &mut self, tree: &UseTree, @@ -493,8 +505,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ident: &mut Ident, attrs: Option<&'hir [Attribute]>, ) -> hir::ItemKind<'hir> { - debug!("lower_use_tree(tree={:?})", tree); - let path = &tree.prefix; let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect(); @@ -526,7 +536,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Essentially a single `use` which imports two names is desugared into // two imports. for new_node_id in [id1, id2] { - let new_id = self.resolver.local_def_id(new_node_id); + let new_id = self.local_def_id(new_node_id); let Some(res) = resolutions.next() else { // Associate an HirId to both ids even if there is no resolution. let _old = self.children.insert( @@ -539,7 +549,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let ident = *ident; let mut path = path.clone(); for seg in &mut path.segments { - seg.id = self.resolver.next_node_id(); + seg.id = self.next_node_id(); } let span = path.span; @@ -602,13 +612,13 @@ impl<'hir> LoweringContext<'_, 'hir> { // Add all the nested `PathListItem`s to the HIR. for &(ref use_tree, id) in trees { - let new_hir_id = self.resolver.local_def_id(id); + let new_hir_id = self.local_def_id(id); let mut prefix = prefix.clone(); // Give the segments new node-ids since they are being cloned. for seg in &mut prefix.segments { - seg.id = self.resolver.next_node_id(); + seg.id = self.next_node_id(); } // Each `use` import is an item and thus are owners of the @@ -654,8 +664,9 @@ impl<'hir> LoweringContext<'_, 'hir> { kind: match i.kind { ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => { let fdec = &sig.decl; + let itctx = ImplTraitContext::Universal; let (generics, (fn_dec, fn_args)) = - self.add_implicit_generics(generics, i.id, |this, _, _| { + self.lower_generics(generics, i.id, itctx, |this| { ( // Disallow `impl Trait` in foreign items. this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None), @@ -681,7 +692,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef { hir::ForeignItemRef { - id: hir::ForeignItemId { def_id: self.resolver.local_def_id(i.id) }, + id: hir::ForeignItemId { def_id: self.local_def_id(i.id) }, ident: self.lower_ident(i.ident), span: self.lower_span(i.span), } @@ -792,24 +803,25 @@ impl<'hir> LoweringContext<'_, 'hir> { ref ty, .. }) => { - let ty = ty.as_ref().map(|x| { - self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type)) - }); let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, where_clauses, false); - let generics = self.lower_generics( + self.lower_generics( &generics, + i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ); - let kind = hir::TraitItemKind::Type( - self.lower_param_bounds( - bounds, - ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - ty, - ); - - (generics, kind) + |this| { + let ty = ty.as_ref().map(|x| { + this.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type)) + }); + hir::TraitItemKind::Type( + this.lower_param_bounds( + bounds, + ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + ), + ty, + ) + }, + ) } AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"), }; @@ -836,7 +848,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } AssocItemKind::MacCall(..) => unimplemented!(), }; - let id = hir::TraitItemId { def_id: self.resolver.local_def_id(i.id) }; + let id = hir::TraitItemId { def_id: self.local_def_id(i.id) }; let defaultness = hir::Defaultness::Default { has_value: has_default }; hir::TraitItemRef { id, @@ -848,7 +860,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } /// Construct `ExprKind::Err` for the given `span`. - crate fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> { + pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> { self.expr(span, hir::ExprKind::Err, AttrVec::new()) } @@ -879,21 +891,21 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => { let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, *where_clauses, false); - let generics = self.lower_generics( + self.lower_generics( &generics, + i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ); - let kind = match ty { - None => { - let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err)); - hir::ImplItemKind::TyAlias(ty) - } - Some(ty) => { - let ty = self.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy); - hir::ImplItemKind::TyAlias(ty) - } - }; - (generics, kind) + |this| match ty { + None => { + let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err)); + hir::ImplItemKind::TyAlias(ty) + } + Some(ty) => { + let ty = this.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy); + hir::ImplItemKind::TyAlias(ty) + } + }, + ) } AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"), }; @@ -916,7 +928,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let has_value = true; let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); hir::ImplItemRef { - id: hir::ImplItemId { def_id: self.resolver.local_def_id(i.id) }, + id: hir::ImplItemId { def_id: self.local_def_id(i.id) }, ident: self.lower_ident(i.ident), span: self.lower_span(i.span), defaultness, @@ -1234,8 +1246,9 @@ impl<'hir> LoweringContext<'_, 'hir> { is_async: Option, ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) { let header = self.lower_fn_header(sig.header); - let (generics, decl) = self.add_implicit_generics(generics, id, |this, idty, idpb| { - this.lower_fn_decl(&sig.decl, Some((id, idty, idpb)), kind, is_async) + let itctx = ImplTraitContext::Universal; + let (generics, decl) = self.lower_generics(generics, id, itctx, |this| { + this.lower_fn_decl(&sig.decl, Some(id), kind, is_async) }); (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) }) } @@ -1292,11 +1305,19 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - pub(super) fn lower_generics_mut( + /// Return the pair of the lowered `generics` as `hir::Generics` and the evaluation of `f` with + /// the carried impl trait definitions and bounds. + #[instrument(level = "debug", skip(self, f))] + fn lower_generics( &mut self, generics: &Generics, - mut itctx: ImplTraitContext<'_, 'hir>, - ) -> GenericsCtor<'hir> { + parent_node_id: NodeId, + itctx: ImplTraitContext, + f: impl FnOnce(&mut Self) -> T, + ) -> (&'hir hir::Generics<'hir>, T) { + debug_assert!(self.impl_trait_defs.is_empty()); + debug_assert!(self.impl_trait_bounds.is_empty()); + // Error if `?Trait` bounds in where clauses don't refer directly to type parameters. // Note: we used to clone these bounds directly onto the type parameter (and avoid lowering // these into hir when we lower thee where clauses), but this makes it quite difficult to @@ -1319,7 +1340,7 @@ impl<'hir> LoweringContext<'_, 'hir> { generics .params .iter() - .any(|p| def_id == self.resolver.local_def_id(p.id).to_def_id()) + .any(|p| def_id == self.local_def_id(p.id).to_def_id()) } // Either the `bounded_ty` is not a plain type parameter, or // it's not found in the generic type parameters list. @@ -1344,9 +1365,9 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - let mut predicates = SmallVec::new(); + let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new(); predicates.extend(generics.params.iter().filter_map(|param| { - let bounds = self.lower_param_bounds(¶m.bounds, itctx.reborrow()); + let bounds = self.lower_param_bounds(¶m.bounds, itctx); self.lower_generic_bound_predicate( param.ident, param.id, @@ -1363,22 +1384,35 @@ impl<'hir> LoweringContext<'_, 'hir> { .map(|predicate| self.lower_where_predicate(predicate)), ); - GenericsCtor { - params: self.lower_generic_params_mut(&generics.params).collect(), - predicates, - has_where_clause: !generics.where_clause.predicates.is_empty(), - where_clause_span: self.lower_span(generics.where_clause.span), - span: self.lower_span(generics.span), - } - } + let mut params: SmallVec<[hir::GenericParam<'hir>; 4]> = + self.lower_generic_params_mut(&generics.params).collect(); - pub(super) fn lower_generics( - &mut self, - generics: &Generics, - itctx: ImplTraitContext<'_, 'hir>, - ) -> &'hir hir::Generics<'hir> { - let generics_ctor = self.lower_generics_mut(generics, itctx); - generics_ctor.into_generics(self.arena) + // Introduce extra lifetimes if late resolution tells us to. + let extra_lifetimes = self.resolver.take_extra_lifetime_params(parent_node_id); + params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| { + self.lifetime_res_to_generic_param(ident, node_id, res) + })); + + let has_where_clause_predicates = !generics.where_clause.predicates.is_empty(); + let where_clause_span = self.lower_span(generics.where_clause.span); + let span = self.lower_span(generics.span); + let res = f(self); + + let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs); + params.extend(impl_trait_defs.into_iter()); + + let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds); + predicates.extend(impl_trait_bounds.into_iter()); + + let lowered_generics = self.arena.alloc(hir::Generics { + params: self.arena.alloc_from_iter(params), + predicates: self.arena.alloc_from_iter(predicates), + has_where_clause_predicates, + where_clause_span, + span, + }); + + (lowered_generics, res) } pub(super) fn lower_generic_bound_predicate( @@ -1413,7 +1447,7 @@ impl<'hir> LoweringContext<'_, 'hir> { match kind { GenericParamKind::Const { .. } => None, GenericParamKind::Type { .. } => { - let def_id = self.resolver.local_def_id(id).to_def_id(); + let def_id = self.local_def_id(id).to_def_id(); let ty_path = self.arena.alloc(hir::Path { span: param_span, res: Res::Def(DefKind::TyParam, def_id), @@ -1436,7 +1470,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let res = self.resolver.get_lifetime_res(id).unwrap_or_else(|| { panic!("Missing resolution for lifetime {:?} at {:?}", id, ident.span) }); - let lt_id = self.resolver.next_node_id(); + let lt_id = self.next_node_id(); let lifetime = self.new_named_lifetime_with_res(lt_id, ident_span, ident, res); Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { lifetime, @@ -1494,24 +1528,3 @@ impl<'hir> LoweringContext<'_, 'hir> { } } } - -/// Helper struct for delayed construction of Generics. -pub(super) struct GenericsCtor<'hir> { - pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>, - pub(super) predicates: SmallVec<[hir::WherePredicate<'hir>; 4]>, - has_where_clause: bool, - where_clause_span: Span, - span: Span, -} - -impl<'hir> GenericsCtor<'hir> { - pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> &'hir hir::Generics<'hir> { - arena.alloc(hir::Generics { - params: arena.alloc_from_iter(self.params), - predicates: arena.alloc_from_iter(self.predicates), - has_where_clause: self.has_where_clause, - where_clause_span: self.where_clause_span, - span: self.span, - }) - } -} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c143266f6c..cab2de0ced 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -30,7 +30,6 @@ //! get confused if the spans from leaf AST nodes occur in multiple places //! in the HIR, especially for multiple identifiers. -#![feature(crate_visibility_modifier)] #![feature(box_patterns)] #![feature(let_chains)] #![feature(let_else)] @@ -38,7 +37,9 @@ #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] -use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream}; +#[macro_use] +extern crate tracing; + use rustc_ast::visit; use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust; @@ -48,25 +49,25 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; -use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res}; -use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID}; -use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; +use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; +use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; +use rustc_hir::definitions::{DefPathData, Definitions}; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; use rustc_index::vec::{Idx, IndexVec}; +use rustc_middle::ty::{ResolverAstLowering, ResolverOutputs}; use rustc_query_system::ich::StableHashingContext; +use rustc_session::cstore::CrateStoreDyn; use rustc_session::parse::feature_err; -use rustc_session::utils::{FlattenNonterminals, NtToTokenstream}; use rustc_session::Session; -use rustc_span::hygiene::{ExpnId, MacroKind}; +use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use smallvec::SmallVec; use std::collections::hash_map::Entry; -use tracing::{debug, trace}; macro_rules! arena_vec { ($this:expr; $($x:expr),*) => ( @@ -88,12 +89,10 @@ struct LoweringContext<'a, 'hir: 'a> { /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes. sess: &'a Session, - resolver: &'a mut dyn ResolverAstLowering, - - /// HACK(Centril): there is a cyclic dependency between the parser and lowering - /// if we don't have this function pointer. To avoid that dependency so that - /// `rustc_middle` is independent of the parser, we use dynamic dispatch here. - nt_to_tokenstream: NtToTokenstream, + definitions: &'a mut Definitions, + cstore: &'a CrateStoreDyn, + resolutions: &'a ResolverOutputs, + resolver: &'a mut ResolverAstLowering, /// Used to allocate HIR nodes. arena: &'hir Arena<'hir>, @@ -129,6 +128,9 @@ struct LoweringContext<'a, 'hir: 'a> { local_id_to_def_id: SortedMap, trait_map: FxHashMap>, + impl_trait_defs: Vec>, + impl_trait_bounds: Vec>, + /// NodeIds that are lowered inside the current HIR owner. node_id_to_local_id: FxHashMap, @@ -137,46 +139,6 @@ struct LoweringContext<'a, 'hir: 'a> { allow_into_future: Option>, } -/// Resolution for a lifetime appearing in a type. -#[derive(Copy, Clone, Debug)] -pub enum LifetimeRes { - /// Successfully linked the lifetime to a generic parameter. - Param { - /// Id of the generic parameter that introduced it. - param: LocalDefId, - /// Id of the introducing place. That can be: - /// - an item's id, for the item's generic parameters; - /// - a TraitRef's ref_id, identifying the `for<...>` binder; - /// - a BareFn type's id; - /// - a Path's id when this path has parenthesized generic args. - /// - /// This information is used for impl-trait lifetime captures, to know when to or not to - /// capture any given lifetime. - binder: NodeId, - }, - /// Created a generic parameter for an anonymous lifetime. - Fresh { - /// Id of the generic parameter that introduced it. - param: LocalDefId, - /// Id of the introducing place. See `Param`. - binder: NodeId, - }, - /// This variant is used for anonymous lifetimes that we did not resolve during - /// late resolution. Shifting the work to the HIR lifetime resolver. - Anonymous { - /// Id of the introducing place. See `Param`. - binder: NodeId, - /// Whether this lifetime was spelled or elided. - elided: bool, - }, - /// Explicit `'static` lifetime. - Static, - /// Resolution failure. - Error, - /// HACK: This is used to recover the NodeId of an elided lifetime. - ElidedAnchor { start: NodeId, end: NodeId }, -} - /// When we lower a lifetime, it is inserted in `captures`, and the resolution is modified so /// to point to the lifetime parameter impl-trait will generate. /// When traversing `for<...>` binders, they are inserted in `binders_to_ignore` so we know *not* @@ -199,66 +161,93 @@ struct LifetimeCaptureContext { binders_to_ignore: FxHashSet, } -pub trait ResolverAstLowering { - fn def_key(&self, id: DefId) -> DefKey; - - fn def_span(&self, id: LocalDefId) -> Span; - - fn item_generics_num_lifetimes(&self, def: DefId) -> usize; - - fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option>; - - /// Obtains resolution for a `NodeId` with a single resolution. +trait ResolverAstLoweringExt { + fn legacy_const_generic_args(&self, expr: &Expr) -> Option>; fn get_partial_res(&self, id: NodeId) -> Option; - - /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`. fn get_import_res(&self, id: NodeId) -> PerNS>>; - - /// Obtains resolution for a label with the given `NodeId`. fn get_label_res(&self, id: NodeId) -> Option; - - /// Obtains resolution for a lifetime with the given `NodeId`. fn get_lifetime_res(&self, id: NodeId) -> Option; - - /// Obtain the list of lifetimes parameters to add to an item. fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>; + fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind; +} + +impl ResolverAstLoweringExt for ResolverAstLowering { + fn legacy_const_generic_args(&self, expr: &Expr) -> Option> { + if let ExprKind::Path(None, path) = &expr.kind { + // Don't perform legacy const generics rewriting if the path already + // has generic arguments. + if path.segments.last().unwrap().args.is_some() { + return None; + } - fn create_stable_hashing_context(&self) -> StableHashingContext<'_>; + let partial_res = self.partial_res_map.get(&expr.id)?; + if partial_res.unresolved_segments() != 0 { + return None; + } - fn definitions(&self) -> &Definitions; + if let Res::Def(DefKind::Fn, def_id) = partial_res.base_res() { + // We only support cross-crate argument rewriting. Uses + // within the same crate should be updated to use the new + // const generics style. + if def_id.is_local() { + return None; + } - fn next_node_id(&mut self) -> NodeId; + if let Some(v) = self.legacy_const_generic_args.get(&def_id) { + return v.clone(); + } + } + } - fn take_trait_map(&mut self, node: NodeId) -> Option>; + None + } - fn opt_local_def_id(&self, node: NodeId) -> Option; + /// Obtains resolution for a `NodeId` with a single resolution. + fn get_partial_res(&self, id: NodeId) -> Option { + self.partial_res_map.get(&id).copied() + } - fn local_def_id(&self, node: NodeId) -> LocalDefId; + /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`. + fn get_import_res(&self, id: NodeId) -> PerNS>> { + self.import_res_map.get(&id).copied().unwrap_or_default() + } - fn def_path_hash(&self, def_id: DefId) -> DefPathHash; + /// Obtains resolution for a label with the given `NodeId`. + fn get_label_res(&self, id: NodeId) -> Option { + self.label_res_map.get(&id).copied() + } - fn create_def( - &mut self, - parent: LocalDefId, - node_id: ast::NodeId, - data: DefPathData, - expn_id: ExpnId, - span: Span, - ) -> LocalDefId; + /// Obtains resolution for a lifetime with the given `NodeId`. + fn get_lifetime_res(&self, id: NodeId) -> Option { + self.lifetimes_res_map.get(&id).copied() + } - fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind; + /// Obtain the list of lifetimes parameters to add to an item. + /// + /// Extra lifetime parameters should only be added in places that can appear + /// as a `binder` in `LifetimeRes`. + /// + /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring + /// should appear at the enclosing `PolyTraitRef`. + fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> { + self.extra_lifetime_params_map.remove(&id).unwrap_or_default() + } + + fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind { + self.builtin_macro_kinds.get(&def_id).copied().unwrap_or(MacroKind::Bang) + } } /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree, /// and if so, what meaning it has. -#[derive(Debug)] -enum ImplTraitContext<'b, 'a> { +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +enum ImplTraitContext { /// Treat `impl Trait` as shorthand for a new universal generic parameter. /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually /// equivalent to a fresh universal parameter like `fn foo(x: T)`. /// /// Newly generated parameters should be inserted into the given `Vec`. - Universal(&'b mut Vec>, &'b mut Vec>, LocalDefId), + Universal, /// Treat `impl Trait` as shorthand for a new opaque type. /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually @@ -298,18 +287,6 @@ enum ImplTraitPosition { ImplReturn, } -impl<'a> ImplTraitContext<'_, 'a> { - fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> { - use self::ImplTraitContext::*; - match self { - Universal(params, bounds, parent) => Universal(params, bounds, *parent), - ReturnPositionOpaqueTy { origin } => ReturnPositionOpaqueTy { origin: *origin }, - TypeAliasesOpaqueTy => TypeAliasesOpaqueTy, - Disallowed(pos) => Disallowed(*pos), - } - } -} - impl std::fmt::Display for ImplTraitPosition { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let name = match self { @@ -368,17 +345,17 @@ enum AstOwner<'a> { } fn index_crate<'a>( - resolver: &dyn ResolverAstLowering, + node_id_to_def_id: &FxHashMap, krate: &'a Crate, ) -> IndexVec> { - let mut indexer = Indexer { resolver, index: IndexVec::new() }; + let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() }; indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner); indexer.index[CRATE_DEF_ID] = AstOwner::Crate(krate); visit::walk_crate(&mut indexer, krate); return indexer.index; struct Indexer<'s, 'a> { - resolver: &'s dyn ResolverAstLowering, + node_id_to_def_id: &'s FxHashMap, index: IndexVec>, } @@ -389,21 +366,21 @@ fn index_crate<'a>( } fn visit_item(&mut self, item: &'a ast::Item) { - let def_id = self.resolver.local_def_id(item.id); + let def_id = self.node_id_to_def_id[&item.id]; self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); self.index[def_id] = AstOwner::Item(item); visit::walk_item(self, item) } fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) { - let def_id = self.resolver.local_def_id(item.id); + let def_id = self.node_id_to_def_id[&item.id]; self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); self.index[def_id] = AstOwner::AssocItem(item, ctxt); visit::walk_assoc_item(self, item, ctxt); } fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) { - let def_id = self.resolver.local_def_id(item.id); + let def_id = self.node_id_to_def_id[&item.id]; self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); self.index[def_id] = AstOwner::ForeignItem(item); visit::walk_foreign_item(self, item); @@ -414,44 +391,51 @@ fn index_crate<'a>( /// Compute the hash for the HIR of the full crate. /// This hash will then be part of the crate_hash which is stored in the metadata. fn compute_hir_hash( - resolver: &mut dyn ResolverAstLowering, + sess: &Session, + definitions: &Definitions, + cstore: &CrateStoreDyn, + resolver: &ResolverOutputs, owners: &IndexVec>>, ) -> Fingerprint { let mut hir_body_nodes: Vec<_> = owners .iter_enumerated() .filter_map(|(def_id, info)| { let info = info.as_owner()?; - let def_path_hash = resolver.definitions().def_path_hash(def_id); + let def_path_hash = definitions.def_path_hash(def_id); Some((def_path_hash, info)) }) .collect(); hir_body_nodes.sort_unstable_by_key(|bn| bn.0); let mut stable_hasher = StableHasher::new(); - let mut hcx = resolver.create_stable_hashing_context(); + let mut hcx = StableHashingContext::new(sess, definitions, cstore, &resolver.source_span); hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher); stable_hasher.finish() } -pub fn lower_crate<'a, 'hir>( - sess: &'a Session, - krate: &'a Crate, - resolver: &'a mut dyn ResolverAstLowering, - nt_to_tokenstream: NtToTokenstream, +pub fn lower_crate<'hir>( + sess: &Session, + krate: &Crate, + definitions: &mut Definitions, + cstore: &CrateStoreDyn, + resolutions: &ResolverOutputs, + mut resolver: ResolverAstLowering, arena: &'hir Arena<'hir>, ) -> &'hir hir::Crate<'hir> { let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering"); - let ast_index = index_crate(resolver, krate); + let ast_index = index_crate(&resolver.node_id_to_def_id, krate); let mut owners = - IndexVec::from_fn_n(|_| hir::MaybeOwner::Phantom, resolver.definitions().def_index_count()); + IndexVec::from_fn_n(|_| hir::MaybeOwner::Phantom, definitions.def_index_count()); for def_id in ast_index.indices() { item::ItemLowerer { sess, - resolver, - nt_to_tokenstream, + definitions, + cstore, + resolutions, + resolver: &mut resolver, arena, ast_index: &ast_index, owners: &mut owners, @@ -459,12 +443,12 @@ pub fn lower_crate<'a, 'hir>( .lower_node(def_id); } - let hir_hash = compute_hir_hash(resolver, &owners); + let hir_hash = compute_hir_hash(sess, definitions, cstore, resolutions, &owners); let krate = hir::Crate { owners, hir_hash }; arena.alloc(krate) } -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, PartialEq, Debug)] enum ParamMode { /// Any path in a type context. Explicit, @@ -480,12 +464,64 @@ enum ParenthesizedGenericArgs { } impl<'a, 'hir> LoweringContext<'a, 'hir> { + fn create_stable_hashing_context(&self) -> StableHashingContext<'_> { + StableHashingContext::new( + self.sess, + self.definitions, + self.cstore, + &self.resolutions.source_span, + ) + } + + fn create_def( + &mut self, + parent: LocalDefId, + node_id: ast::NodeId, + data: DefPathData, + ) -> LocalDefId { + assert!( + self.opt_local_def_id(node_id).is_none(), + "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}", + node_id, + data, + self.definitions.def_key(self.local_def_id(node_id)), + ); + + let def_id = self.definitions.create_def(parent, data); + + // Some things for which we allocate `LocalDefId`s don't correspond to + // anything in the AST, so they don't have a `NodeId`. For these cases + // we don't need a mapping from `NodeId` to `LocalDefId`. + if node_id != ast::DUMMY_NODE_ID { + debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); + self.resolver.node_id_to_def_id.insert(node_id, def_id); + } + + def_id + } + + fn next_node_id(&mut self) -> NodeId { + let start = self.resolver.next_node_id; + let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds"); + self.resolver.next_node_id = ast::NodeId::from_u32(next); + start + } + + fn opt_local_def_id(&self, node: NodeId) -> Option { + self.resolver.node_id_to_def_id.get(&node).copied() + } + + fn local_def_id(&self, node: NodeId) -> LocalDefId { + self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node)) + } + + #[instrument(level = "debug", skip(self, f))] fn with_hir_id_owner( &mut self, owner: NodeId, f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>, ) { - let def_id = self.resolver.local_def_id(owner); + let def_id = self.local_def_id(owner); let current_attrs = std::mem::take(&mut self.attrs); let current_bodies = std::mem::take(&mut self.bodies); @@ -495,6 +531,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id); let current_local_counter = std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1)); + let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs); + let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds); + // Do not reset `next_node_id` and `node_id_to_def_id` as we want to refer to the + // subdefinitions' nodes. // Always allocate the first `HirId` for the owner itself. let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::new(0)); @@ -502,6 +542,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let item = f(self); debug_assert_eq!(def_id, item.def_id()); + // `f` should have consumed all the elements in these vectors when constructing `item`. + debug_assert!(self.impl_trait_defs.is_empty()); + debug_assert!(self.impl_trait_bounds.is_empty()); let info = self.make_owner_info(item); self.attrs = current_attrs; @@ -511,6 +554,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.trait_map = current_trait_map; self.current_hir_id_owner = current_owner; self.item_local_id_counter = current_local_counter; + self.impl_trait_defs = current_impl_trait_defs; + self.impl_trait_bounds = current_impl_trait_bounds; let _old = self.children.insert(def_id, hir::MaybeOwner::Owner(info)); debug_assert!(_old.is_none()) @@ -533,8 +578,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bodies.sort_by_key(|(k, _)| *k); let bodies = SortedMap::from_presorted_elements(bodies); let (hash_including_bodies, hash_without_bodies) = self.hash_owner(node, &bodies); - let (nodes, parenting) = - index::index_hir(self.sess, self.resolver.definitions(), node, &bodies); + let (nodes, parenting) = index::index_hir(self.sess, self.definitions, node, &bodies); let nodes = hir::OwnerNodes { hash_including_bodies, hash_without_bodies, @@ -543,7 +587,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { local_id_to_def_id, }; let attrs = { - let mut hcx = self.resolver.create_stable_hashing_context(); + let mut hcx = self.create_stable_hashing_context(); let mut stable_hasher = StableHasher::new(); attrs.hash_stable(&mut hcx, &mut stable_hasher); let hash = stable_hasher.finish(); @@ -560,7 +604,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { node: hir::OwnerNode<'hir>, bodies: &SortedMap>, ) -> (Fingerprint, Fingerprint) { - let mut hcx = self.resolver.create_stable_hashing_context(); + let mut hcx = self.create_stable_hashing_context(); let mut stable_hasher = StableHasher::new(); hcx.with_hir_bodies(true, node.def_id(), bodies, |hcx| { node.hash_stable(hcx, &mut stable_hasher) @@ -597,13 +641,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.item_local_id_counter.increment_by(1); assert_ne!(local_id, hir::ItemLocalId::new(0)); - if let Some(def_id) = self.resolver.opt_local_def_id(ast_node_id) { + if let Some(def_id) = self.opt_local_def_id(ast_node_id) { // Do not override a `MaybeOwner::Owner` that may already here. self.children.entry(def_id).or_insert(hir::MaybeOwner::NonOwner(hir_id)); self.local_id_to_def_id.insert(local_id, def_id); } - if let Some(traits) = self.resolver.take_trait_map(ast_node_id) { + if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) { self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice()); } @@ -613,16 +657,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn next_id(&mut self) -> hir::HirId { - let node_id = self.resolver.next_node_id(); + let node_id = self.next_node_id(); self.lower_node_id(node_id) } + #[instrument(level = "trace", skip(self))] fn lower_res(&mut self, res: Res) -> Res { let res: Result = res.apply_id(|id| { let owner = self.current_hir_id_owner; let local_id = self.node_id_to_local_id.get(&id).copied().ok_or(())?; Ok(hir::HirId { owner, local_id }) }); + trace!(?res); + // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner. // This can happen when trying to lower the return type `x` in erroneous code like // async fn foo(x: u8) -> x {} @@ -660,7 +707,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { allow_internal_unstable, reason, self.sess.edition(), - self.resolver.create_stable_hashing_context(), + self.create_stable_hashing_context(), ) } @@ -680,6 +727,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } /// Converts a lifetime into a new generic parameter. + #[tracing::instrument(level = "debug", skip(self))] fn lifetime_res_to_generic_param( &mut self, ident: Ident, @@ -691,7 +739,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit) } LifetimeRes::Fresh { param, .. } => { - (hir::ParamName::Fresh(param), hir::LifetimeParamKind::Elided) + // Late resolution delegates to us the creation of the `LocalDefId`. + let _def_id = self.create_def( + self.current_hir_id_owner, + param, + DefPathData::LifetimeNs(kw::UnderscoreLifetime), + ); + debug!(?_def_id); + + (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided) } LifetimeRes::Static | LifetimeRes::Error => return None, res => panic!( @@ -710,46 +766,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) } - /// Creates a new `hir::GenericParam` for every new `Fresh` lifetime and - /// universal `impl Trait` type parameter encountered while evaluating `f`. - /// Definitions are created with the provided `parent_def_id`. - fn add_implicit_generics( - &mut self, - generics: &Generics, - parent_node_id: NodeId, - f: impl FnOnce( - &mut Self, - &mut Vec>, - &mut Vec>, - ) -> T, - ) -> (&'hir hir::Generics<'hir>, T) { - let mut impl_trait_defs = Vec::new(); - let mut impl_trait_bounds = Vec::new(); - let mut lowered_generics = self.lower_generics_mut( - generics, - ImplTraitContext::Universal( - &mut impl_trait_defs, - &mut impl_trait_bounds, - self.current_hir_id_owner, - ), - ); - let res = f(self, &mut impl_trait_defs, &mut impl_trait_bounds); - - let extra_lifetimes = self.resolver.take_extra_lifetime_params(parent_node_id); - lowered_generics.params.extend( - extra_lifetimes - .into_iter() - .filter_map(|(ident, node_id, res)| { - self.lifetime_res_to_generic_param(ident, node_id, res) - }) - .chain(impl_trait_defs), - ); - lowered_generics.predicates.extend(impl_trait_bounds); - - let lowered_generics = lowered_generics.into_generics(self.arena); - (lowered_generics, res) - } - /// Setup lifetime capture for and impl-trait. /// The captures will be added to `captures`. fn while_capturing_lifetimes( @@ -778,11 +794,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Register a binder to be ignored for lifetime capture. #[tracing::instrument(level = "debug", skip(self, f))] #[inline] - fn with_lifetime_binder(&mut self, binder: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { + fn with_lifetime_binder( + &mut self, + binder: NodeId, + generic_params: &[GenericParam], + f: impl FnOnce(&mut Self, &'hir [hir::GenericParam<'hir>]) -> T, + ) -> T { + let mut generic_params: Vec<_> = self.lower_generic_params_mut(generic_params).collect(); + let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder); + debug!(?extra_lifetimes); + generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| { + self.lifetime_res_to_generic_param(ident, node_id, res) + })); + let generic_params = self.arena.alloc_from_iter(generic_params); + debug!(?generic_params); + if let Some(ctxt) = &mut self.captured_lifetimes { ctxt.binders_to_ignore.insert(binder); } - let ret = f(self); + let ret = f(self, generic_params); if let Some(ctxt) = &mut self.captured_lifetimes { ctxt.binders_to_ignore.remove(&binder); } @@ -876,11 +906,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // ``` // // In both cases, we don't want to synthesize any tokens - MacArgs::Delimited( - dspan, - delim, - self.lower_token_stream(tokens.clone(), CanSynthesizeMissingTokens::No), - ) + MacArgs::Delimited(dspan, delim, tokens.flattened()) } // This is an inert key-value attribute - it will never be visible to macros // after it gets lowered to HIR. Therefore, we can extract literals to handle @@ -905,19 +931,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_token_stream( - &self, - tokens: TokenStream, - synthesize_tokens: CanSynthesizeMissingTokens, - ) -> TokenStream { - FlattenNonterminals { - parse_sess: &self.sess.parse_sess, - synthesize_tokens, - nt_to_tokenstream: self.nt_to_tokenstream, - } - .process_token_stream(tokens) - } - /// Given an associated type constraint like one of these: /// /// ```ignore (illustrative) @@ -928,35 +941,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// ``` /// /// returns a `hir::TypeBinding` representing `Item`. + #[instrument(level = "debug", skip(self))] fn lower_assoc_ty_constraint( &mut self, constraint: &AssocConstraint, - mut itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::TypeBinding<'hir> { debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); - // lower generic arguments of identifier in constraint let gen_args = if let Some(ref gen_args) = constraint.gen_args { let gen_args_ctor = match gen_args { GenericArgs::AngleBracketed(ref data) => { - self.lower_angle_bracketed_parameter_data( - data, - ParamMode::Explicit, - itctx.reborrow(), - ) - .0 + self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } GenericArgs::Parenthesized(ref data) => { - let mut err = self.sess.struct_span_err( - gen_args.span(), - "parenthesized generic arguments cannot be used in associated type constraints" - ); - // FIXME: try to write a suggestion here - err.emit(); + self.emit_bad_parenthesized_trait_in_assoc_ty(data); self.lower_angle_bracketed_parameter_data( &data.as_angle_bracketed_args(), ParamMode::Explicit, - itctx.reborrow(), + itctx, ) .0 } @@ -975,7 +978,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBindingKind::Equality { term } } AssocConstraintKind::Bound { ref bounds } => { - let mut parent_def_id = self.current_hir_id_owner; // Piggy-back on the `impl Trait` context to figure out the correct behavior. let (desugar_to_impl_trait, itctx) = match itctx { // We are in the return position: @@ -995,10 +997,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so desugar to // // fn foo(x: dyn Iterator) - ImplTraitContext::Universal(_, _, parent) if self.is_in_dyn_type => { - parent_def_id = parent; - (true, itctx) - } + ImplTraitContext::Universal if self.is_in_dyn_type => (true, itctx), // In `type Foo = dyn Iterator` we desugar to // `type Foo = dyn Iterator` but we have to override the @@ -1024,17 +1023,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by // constructing the HIR for `impl bounds...` and then lowering that. - let impl_trait_node_id = self.resolver.next_node_id(); - self.resolver.create_def( - parent_def_id, - impl_trait_node_id, - DefPathData::ImplTrait, - ExpnId::root(), - constraint.span, - ); + let parent_def_id = self.current_hir_id_owner; + let impl_trait_node_id = self.next_node_id(); + self.create_def(parent_def_id, impl_trait_node_id, DefPathData::ImplTrait); self.with_dyn_type_scope(false, |this| { - let node_id = this.resolver.next_node_id(); + let node_id = this.next_node_id(); let ty = this.lower_ty( &Ty { id: node_id, @@ -1066,10 +1060,47 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } + fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) { + let mut err = self.sess.struct_span_err( + data.span, + "parenthesized generic arguments cannot be used in associated type constraints", + ); + // Suggest removing empty parentheses: "Trait()" -> "Trait" + if data.inputs.is_empty() { + let parentheses_span = + data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi()); + err.multipart_suggestion( + "remove these parentheses", + vec![(parentheses_span, String::new())], + Applicability::MaybeIncorrect, + ); + } + // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait` + else { + // Start of parameters to the 1st argument + let open_param = data.inputs_span.shrink_to_lo().to(data + .inputs + .first() + .unwrap() + .span + .shrink_to_lo()); + // End of last argument to end of parameters + let close_param = + data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi()); + err.multipart_suggestion( + &format!("use angle brackets instead",), + vec![(open_param, String::from("<")), (close_param, String::from(">"))], + Applicability::MaybeIncorrect, + ); + } + err.emit(); + } + + #[instrument(level = "debug", skip(self))] fn lower_generic_arg( &mut self, arg: &ast::GenericArg, - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::GenericArg<'hir> { match arg { ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), @@ -1097,16 +1128,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Construct an AnonConst where the expr is the "ty"'s path. let parent_def_id = self.current_hir_id_owner; - let node_id = self.resolver.next_node_id(); + let node_id = self.next_node_id(); // Add a definition for the in-band const def. - self.resolver.create_def( - parent_def_id, - node_id, - DefPathData::AnonConst, - ExpnId::root(), - ty.span, - ); + self.create_def(parent_def_id, node_id, DefPathData::AnonConst); let span = self.lower_span(ty.span); let path_expr = Expr { @@ -1136,7 +1161,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_, 'hir>) -> &'hir hir::Ty<'hir> { + #[instrument(level = "debug", skip(self))] + fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> { self.arena.alloc(self.lower_ty_direct(t, itctx)) } @@ -1146,8 +1172,35 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { qself: &Option, path: &Path, param_mode: ParamMode, - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::Ty<'hir> { + // Check whether we should interpret this as a bare trait object. + // This check mirrors the one in late resolution. We only introduce this special case in + // the rare occurence we need to lower `Fresh` anonymous lifetimes. + // The other cases when a qpath should be opportunistically made a trait object are handled + // by `ty_path`. + if qself.is_none() + && let Some(partial_res) = self.resolver.get_partial_res(t.id) + && partial_res.unresolved_segments() == 0 + && let Res::Def(DefKind::Trait | DefKind::TraitAlias, _) = partial_res.base_res() + { + let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| { + let bound = this.lower_poly_trait_ref( + &PolyTraitRef { + bound_generic_params: vec![], + trait_ref: TraitRef { path: path.clone(), ref_id: t.id }, + span: t.span + }, + itctx, + ); + let bounds = this.arena.alloc_from_iter([bound]); + let lifetime_bound = this.elided_dyn_bound(t.span); + (bounds, lifetime_bound) + }); + let kind = hir::TyKind::TraitObject(bounds, lifetime_bound, TraitObjectSyntax::None); + return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() }; + } + let id = self.lower_node_id(t.id); let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx); self.ty_path(id, t.span, qpath) @@ -1161,7 +1214,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.ty(span, hir::TyKind::Tup(tys)) } - fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_, 'hir>) -> hir::Ty<'hir> { + fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> { let kind = match t.kind { TyKind::Infer => hir::TyKind::Infer, TyKind::Err => hir::TyKind::Err, @@ -1169,34 +1222,35 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), TyKind::Rptr(ref region, ref mt) => { let region = region.unwrap_or_else(|| { - let Some(LifetimeRes::ElidedAnchor { start, end }) = self.resolver.get_lifetime_res(t.id) else { - panic!() + let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) = + self.resolver.get_lifetime_res(t.id) + { + debug_assert_eq!(start.plus(1), end); + start + } else { + self.next_node_id() }; - debug_assert_eq!(start.plus(1), end); let span = self.sess.source_map().next_point(t.span.shrink_to_lo()); - Lifetime { - ident: Ident::new(kw::UnderscoreLifetime, span), - id: start, - } + Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id } }); let lifetime = self.lower_lifetime(®ion); hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx)) } - TyKind::BareFn(ref f) => self.with_lifetime_binder(t.id, |this| { - hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy { - generic_params: this.lower_generic_params(&f.generic_params), - unsafety: this.lower_unsafety(f.unsafety), - abi: this.lower_extern(f.ext), - decl: this.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None), - param_names: this.lower_fn_params_to_names(&f.decl), - })) - }), - TyKind::Never => hir::TyKind::Never, - TyKind::Tup(ref tys) => { - hir::TyKind::Tup(self.arena.alloc_from_iter( - tys.iter().map(|ty| self.lower_ty_direct(ty, itctx.reborrow())), - )) + TyKind::BareFn(ref f) => { + self.with_lifetime_binder(t.id, &f.generic_params, |this, generic_params| { + hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy { + generic_params, + unsafety: this.lower_unsafety(f.unsafety), + abi: this.lower_extern(f.ext), + decl: this.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None), + param_names: this.lower_fn_params_to_names(&f.decl), + })) + }) } + TyKind::Never => hir::TyKind::Never, + TyKind::Tup(ref tys) => hir::TyKind::Tup( + self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))), + ), TyKind::Paren(ref ty) => { return self.lower_ty_direct(ty, itctx); } @@ -1230,7 +1284,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericBound::Trait( ref ty, TraitBoundModifier::None | TraitBoundModifier::MaybeConst, - ) => Some(this.lower_poly_trait_ref(ty, itctx.reborrow())), + ) => Some(this.lower_poly_trait_ref(ty, itctx)), // `~const ?Bound` will cause an error during AST validation // anyways, so treat it like `?Bound` as compilation proceeds. GenericBound::Trait( @@ -1267,50 +1321,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { |this| this.lower_param_bounds(bounds, nested_itctx), ) } - ImplTraitContext::Universal( - in_band_ty_params, - in_band_ty_bounds, - parent_def_id, - ) => { - // Add a definition for the in-band `Param`. - let def_id = self.resolver.local_def_id(def_node_id); - - let hir_bounds = self.lower_param_bounds( - bounds, - ImplTraitContext::Universal( - in_band_ty_params, - in_band_ty_bounds, - parent_def_id, - ), - ); - // Set the name to `impl Bound1 + Bound2`. + ImplTraitContext::Universal => { + let span = t.span; let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span); - in_band_ty_params.push(hir::GenericParam { - hir_id: self.lower_node_id(def_node_id), - name: ParamName::Plain(self.lower_ident(ident)), - pure_wrt_drop: false, - span: self.lower_span(span), - kind: hir::GenericParamKind::Type { default: None, synthetic: true }, - colon_span: None, - }); - if let Some(preds) = self.lower_generic_bound_predicate( - ident, - def_node_id, - &GenericParamKind::Type { default: None }, - hir_bounds, - hir::PredicateOrigin::ImplTrait, - ) { - in_band_ty_bounds.push(preds) + let (param, bounds, path) = + self.lower_generic_and_bounds(def_node_id, span, ident, bounds); + self.impl_trait_defs.push(param); + if let Some(bounds) = bounds { + self.impl_trait_bounds.push(bounds); } - - hir::TyKind::Path(hir::QPath::Resolved( - None, - self.arena.alloc(hir::Path { - span: self.lower_span(span), - res: Res::Def(DefKind::TyParam, def_id.to_def_id()), - segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident))], - }), - )) + path } ImplTraitContext::Disallowed(position) => { let mut err = struct_span_err!( @@ -1353,7 +1373,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id); + let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id); let mut collected_lifetimes = FxHashMap::default(); self.with_hir_id_owner(opaque_ty_node_id, |lctx| { @@ -1371,7 +1391,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lifetime_defs = lctx.arena.alloc_from_iter(collected_lifetimes.iter().map( |(_, &(span, p_id, p_name, _))| { let hir_id = lctx.lower_node_id(p_id); - debug_assert_ne!(lctx.resolver.opt_local_def_id(p_id), None); + debug_assert_ne!(lctx.opt_local_def_id(p_id), None); let kind = if p_name.ident().name == kw::UnderscoreLifetime { hir::LifetimeParamKind::Elided @@ -1396,7 +1416,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { generics: self.arena.alloc(hir::Generics { params: lifetime_defs, predicates: &[], - has_where_clause: false, + has_where_clause_predicates: false, where_clause_span: lctx.lower_span(span), span: lctx.lower_span(span), }), @@ -1410,7 +1430,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lifetimes = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map( |(_, (span, _, p_name, res))| { - let id = self.resolver.next_node_id(); + let id = self.next_node_id(); let ident = Ident::new(p_name.ident().name, span); let l = self.new_named_lifetime_with_res(id, span, ident, res); hir::GenericArg::Lifetime(l) @@ -1471,26 +1491,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future` in the // return type. This is used for `async fn` declarations. The `NodeId` is the ID of the // return type `impl Trait` item. + #[tracing::instrument(level = "debug", skip(self))] fn lower_fn_decl( &mut self, decl: &FnDecl, - mut in_band_ty_params: Option<( - NodeId, - &mut Vec>, - &mut Vec>, - )>, + fn_node_id: Option, kind: FnDeclKind, make_ret_async: Option, ) -> &'hir hir::FnDecl<'hir> { - debug!( - "lower_fn_decl(\ - fn_decl: {:?}, \ - in_band_ty_params: {:?}, \ - kind: {:?}, \ - make_ret_async: {:?})", - decl, in_band_ty_params, kind, make_ret_async, - ); - let c_variadic = decl.c_variadic(); // Skip the `...` (`CVarArgs`) trailing arguments from the AST, @@ -1501,11 +1509,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs = &inputs[..inputs.len() - 1]; } let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| { - if let Some((_, ibty, ibpb)) = &mut in_band_ty_params { - self.lower_ty_direct( - ¶m.ty, - ImplTraitContext::Universal(ibty, ibpb, self.current_hir_id_owner), - ) + if fn_node_id.is_some() { + self.lower_ty_direct(¶m.ty, ImplTraitContext::Universal) } else { self.lower_ty_direct( ¶m.ty, @@ -1526,15 +1531,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let output = if let Some(ret_id) = make_ret_async { self.lower_async_fn_ret_ty( &decl.output, - in_band_ty_params.expect("`make_ret_async` but no `fn_def_id`").0, + fn_node_id.expect("`make_ret_async` but no `fn_def_id`"), ret_id, ) } else { match decl.output { FnRetTy::Ty(ref ty) => { - let context = match in_band_ty_params { - Some((node_id, _, _)) if kind.impl_trait_return_allowed() => { - let fn_def_id = self.resolver.local_def_id(node_id); + let context = match fn_node_id { + Some(fn_node_id) if kind.impl_trait_return_allowed() => { + let fn_def_id = self.local_def_id(fn_node_id); ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), } @@ -1608,8 +1613,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None); - let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id); - let fn_def_id = self.resolver.local_def_id(fn_node_id); + let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id); + let fn_def_id = self.local_def_id(fn_node_id); // When we create the opaque type for this async fn, it is going to have // to capture all the lifetimes involved in the signature (including in the @@ -1659,17 +1664,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { debug!(?extra_lifetime_params); for (ident, outer_node_id, outer_res) in extra_lifetime_params { let Ident { name, span } = ident; - let outer_def_id = self.resolver.local_def_id(outer_node_id); - let inner_node_id = self.resolver.next_node_id(); + let outer_def_id = self.local_def_id(outer_node_id); + let inner_node_id = self.next_node_id(); // Add a definition for the in scope lifetime def. - self.resolver.create_def( - opaque_ty_def_id, - inner_node_id, - DefPathData::LifetimeNs(name), - ExpnId::root(), - span.with_parent(None), - ); + self.create_def(opaque_ty_def_id, inner_node_id, DefPathData::LifetimeNs(name)); let (p_name, inner_res) = match outer_res { // Input lifetime like `'a`: @@ -1677,10 +1676,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(ident), LifetimeRes::Param { param, binder: fn_node_id }) } // Input lifetime like `'1`: - LifetimeRes::Fresh { param, .. } => ( - hir::ParamName::Fresh(outer_def_id), - LifetimeRes::Fresh { param, binder: fn_node_id }, - ), + LifetimeRes::Fresh { param, .. } => { + (hir::ParamName::Fresh, LifetimeRes::Fresh { param, binder: fn_node_id }) + } LifetimeRes::Static | LifetimeRes::Error => continue, res => { panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span) @@ -1711,7 +1709,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let generic_params = this.arena.alloc_from_iter(captures.iter().map(|(_, &(span, p_id, p_name, _))| { let hir_id = this.lower_node_id(p_id); - debug_assert_ne!(this.resolver.opt_local_def_id(p_id), None); + debug_assert_ne!(this.opt_local_def_id(p_id), None); let kind = if p_name.ident().name == kw::UnderscoreLifetime { hir::LifetimeParamKind::Elided @@ -1734,7 +1732,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { generics: this.arena.alloc(hir::Generics { params: generic_params, predicates: &[], - has_where_clause: false, + has_where_clause_predicates: false, where_clause_span: this.lower_span(span), span: this.lower_span(span), }), @@ -1763,7 +1761,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // generate `'_`. let generic_args = self.arena.alloc_from_iter(captures.into_iter().map(|(_, (span, _, p_name, res))| { - let id = self.resolver.next_node_id(); + let id = self.next_node_id(); let ident = Ident::new(p_name.ident().name, span); let l = self.new_named_lifetime_with_res(id, span, ident, res); hir::GenericArg::Lifetime(l) @@ -1817,10 +1815,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } + #[instrument(level = "trace", skip(self))] fn lower_param_bound( &mut self, tpb: &GenericBound, - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::GenericBound<'hir> { match tpb { GenericBound::Trait(p, modifier) => hir::GenericBound::Trait( @@ -1836,10 +1835,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime { let span = self.lower_span(l.ident.span); let ident = self.lower_ident(l.ident); - let res = self - .resolver - .get_lifetime_res(l.id) - .unwrap_or_else(|| panic!("Missing resolution for lifetime {:?} at {:?}", l, span)); + let res = self.resolver.get_lifetime_res(l.id).unwrap_or(LifetimeRes::Error); self.new_named_lifetime_with_res(l.id, span, ident, res) } @@ -1853,88 +1849,85 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::Lifetime { debug!(?self.captured_lifetimes); let name = match res { - LifetimeRes::Param { param, binder } => { + LifetimeRes::Param { mut param, binder } => { debug_assert_ne!(ident.name, kw::UnderscoreLifetime); let p_name = ParamName::Plain(ident); - if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) = - &mut self.captured_lifetimes - && !binders_to_ignore.contains(&binder) - { - match captures.entry(param) { - Entry::Occupied(_) => {} - Entry::Vacant(v) => { - let p_id = self.resolver.next_node_id(); - self.resolver.create_def( - *parent_def_id, - p_id, - DefPathData::LifetimeNs(p_name.ident().name), - ExpnId::root(), - span.with_parent(None), - ); - - v.insert((span, p_id, p_name, res)); + if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() { + if !captured_lifetimes.binders_to_ignore.contains(&binder) { + match captured_lifetimes.captures.entry(param) { + Entry::Occupied(o) => param = self.local_def_id(o.get().1), + Entry::Vacant(v) => { + let p_id = self.next_node_id(); + let p_def_id = self.create_def( + captured_lifetimes.parent_def_id, + p_id, + DefPathData::LifetimeNs(p_name.ident().name), + ); + + v.insert((span, p_id, p_name, res)); + param = p_def_id; + } } } + + self.captured_lifetimes = Some(captured_lifetimes); } - hir::LifetimeName::Param(p_name) + hir::LifetimeName::Param(param, p_name) } - LifetimeRes::Fresh { mut param, binder } => { + LifetimeRes::Fresh { param, binder } => { debug_assert_eq!(ident.name, kw::UnderscoreLifetime); - if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) = - &mut self.captured_lifetimes - && !binders_to_ignore.contains(&binder) - { - match captures.entry(param) { - Entry::Occupied(o) => param = self.resolver.local_def_id(o.get().1), - Entry::Vacant(v) => { - let p_id = self.resolver.next_node_id(); - let p_def_id = self.resolver.create_def( - *parent_def_id, - p_id, - DefPathData::LifetimeNs(kw::UnderscoreLifetime), - ExpnId::root(), - span.with_parent(None), - ); - - let p_name = ParamName::Fresh(param); - v.insert((span, p_id, p_name, res)); - param = p_def_id; + let mut param = self.local_def_id(param); + if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() { + if !captured_lifetimes.binders_to_ignore.contains(&binder) { + match captured_lifetimes.captures.entry(param) { + Entry::Occupied(o) => param = self.local_def_id(o.get().1), + Entry::Vacant(v) => { + let p_id = self.next_node_id(); + let p_def_id = self.create_def( + captured_lifetimes.parent_def_id, + p_id, + DefPathData::LifetimeNs(kw::UnderscoreLifetime), + ); + + v.insert((span, p_id, ParamName::Fresh, res)); + param = p_def_id; + } } } + + self.captured_lifetimes = Some(captured_lifetimes); } - let p_name = ParamName::Fresh(param); - hir::LifetimeName::Param(p_name) + hir::LifetimeName::Param(param, ParamName::Fresh) } LifetimeRes::Anonymous { binder, elided } => { - let l_name = if elided { + let mut l_name = None; + if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() { + if !captured_lifetimes.binders_to_ignore.contains(&binder) { + let p_id = self.next_node_id(); + let p_def_id = self.create_def( + captured_lifetimes.parent_def_id, + p_id, + DefPathData::LifetimeNs(kw::UnderscoreLifetime), + ); + captured_lifetimes + .captures + .insert(p_def_id, (span, p_id, ParamName::Fresh, res)); + l_name = Some(hir::LifetimeName::Param(p_def_id, ParamName::Fresh)); + } + self.captured_lifetimes = Some(captured_lifetimes); + }; + l_name.unwrap_or(if elided { hir::LifetimeName::Implicit } else { hir::LifetimeName::Underscore - }; - if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) = - &mut self.captured_lifetimes - && !binders_to_ignore.contains(&binder) - { - let p_id = self.resolver.next_node_id(); - let p_def_id = self.resolver.create_def( - *parent_def_id, - p_id, - DefPathData::LifetimeNs(kw::UnderscoreLifetime), - ExpnId::root(), - span.with_parent(None), - ); - let p_name = ParamName::Fresh(p_def_id); - captures.insert(p_def_id, (span, p_id, p_name, res)); - hir::LifetimeName::Param(p_name) - } else { - l_name - } + }) } LifetimeRes::Static => hir::LifetimeName::Static, LifetimeRes::Error => hir::LifetimeName::Error, res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span), }; debug!(?self.captured_lifetimes); + debug!(?name); hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name } } @@ -1949,17 +1942,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc_from_iter(self.lower_generic_params_mut(params)) } + #[instrument(level = "trace", skip(self))] fn lower_generic_param(&mut self, param: &GenericParam) -> hir::GenericParam<'hir> { - let (name, kind) = match param.kind { + let (name, kind) = self.lower_generic_param_kind(param); + + let hir_id = self.lower_node_id(param.id); + self.lower_attrs(hir_id, ¶m.attrs); + hir::GenericParam { + hir_id, + name, + span: self.lower_span(param.span()), + pure_wrt_drop: self.sess.contains_name(¶m.attrs, sym::may_dangle), + kind, + colon_span: param.colon_span.map(|s| self.lower_span(s)), + } + } + + fn lower_generic_param_kind( + &mut self, + param: &GenericParam, + ) -> (hir::ParamName, hir::GenericParamKind<'hir>) { + match param.kind { GenericParamKind::Lifetime => { - let param_name = if param.ident.name == kw::StaticLifetime - || param.ident.name == kw::UnderscoreLifetime - { - ParamName::Error - } else { - let ident = self.lower_ident(param.ident); - ParamName::Plain(ident) - }; + // AST resolution emitted an error on those parameters, so we lower them using + // `ParamName::Error`. + let param_name = + if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) { + ParamName::Error + } else { + let ident = self.lower_ident(param.ident); + ParamName::Plain(ident) + }; let kind = hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }; @@ -1983,29 +1996,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::GenericParamKind::Const { ty, default }, ) } - }; - let name = match name { - hir::ParamName::Plain(ident) => hir::ParamName::Plain(self.lower_ident(ident)), - name => name, - }; - - let hir_id = self.lower_node_id(param.id); - self.lower_attrs(hir_id, ¶m.attrs); - hir::GenericParam { - hir_id, - name, - span: self.lower_span(param.span()), - pure_wrt_drop: self.sess.contains_name(¶m.attrs, sym::may_dangle), - kind, - colon_span: param.colon_span.map(|s| self.lower_span(s)), } } - fn lower_trait_ref( - &mut self, - p: &TraitRef, - itctx: ImplTraitContext<'_, 'hir>, - ) -> hir::TraitRef<'hir> { + fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::TraitRef<'hir> { let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) { hir::QPath::Resolved(None, path) => path, qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath), @@ -2017,25 +2011,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_poly_trait_ref( &mut self, p: &PolyTraitRef, - mut itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::PolyTraitRef<'hir> { - let bound_generic_params = self.lower_generic_params(&p.bound_generic_params); - - let trait_ref = self.with_lifetime_binder(p.trait_ref.ref_id, |this| { - this.lower_trait_ref(&p.trait_ref, itctx.reborrow()) - }); - - hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) } + self.with_lifetime_binder( + p.trait_ref.ref_id, + &p.bound_generic_params, + |this, bound_generic_params| { + let trait_ref = this.lower_trait_ref(&p.trait_ref, itctx); + hir::PolyTraitRef { bound_generic_params, trait_ref, span: this.lower_span(p.span) } + }, + ) } - fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_, 'hir>) -> hir::MutTy<'hir> { + fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> { hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl } } fn lower_param_bounds( &mut self, bounds: &[GenericBound], - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::GenericBounds<'hir> { self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx)) } @@ -2043,9 +2038,50 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_param_bounds_mut<'s>( &'s mut self, bounds: &'s [GenericBound], - mut itctx: ImplTraitContext<'s, 'hir>, + itctx: ImplTraitContext, ) -> impl Iterator> + Captures<'s> + Captures<'a> { - bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx.reborrow())) + bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx)) + } + + fn lower_generic_and_bounds( + &mut self, + node_id: NodeId, + span: Span, + ident: Ident, + bounds: &[GenericBound], + ) -> (hir::GenericParam<'hir>, Option>, hir::TyKind<'hir>) { + // Add a definition for the in-band `Param`. + let def_id = self.local_def_id(node_id); + + let hir_bounds = self.lower_param_bounds(bounds, ImplTraitContext::Universal); + // Set the name to `impl Bound1 + Bound2`. + let param = hir::GenericParam { + hir_id: self.lower_node_id(node_id), + name: ParamName::Plain(self.lower_ident(ident)), + pure_wrt_drop: false, + span: self.lower_span(span), + kind: hir::GenericParamKind::Type { default: None, synthetic: true }, + colon_span: None, + }; + + let preds = self.lower_generic_bound_predicate( + ident, + node_id, + &GenericParamKind::Type { default: None }, + hir_bounds, + hir::PredicateOrigin::ImplTrait, + ); + + let ty = hir::TyKind::Path(hir::QPath::Resolved( + None, + self.arena.alloc(hir::Path { + span: self.lower_span(span), + res: Res::Def(DefKind::TyParam, def_id.to_def_id()), + segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident))], + }), + )); + + (param, preds, ty) } /// Lowers a block directly to an expression, presuming that it diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 2c331767b8..bd2e76e552 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -1,6 +1,6 @@ -use crate::ImplTraitPosition; - +use super::ResolverAstLoweringExt; use super::{ImplTraitContext, LoweringContext, ParamMode}; +use crate::ImplTraitPosition; use rustc_ast::ptr::P; use rustc_ast::*; @@ -12,11 +12,11 @@ use rustc_span::symbol::Ident; use rustc_span::{source_map::Spanned, Span}; impl<'a, 'hir> LoweringContext<'a, 'hir> { - crate fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> { + pub(crate) fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> { self.arena.alloc(self.lower_pat_mut(pattern)) } - crate fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> { + pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> { ensure_sufficient_stack(|| { // loop here to avoid recursion let node = loop { @@ -139,7 +139,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .span_suggestion_verbose( sp, &format!("if you don't need to use the contents of {}, discard the tuple's remaining fields", ident), - "..".to_string(), + "..", Applicability::MaybeIncorrect, ) .emit(); @@ -290,7 +290,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern. - crate fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) { + pub(crate) fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) { self.diagnostic() .struct_span_err(sp, &format!("`..` can only be used once per {} pattern", ctx)) .span_label(sp, &format!("can only be used once per {} pattern", ctx)) diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 3c9399c1fd..52ba5daf01 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -1,5 +1,6 @@ use crate::ImplTraitPosition; +use super::ResolverAstLoweringExt; use super::{GenericArgsCtor, LifetimeRes, ParenthesizedGenericArgs}; use super::{ImplTraitContext, LoweringContext, ParamMode}; @@ -15,17 +16,17 @@ use smallvec::smallvec; use tracing::debug; impl<'a, 'hir> LoweringContext<'a, 'hir> { - crate fn lower_qpath( + #[instrument(level = "trace", skip(self))] + pub(crate) fn lower_qpath( &mut self, id: NodeId, qself: &Option, p: &Path, param_mode: ParamMode, - mut itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::QPath<'hir> { - debug!("lower_qpath(id: {:?}, qself: {:?}, p: {:?})", id, qself, p); let qself_position = qself.as_ref().map(|q| q.position); - let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow())); + let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx)); let partial_res = self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); @@ -70,7 +71,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { segment, param_mode, parenthesized_generic_args, - itctx.reborrow(), + itctx, ) }, )), @@ -116,7 +117,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { segment, param_mode, ParenthesizedGenericArgs::Err, - itctx.reborrow(), + itctx, )); let qpath = hir::QPath::TypeRelative(ty, hir_segment); @@ -142,7 +143,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); } - crate fn lower_path_extra( + pub(crate) fn lower_path_extra( &mut self, res: Res, p: &Path, @@ -163,7 +164,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) } - crate fn lower_path( + pub(crate) fn lower_path( &mut self, id: NodeId, p: &Path, @@ -174,13 +175,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_path_extra(res, p, param_mode) } - crate fn lower_path_segment( + pub(crate) fn lower_path_segment( &mut self, path_span: Span, segment: &PathSegment, param_mode: ParamMode, parenthesized_generic_args: ParenthesizedGenericArgs, - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::PathSegment<'hir> { debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,); let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args { @@ -190,31 +191,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) } GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { - ParenthesizedGenericArgs::Ok => { - self.lower_parenthesized_parameter_data(segment.id, data) - } + ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), ParenthesizedGenericArgs::Err => { let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); err.span_label(data.span, "only `Fn` traits may use parentheses"); - if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) { - // Do not suggest going from `Trait()` to `Trait<>` - if !data.inputs.is_empty() { - // Suggest replacing `(` and `)` with `<` and `>` - // The snippet may be missing the closing `)`, skip that case - if snippet.ends_with(')') { - if let Some(split) = snippet.find('(') { - let trait_name = &snippet[0..split]; - let args = &snippet[split + 1..snippet.len() - 1]; - err.span_suggestion( - data.span, - "use angle brackets instead", - format!("{}<{}>", trait_name, args), - Applicability::MaybeIncorrect, - ); - } - } - } - }; + // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait` + if !data.inputs.is_empty() { + // Start of the span to the 1st character of 1st argument + let open_param = data.inputs_span.shrink_to_lo().to(data + .inputs + .first() + .unwrap() + .span + .shrink_to_lo()); + // Last character position of last argument to the end of the span + let close_param = data + .inputs + .last() + .unwrap() + .span + .shrink_to_hi() + .to(data.inputs_span.shrink_to_hi()); + err.multipart_suggestion( + &format!("use angle brackets instead",), + vec![ + (open_param, String::from("<")), + (close_param, String::from(">")), + ], + Applicability::MaybeIncorrect, + ); + } err.emit(); ( self.lower_angle_bracketed_parameter_data( @@ -318,7 +324,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, data: &AngleBracketedArgs, param_mode: ParamMode, - mut itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> (GenericArgsCtor<'hir>, bool) { let has_non_lt_args = data.args.iter().any(|arg| match arg { AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_)) @@ -329,14 +335,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .args .iter() .filter_map(|arg| match arg { - AngleBracketedArg::Arg(arg) => Some(self.lower_generic_arg(arg, itctx.reborrow())), + AngleBracketedArg::Arg(arg) => Some(self.lower_generic_arg(arg, itctx)), AngleBracketedArg::Constraint(_) => None, }) .collect(); let bindings = self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg { - AngleBracketedArg::Constraint(c) => { - Some(self.lower_assoc_ty_constraint(c, itctx.reborrow())) - } + AngleBracketedArg::Constraint(c) => Some(self.lower_assoc_ty_constraint(c, itctx)), AngleBracketedArg::Arg(_) => None, })); let ctor = GenericArgsCtor { args, bindings, parenthesized: false, span: data.span }; @@ -345,7 +349,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_parenthesized_parameter_data( &mut self, - id: NodeId, data: &ParenthesizedArgs, ) -> (GenericArgsCtor<'hir>, bool) { // Switch to `PassThrough` mode for anonymous lifetimes; this @@ -353,35 +356,31 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // a hidden lifetime parameter. This is needed for backwards // compatibility, even in contexts like an impl header where // we generally don't permit such things (see #51008). - self.with_lifetime_binder(id, |this| { - let ParenthesizedArgs { span, inputs, inputs_span, output } = data; - let inputs = this.arena.alloc_from_iter(inputs.iter().map(|ty| { - this.lower_ty_direct( - ty, - ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam), - ) - })); - let output_ty = match output { - FnRetTy::Ty(ty) => this - .lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)), - FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(*span, &[])), - }; - let args = smallvec![GenericArg::Type(this.ty_tup(*inputs_span, inputs))]; - let binding = this.output_ty_binding(output_ty.span, output_ty); - ( - GenericArgsCtor { - args, - bindings: arena_vec![this; binding], - parenthesized: true, - span: data.inputs_span, - }, - false, - ) - }) + let ParenthesizedArgs { span, inputs, inputs_span, output } = data; + let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| { + self.lower_ty_direct(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam)) + })); + let output_ty = match output { + FnRetTy::Ty(ty) => { + self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)) + } + FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])), + }; + let args = smallvec![GenericArg::Type(self.ty_tup(*inputs_span, inputs))]; + let binding = self.output_ty_binding(output_ty.span, output_ty); + ( + GenericArgsCtor { + args, + bindings: arena_vec![self; binding], + parenthesized: true, + span: data.inputs_span, + }, + false, + ) } /// An associated type binding `Output = $ty`. - crate fn output_ty_binding( + pub(crate) fn output_ty_binding( &mut self, span: Span, ty: &'hir hir::Ty<'hir>, diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 058a0f975a..503bdbad25 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -420,7 +420,15 @@ impl<'a> AstValidator<'a> { .iter() .flat_map(|i| i.attrs.as_ref()) .filter(|attr| { - let arr = [sym::allow, sym::cfg, sym::cfg_attr, sym::deny, sym::forbid, sym::warn]; + let arr = [ + sym::allow, + sym::cfg, + sym::cfg_attr, + sym::deny, + sym::expect, + sym::forbid, + sym::warn, + ]; !arr.contains(&attr.name_or_empty()) && rustc_attr::is_builtin_attr(attr) }) .for_each(|attr| { @@ -435,7 +443,7 @@ impl<'a> AstValidator<'a> { } else { self.err_handler().span_err( attr.span, - "allow, cfg, cfg_attr, deny, \ + "allow, cfg, cfg_attr, deny, expect, \ forbid, and warn are the only allowed built-in attributes in function parameters", ); } @@ -480,7 +488,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( replace_span, &format!("provide a definition for the {}", ctx), - sugg.to_string(), + sugg, Applicability::HasPlaceholders, ) .emit(); @@ -514,7 +522,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( span, &format!("remove the {}", remove_descr), - String::new(), + "", Applicability::MaybeIncorrect, ) .span_label(self.current_extern_span(), "`extern` block begins here") @@ -562,7 +570,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( body.span, "remove the invalid body", - ";".to_string(), + ";", Applicability::MaybeIncorrect, ) .help( @@ -591,7 +599,7 @@ impl<'a> AstValidator<'a> { .span_suggestion_verbose( span.until(ident.span.shrink_to_lo()), "remove the qualifiers", - "fn ".to_string(), + "fn ", Applicability::MaybeIncorrect, ) .emit(); @@ -695,7 +703,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( generics.span, "remove the parameters", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -713,7 +721,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( span, "remove the super traits or lifetime bounds", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -745,7 +753,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( total_span, "remove these associated items", - String::new(), + "", Applicability::MachineApplicable, ) .span_label(ident_span, "auto trait cannot have associated items") @@ -985,7 +993,7 @@ fn validate_generic_param_order( err.span_suggestion( span, "reorder the parameters: lifetimes, then consts and types", - ordered_params.clone(), + &ordered_params, Applicability::MachineApplicable, ); err.emit(); @@ -1070,7 +1078,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_label(self, label); } - fn visit_lifetime(&mut self, lifetime: &'a Lifetime) { + fn visit_lifetime(&mut self, lifetime: &'a Lifetime, _: visit::LifetimeCtxt) { self.check_lifetime(lifetime.ident); visit::walk_lifetime(self, lifetime); } @@ -1463,10 +1471,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let GenericBound::Trait(ref poly, modify) = *bound { match (ctxt, modify) { (BoundKind::SuperTraits, TraitBoundModifier::Maybe) => { - let mut err = self.err_handler().struct_span_err( - poly.span, - &format!("`?Trait` is not permitted in supertraits"), - ); + let mut err = self + .err_handler() + .struct_span_err(poly.span, "`?Trait` is not permitted in supertraits"); let path_str = pprust::path_to_string(&poly.trait_ref.path); err.note(&format!("traits are `?{}` by default", path_str)); err.emit(); @@ -1474,7 +1481,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { (BoundKind::TraitObject, TraitBoundModifier::Maybe) => { let mut err = self.err_handler().struct_span_err( poly.span, - &format!("`?Trait` is not permitted in trait object types"), + "`?Trait` is not permitted in trait object types", ); err.emit(); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 0e8af54969..37c4f66541 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -113,6 +113,14 @@ impl<'a> PostExpansionVisitor<'a> { "rust-call ABI is subject to change" ); } + "rust-cold" => { + gate_feature_post!( + &self, + rust_cold_cc, + span, + "rust-cold is experimental and subject to change" + ); + } "ptx-kernel" => { gate_feature_post!( &self, @@ -393,44 +401,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { let msg = "`#[doc(keyword)]` is meant for internal use only"; gate_feature_post!(self, rustdoc_internals, attr.span, msg); } - } - } - // Check for unstable modifiers on `#[link(..)]` attribute - if attr.has_name(sym::link) { - for nested_meta in attr.meta_item_list().unwrap_or_default() { - if nested_meta.has_name(sym::modifiers) { - if let Some(modifiers) = nested_meta.value_str() { - for modifier in modifiers.as_str().split(',') { - if let Some(modifier) = modifier.strip_prefix(&['+', '-']) { - macro_rules! gate_modifier { ($($name:literal => $feature:ident)*) => { - $(if modifier == $name { - let msg = concat!("`#[link(modifiers=\"", $name, "\")]` is unstable"); - gate_feature_post!( - self, - $feature, - nested_meta.name_value_literal_span().unwrap(), - msg - ); - })* - }} - - gate_modifier!( - "bundle" => native_link_modifiers_bundle - "verbatim" => native_link_modifiers_verbatim - "as-needed" => native_link_modifiers_as_needed - ); - } - } - } + if nested_meta.has_name(sym::tuple_variadic) { + let msg = "`#[doc(tuple_variadic)]` is meant for internal use only"; + gate_feature_post!(self, rustdoc_internals, attr.span, msg); } } } // Emit errors for non-staged-api crates. if !self.features.staged_api { - if attr.has_name(sym::rustc_deprecated) - || attr.has_name(sym::unstable) + if attr.has_name(sym::unstable) || attr.has_name(sym::stable) || attr.has_name(sym::rustc_const_unstable) || attr.has_name(sym::rustc_const_stable) @@ -728,18 +709,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } visit::walk_assoc_item(self, i, ctxt) } - - fn visit_vis(&mut self, vis: &'a ast::Visibility) { - if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.kind { - gate_feature_post!( - &self, - crate_visibility_modifier, - vis.span, - "`crate` visibility modifier is experimental" - ); - } - visit::walk_vis(self, vis) - } } pub fn check_crate(krate: &ast::Crate, sess: &Session) { @@ -801,7 +770,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { gate_all!(trait_alias, "trait aliases are experimental"); gate_all!(associated_type_bounds, "associated type bounds are unstable"); - gate_all!(crate_visibility_modifier, "`crate` visibility modifier is experimental"); gate_all!(decl_macro, "`macro` is experimental"); gate_all!(box_patterns, "box pattern syntax is experimental"); gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental"); @@ -859,7 +827,7 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) { err.span_suggestion( attr.span, "remove the attribute", - String::new(), + "", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index 48b79809c1..ee166f7570 100644 --- a/compiler/rustc_ast_passes/src/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs @@ -106,7 +106,7 @@ impl<'ast> Visitor<'ast> for NodeCounter { self.count += 1; walk_variant(self, v) } - fn visit_lifetime(&mut self, lifetime: &Lifetime) { + fn visit_lifetime(&mut self, lifetime: &Lifetime, _: visit::LifetimeCtxt) { self.count += 1; walk_lifetime(self, lifetime) } diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 95beccbb72..79178830bf 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -1,5 +1,4 @@ #![feature(associated_type_bounds)] -#![feature(crate_visibility_modifier)] #![feature(box_patterns)] #![feature(with_negative_coherence)] #![recursion_limit = "256"] diff --git a/compiler/rustc_ast_pretty/src/pprust/mod.rs b/compiler/rustc_ast_pretty/src/pprust/mod.rs index d2e2fd520c..ac9e7d06c4 100644 --- a/compiler/rustc_ast_pretty/src/pprust/mod.rs +++ b/compiler/rustc_ast_pretty/src/pprust/mod.rs @@ -4,42 +4,12 @@ mod tests; pub mod state; pub use state::{print_crate, AnnNode, Comments, PpAnn, PrintState, State}; +use rustc_ast as ast; use rustc_ast::token::{Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; -use rustc_ast::{self as ast, AstDeref}; use std::borrow::Cow; -pub trait AstPrettyPrint { - fn pretty_print(&self) -> String; -} - -impl> AstPrettyPrint for T { - fn pretty_print(&self) -> String { - self.ast_deref().pretty_print() - } -} - -macro_rules! impl_ast_pretty_print { - ($($T:ty => $method:ident),+ $(,)?) => { - $( - impl AstPrettyPrint for $T { - fn pretty_print(&self) -> String { - State::new().$method(self) - } - } - )+ - }; -} - -impl_ast_pretty_print! { - ast::Item => item_to_string, - ast::AssocItem => assoc_item_to_string, - ast::ForeignItem => foreign_item_to_string, - ast::Expr => expr_to_string, - ast::Stmt => stmt_to_string, -} - pub fn nonterminal_to_string(nt: &Nonterminal) -> String { State::new().nonterminal_to_string(nt) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 2fffa529d2..ad8dbfd506 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -95,7 +95,7 @@ pub struct State<'a> { ann: &'a (dyn PpAnn + 'a), } -crate const INDENT_UNIT: isize = 4; +pub(crate) const INDENT_UNIT: isize = 4; /// Requires you to pass an input filename and reader so that /// it can scan the input text for comments to copy forward. @@ -550,9 +550,9 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn print_tts(&mut self, tts: &TokenStream, convert_dollar_crate: bool) { let mut iter = tts.trees().peekable(); while let Some(tt) = iter.next() { - self.print_tt(&tt, convert_dollar_crate); + self.print_tt(tt, convert_dollar_crate); if let Some(next) = iter.peek() { - if tt_prepend_space(next, &tt) { + if tt_prepend_space(next, tt) { self.space(); } } @@ -814,7 +814,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } fn bounds_to_string(&self, bounds: &[ast::GenericBound]) -> String { - Self::to_string(|s| s.print_type_bounds("", bounds)) + Self::to_string(|s| s.print_type_bounds(bounds)) } fn pat_to_string(&self, pat: &ast::Pat) -> String { @@ -942,8 +942,13 @@ impl<'a> State<'a> { State { s: pp::Printer::new(), comments: None, ann: &NoAnn } } - crate fn commasep_cmnt(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G) - where + pub(crate) fn commasep_cmnt( + &mut self, + b: Breaks, + elts: &[T], + mut op: F, + mut get_span: G, + ) where F: FnMut(&mut State<'_>, &T), G: FnMut(&T) -> rustc_span::Span, { @@ -963,7 +968,7 @@ impl<'a> State<'a> { self.end(); } - crate fn commasep_exprs(&mut self, b: Breaks, exprs: &[P]) { + pub(crate) fn commasep_exprs(&mut self, b: Breaks, exprs: &[P]) { self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span) } @@ -986,7 +991,12 @@ impl<'a> State<'a> { Term::Const(c) => self.print_expr_anon_const(c, &[]), } } - ast::AssocConstraintKind::Bound { bounds } => self.print_type_bounds(":", &*bounds), + ast::AssocConstraintKind::Bound { bounds } => { + if !bounds.is_empty() { + self.word_nbsp(":"); + self.print_type_bounds(&bounds); + } + } } } @@ -1040,11 +1050,14 @@ impl<'a> State<'a> { } ast::TyKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, false), ast::TyKind::TraitObject(ref bounds, syntax) => { - let prefix = if syntax == ast::TraitObjectSyntax::Dyn { "dyn" } else { "" }; - self.print_type_bounds(prefix, &bounds); + if syntax == ast::TraitObjectSyntax::Dyn { + self.word_nbsp("dyn"); + } + self.print_type_bounds(bounds); } ast::TyKind::ImplTrait(_, ref bounds) => { - self.print_type_bounds("impl", &bounds); + self.word_nbsp("impl"); + self.print_type_bounds(bounds); } ast::TyKind::Array(ref ty, ref length) => { self.word("["); @@ -1096,7 +1109,7 @@ impl<'a> State<'a> { self.print_trait_ref(&t.trait_ref) } - crate fn print_stmt(&mut self, st: &ast::Stmt) { + pub(crate) fn print_stmt(&mut self, st: &ast::Stmt) { self.maybe_print_comment(st.span.lo()); match st.kind { ast::StmtKind::Local(ref loc) => { @@ -1151,19 +1164,19 @@ impl<'a> State<'a> { self.maybe_print_trailing_comment(st.span, None) } - crate fn print_block(&mut self, blk: &ast::Block) { + pub(crate) fn print_block(&mut self, blk: &ast::Block) { self.print_block_with_attrs(blk, &[]) } - crate fn print_block_unclosed_indent(&mut self, blk: &ast::Block) { + pub(crate) fn print_block_unclosed_indent(&mut self, blk: &ast::Block) { self.print_block_maybe_unclosed(blk, &[], false) } - crate fn print_block_with_attrs(&mut self, blk: &ast::Block, attrs: &[ast::Attribute]) { + pub(crate) fn print_block_with_attrs(&mut self, blk: &ast::Block, attrs: &[ast::Attribute]) { self.print_block_maybe_unclosed(blk, attrs, true) } - crate fn print_block_maybe_unclosed( + pub(crate) fn print_block_maybe_unclosed( &mut self, blk: &ast::Block, attrs: &[ast::Attribute], @@ -1197,7 +1210,7 @@ impl<'a> State<'a> { } /// Print a `let pat = expr` expression. - crate fn print_let(&mut self, pat: &ast::Pat, expr: &ast::Expr) { + pub(crate) fn print_let(&mut self, pat: &ast::Pat, expr: &ast::Expr) { self.word("let "); self.print_pat(pat); self.space(); @@ -1206,7 +1219,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren(expr, Self::cond_needs_par(expr) || npals()) } - crate fn print_mac(&mut self, m: &ast::MacCall) { + pub(crate) fn print_mac(&mut self, m: &ast::MacCall) { self.print_mac_common( Some(MacHeader::Path(&m.path)), true, @@ -1347,7 +1360,7 @@ impl<'a> State<'a> { self.pclose(); } - crate fn print_local_decl(&mut self, loc: &ast::Local) { + pub(crate) fn print_local_decl(&mut self, loc: &ast::Local) { self.print_pat(&loc.pat); if let Some(ref ty) = loc.ty { self.word_space(":"); @@ -1355,7 +1368,7 @@ impl<'a> State<'a> { } } - crate fn print_name(&mut self, name: Symbol) { + pub(crate) fn print_name(&mut self, name: Symbol) { self.word(name.to_string()); self.ann.post(self, AnnNode::Name(&name)) } @@ -1379,7 +1392,7 @@ impl<'a> State<'a> { } } - crate fn print_pat(&mut self, pat: &ast::Pat) { + pub(crate) fn print_pat(&mut self, pat: &ast::Pat) { self.maybe_print_comment(pat.span.lo()); self.ann.pre(self, AnnNode::Pat(pat)); /* Pat isn't normalized, but the beauty of it @@ -1538,64 +1551,51 @@ impl<'a> State<'a> { } } - crate fn print_asyncness(&mut self, asyncness: ast::Async) { + pub(crate) fn print_asyncness(&mut self, asyncness: ast::Async) { if asyncness.is_async() { self.word_nbsp("async"); } } - pub fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound]) { - if !bounds.is_empty() { - self.word(prefix); - let mut first = true; - for bound in bounds { - if !(first && prefix.is_empty()) { - self.nbsp(); - } - if first { - first = false; - } else { - self.word_space("+"); - } + pub fn print_type_bounds(&mut self, bounds: &[ast::GenericBound]) { + let mut first = true; + for bound in bounds { + if first { + first = false; + } else { + self.nbsp(); + self.word_space("+"); + } - match bound { - GenericBound::Trait(tref, modifier) => { - if modifier == &TraitBoundModifier::Maybe { - self.word("?"); - } - self.print_poly_trait_ref(tref); + match bound { + GenericBound::Trait(tref, modifier) => { + if modifier == &TraitBoundModifier::Maybe { + self.word("?"); } - GenericBound::Outlives(lt) => self.print_lifetime(*lt), + self.print_poly_trait_ref(tref); } + GenericBound::Outlives(lt) => self.print_lifetime(*lt), } } } - crate fn print_lifetime(&mut self, lifetime: ast::Lifetime) { + pub(crate) fn print_lifetime(&mut self, lifetime: ast::Lifetime) { self.print_name(lifetime.ident.name) } - crate fn print_lifetime_bounds( - &mut self, - lifetime: ast::Lifetime, - bounds: &ast::GenericBounds, - ) { - self.print_lifetime(lifetime); - if !bounds.is_empty() { - self.word(": "); - for (i, bound) in bounds.iter().enumerate() { - if i != 0 { - self.word(" + "); - } - match bound { - ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt), - _ => panic!(), - } + pub(crate) fn print_lifetime_bounds(&mut self, bounds: &ast::GenericBounds) { + for (i, bound) in bounds.iter().enumerate() { + if i != 0 { + self.word(" + "); + } + match bound { + ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt), + _ => panic!(), } } } - crate fn print_generic_params(&mut self, generic_params: &[ast::GenericParam]) { + pub(crate) fn print_generic_params(&mut self, generic_params: &[ast::GenericParam]) { if generic_params.is_empty() { return; } @@ -1608,11 +1608,18 @@ impl<'a> State<'a> { match param.kind { ast::GenericParamKind::Lifetime => { let lt = ast::Lifetime { id: param.id, ident: param.ident }; - s.print_lifetime_bounds(lt, ¶m.bounds) + s.print_lifetime(lt); + if !param.bounds.is_empty() { + s.word_nbsp(":"); + s.print_lifetime_bounds(¶m.bounds) + } } ast::GenericParamKind::Type { ref default } => { s.print_ident(param.ident); - s.print_type_bounds(":", ¶m.bounds); + if !param.bounds.is_empty() { + s.word_nbsp(":"); + s.print_type_bounds(¶m.bounds); + } if let Some(ref default) = default { s.space(); s.word_space("="); @@ -1625,7 +1632,10 @@ impl<'a> State<'a> { s.space(); s.word_space(":"); s.print_type(ty); - s.print_type_bounds(":", ¶m.bounds); + if !param.bounds.is_empty() { + s.word_nbsp(":"); + s.print_type_bounds(¶m.bounds); + } if let Some(ref default) = default { s.space(); s.word_space("="); @@ -1649,12 +1659,12 @@ impl<'a> State<'a> { } } - crate fn print_mt(&mut self, mt: &ast::MutTy, print_const: bool) { + pub(crate) fn print_mt(&mut self, mt: &ast::MutTy, print_const: bool) { self.print_mutability(mt.mutbl, print_const); self.print_type(&mt.ty) } - crate fn print_param(&mut self, input: &ast::Param, is_closure: bool) { + pub(crate) fn print_param(&mut self, input: &ast::Param, is_closure: bool) { self.ibox(INDENT_UNIT); self.print_outer_attributes_inline(&input.attrs); @@ -1682,7 +1692,7 @@ impl<'a> State<'a> { self.end(); } - crate fn print_fn_ret_ty(&mut self, fn_ret_ty: &ast::FnRetTy) { + pub(crate) fn print_fn_ret_ty(&mut self, fn_ret_ty: &ast::FnRetTy) { if let ast::FnRetTy::Ty(ty) = fn_ret_ty { self.space_if_not_bol(); self.ibox(INDENT_UNIT); @@ -1693,7 +1703,7 @@ impl<'a> State<'a> { } } - crate fn print_ty_fn( + pub(crate) fn print_ty_fn( &mut self, ext: ast::Extern, unsafety: ast::Unsafe, @@ -1717,7 +1727,7 @@ impl<'a> State<'a> { self.end(); } - crate fn print_fn_header_info(&mut self, header: ast::FnHeader) { + pub(crate) fn print_fn_header_info(&mut self, header: ast::FnHeader) { self.print_constness(header.constness); self.print_asyncness(header.asyncness); self.print_unsafety(header.unsafety); @@ -1737,21 +1747,21 @@ impl<'a> State<'a> { self.word("fn") } - crate fn print_unsafety(&mut self, s: ast::Unsafe) { + pub(crate) fn print_unsafety(&mut self, s: ast::Unsafe) { match s { ast::Unsafe::No => {} ast::Unsafe::Yes(_) => self.word_nbsp("unsafe"), } } - crate fn print_constness(&mut self, s: ast::Const) { + pub(crate) fn print_constness(&mut self, s: ast::Const) { match s { ast::Const::No => {} ast::Const::Yes(_) => self.word_nbsp("const"), } } - crate fn print_is_auto(&mut self, s: ast::IsAuto) { + pub(crate) fn print_is_auto(&mut self, s: ast::IsAuto) { match s { ast::IsAuto::Yes => self.word_nbsp("auto"), ast::IsAuto::No => {} diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 23c5a92e35..f1caf22f36 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -19,7 +19,7 @@ impl<'a> State<'a> { } } - crate fn print_foreign_item(&mut self, item: &ast::ForeignItem) { + pub(crate) fn print_foreign_item(&mut self, item: &ast::ForeignItem) { let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; self.ann.pre(self, AnnNode::SubItem(id)); self.hardbreak_if_not_bol(); @@ -114,7 +114,10 @@ impl<'a> State<'a> { self.word_space("type"); self.print_ident(ident); self.print_generic_params(&generics.params); - self.print_type_bounds(":", bounds); + if !bounds.is_empty() { + self.word_nbsp(":"); + self.print_type_bounds(bounds); + } self.print_where_clause_parts(where_clauses.0.0, before_predicates); if let Some(ty) = ty { self.space(); @@ -128,7 +131,7 @@ impl<'a> State<'a> { } /// Pretty-prints an item. - crate fn print_item(&mut self, item: &ast::Item) { + pub(crate) fn print_item(&mut self, item: &ast::Item) { self.hardbreak_if_not_bol(); self.maybe_print_comment(item.span.lo()); self.print_outer_attributes(&item.attrs); @@ -320,7 +323,10 @@ impl<'a> State<'a> { real_bounds.push(b.clone()); } } - self.print_type_bounds(":", &real_bounds); + if !real_bounds.is_empty() { + self.word_nbsp(":"); + self.print_type_bounds(&real_bounds); + } self.print_where_clause(&generics.where_clause); self.word(" "); self.bopen(); @@ -347,7 +353,10 @@ impl<'a> State<'a> { } } self.nbsp(); - self.print_type_bounds("=", &real_bounds); + if !real_bounds.is_empty() { + self.word_nbsp("="); + self.print_type_bounds(&real_bounds); + } self.print_where_clause(&generics.where_clause); self.word(";"); self.end(); // end inner head-block @@ -400,16 +409,12 @@ impl<'a> State<'a> { self.bclose(span, empty) } - crate fn print_visibility(&mut self, vis: &ast::Visibility) { + pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) { match vis.kind { ast::VisibilityKind::Public => self.word_nbsp("pub"), - ast::VisibilityKind::Crate(sugar) => match sugar { - ast::CrateSugar::PubCrate => self.word_nbsp("pub(crate)"), - ast::CrateSugar::JustCrate => self.word_nbsp("crate"), - }, ast::VisibilityKind::Restricted { ref path, .. } => { let path = Self::to_string(|s| s.print_path(path, false, 0)); - if path == "self" || path == "super" { + if path == "crate" || path == "self" || path == "super" { self.word_nbsp(format!("pub({})", path)) } else { self.word_nbsp(format!("pub(in {})", path)) @@ -484,7 +489,7 @@ impl<'a> State<'a> { } } - crate fn print_variant(&mut self, v: &ast::Variant) { + pub(crate) fn print_variant(&mut self, v: &ast::Variant) { self.head(""); self.print_visibility(&v.vis); let generics = ast::Generics::default(); @@ -496,7 +501,7 @@ impl<'a> State<'a> { } } - crate fn print_assoc_item(&mut self, item: &ast::AssocItem) { + pub(crate) fn print_assoc_item(&mut self, item: &ast::AssocItem) { let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; self.ann.pre(self, AnnNode::SubItem(id)); self.hardbreak_if_not_bol(); @@ -562,7 +567,7 @@ impl<'a> State<'a> { } } - crate fn print_fn( + pub(crate) fn print_fn( &mut self, decl: &ast::FnDecl, header: ast::FnHeader, @@ -579,7 +584,7 @@ impl<'a> State<'a> { self.print_where_clause(&generics.where_clause) } - crate fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) { + pub(crate) fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) { let (open, close) = if is_closure { ("|", "|") } else { ("(", ")") }; self.word(open); self.commasep(Inconsistent, &decl.inputs, |s, param| s.print_param(param, is_closure)); @@ -591,7 +596,7 @@ impl<'a> State<'a> { self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates); } - crate fn print_where_clause_parts( + pub(crate) fn print_where_clause_parts( &mut self, has_where_token: bool, predicates: &[ast::WherePredicate], @@ -622,14 +627,23 @@ impl<'a> State<'a> { }) => { self.print_formal_generic_params(bound_generic_params); self.print_type(bounded_ty); - self.print_type_bounds(":", bounds); + self.word(":"); + if !bounds.is_empty() { + self.nbsp(); + self.print_type_bounds(bounds); + } } ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { lifetime, bounds, .. }) => { - self.print_lifetime_bounds(*lifetime, bounds); + self.print_lifetime(*lifetime); + self.word(":"); + if !bounds.is_empty() { + self.nbsp(); + self.print_lifetime_bounds(bounds); + } } ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => { self.print_type(lhs_ty); diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 3d4bd22271..ce7c0eb72c 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -59,7 +59,7 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { err.span_suggestion( span, "consider removing the prefix", - lint_str[1..].to_string(), + &lint_str[1..], Applicability::MaybeIncorrect, ); } @@ -101,6 +101,16 @@ pub struct Stability { pub feature: Symbol, } +impl Stability { + pub fn is_unstable(&self) -> bool { + self.level.is_unstable() + } + + pub fn is_stable(&self) -> bool { + self.level.is_stable() + } +} + /// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes. #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(HashStable_Generic)] @@ -111,6 +121,16 @@ pub struct ConstStability { pub promotable: bool, } +impl ConstStability { + pub fn is_const_unstable(&self) -> bool { + self.level.is_unstable() + } + + pub fn is_const_stable(&self) -> bool { + self.level.is_stable() + } +} + /// The available stability levels. #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(HashStable_Generic)] @@ -434,6 +454,15 @@ pub fn find_crate_name(sess: &Session, attrs: &[Attribute]) -> Option { sess.first_attr_value_str_by_name(attrs, sym::crate_name) } +#[derive(Clone, Debug)] +pub struct Condition { + pub name: Symbol, + pub name_span: Span, + pub value: Option, + pub value_span: Option, + pub span: Span, +} + /// Tests if a cfg-pattern matches the cfg set pub fn cfg_matches( cfg: &ast::MetaItem, @@ -442,70 +471,42 @@ pub fn cfg_matches( features: Option<&Features>, ) -> bool { eval_condition(cfg, sess, features, &mut |cfg| { - try_gate_cfg(cfg, sess, features); - let error = |span, msg| { - sess.span_diagnostic.span_err(span, msg); - true - }; - if cfg.path.segments.len() != 1 { - return error(cfg.path.span, "`cfg` predicate key must be an identifier"); - } - match &cfg.kind { - MetaItemKind::List(..) => { - error(cfg.span, "unexpected parentheses after `cfg` predicate key") - } - MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { - handle_errors( - sess, - lit.span, - AttrError::UnsupportedLiteral( - "literal in `cfg` predicate value must be a string", - lit.kind.is_bytestr(), - ), + try_gate_cfg(cfg.name, cfg.span, sess, features); + if let Some(names_valid) = &sess.check_config.names_valid { + if !names_valid.contains(&cfg.name) { + sess.buffer_lint_with_diagnostic( + UNEXPECTED_CFGS, + cfg.span, + lint_node_id, + "unexpected `cfg` condition name", + BuiltinLintDiagnostics::UnexpectedCfg((cfg.name, cfg.name_span), None), ); - true } - MetaItemKind::NameValue(..) | MetaItemKind::Word => { - let ident = cfg.ident().expect("multi-segment cfg predicate"); - let name = ident.name; - let value = cfg.value_str(); - if let Some(names_valid) = &sess.check_config.names_valid { - if !names_valid.contains(&name) { - sess.buffer_lint_with_diagnostic( - UNEXPECTED_CFGS, - cfg.span, - lint_node_id, - "unexpected `cfg` condition name", - BuiltinLintDiagnostics::UnexpectedCfg((name, ident.span), None), - ); - } - } - if let Some(value) = value { - if let Some(values) = &sess.check_config.values_valid.get(&name) { - if !values.contains(&value) { - sess.buffer_lint_with_diagnostic( - UNEXPECTED_CFGS, - cfg.span, - lint_node_id, - "unexpected `cfg` condition value", - BuiltinLintDiagnostics::UnexpectedCfg( - (name, ident.span), - Some((value, cfg.name_value_literal_span().unwrap())), - ), - ); - } - } + } + if let Some(value) = cfg.value { + if let Some(values) = &sess.check_config.values_valid.get(&cfg.name) { + if !values.contains(&value) { + sess.buffer_lint_with_diagnostic( + UNEXPECTED_CFGS, + cfg.span, + lint_node_id, + "unexpected `cfg` condition value", + BuiltinLintDiagnostics::UnexpectedCfg( + (cfg.name, cfg.name_span), + cfg.value_span.map(|vs| (value, vs)), + ), + ); } - sess.config.contains(&(name, value)) } } + sess.config.contains(&(cfg.name, cfg.value)) }) } -fn try_gate_cfg(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) { - let gate = find_gated_cfg(|sym| cfg.has_name(sym)); +fn try_gate_cfg(name: Symbol, span: Span, sess: &ParseSess, features: Option<&Features>) { + let gate = find_gated_cfg(|sym| sym == name); if let (Some(feats), Some(gated_cfg)) = (features, gate) { - gate_cfg(&gated_cfg, cfg.span, sess, feats); + gate_cfg(&gated_cfg, span, sess, feats); } } @@ -543,11 +544,11 @@ pub fn eval_condition( cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>, - eval: &mut impl FnMut(&ast::MetaItem) -> bool, + eval: &mut impl FnMut(Condition) -> bool, ) -> bool { match cfg.kind { ast::MetaItemKind::List(ref mis) if cfg.name_or_empty() == sym::version => { - try_gate_cfg(cfg, sess, features); + try_gate_cfg(sym::version, cfg.span, sess, features); let (min_version, span) = match &mis[..] { [NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => { (sym, span) @@ -629,6 +630,25 @@ pub fn eval_condition( !eval_condition(mis[0].meta_item().unwrap(), sess, features, eval) } + sym::target => { + if let Some(features) = features && !features.cfg_target_compact { + feature_err( + sess, + sym::cfg_target_compact, + cfg.span, + &"compact `cfg(target(..))` is experimental and subject to change" + ).emit(); + } + + mis.iter().fold(true, |res, mi| { + let mut mi = mi.meta_item().unwrap().clone(); + if let [seg, ..] = &mut mi.path.segments[..] { + seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name)); + } + + res & eval_condition(&mi, sess, features, eval) + }) + } _ => { struct_span_err!( sess.span_diagnostic, @@ -642,7 +662,32 @@ pub fn eval_condition( } } } - ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => eval(cfg), + ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => { + sess.span_diagnostic + .span_err(cfg.path.span, "`cfg` predicate key must be an identifier"); + true + } + MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => { + handle_errors( + sess, + lit.span, + AttrError::UnsupportedLiteral( + "literal in `cfg` predicate value must be a string", + lit.kind.is_bytestr(), + ), + ); + true + } + ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => { + let ident = cfg.ident().expect("multi-segment cfg predicate"); + eval(Condition { + name: ident.name, + name_span: ident.span, + value: cfg.value_str(), + value_span: cfg.name_value_literal_span(), + span: cfg.span, + }) + } } } @@ -675,18 +720,10 @@ where let is_rustc = sess.features_untracked().staged_api; 'outer: for attr in attrs_iter { - if !(attr.has_name(sym::deprecated) || attr.has_name(sym::rustc_deprecated)) { + if !attr.has_name(sym::deprecated) { continue; } - // FIXME(jhpratt) remove this eventually - if attr.has_name(sym::rustc_deprecated) { - diagnostic - .struct_span_err(attr.span, "`#[rustc_deprecated]` has been removed") - .help("use `#[deprecated]` instead") - .emit(); - } - let Some(meta) = attr.meta() else { continue; }; @@ -742,25 +779,6 @@ where continue 'outer; } } - // FIXME(jhpratt) remove this eventually - sym::reason if attr.has_name(sym::rustc_deprecated) => { - if !get(mi, &mut note) { - continue 'outer; - } - - let mut diag = diagnostic - .struct_span_err(mi.span, "`reason` has been renamed"); - match note { - Some(note) => diag.span_suggestion( - mi.span, - "use `note` instead", - format!("note = \"{note}\""), - Applicability::MachineApplicable, - ), - None => diag.span_help(mi.span, "use `note` instead"), - }; - diag.emit(); - } sym::suggestion => { if !sess.features_untracked().deprecated_suggestion { let mut diag = sess.struct_span_err( @@ -897,7 +915,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { err.span_suggestion( item.span(), "supply an argument here", - "align(...)".to_string(), + "align(...)", Applicability::HasPlaceholders, ); err.emit(); diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index c95c1c40a3..c3f9f0cf36 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -4,6 +4,7 @@ //! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax` //! to this crate. +#![feature(let_chains)] #![feature(let_else)] #[macro_use] diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs index 7c921b8505..c7d0e33613 100644 --- a/compiler/rustc_borrowck/src/borrow_set.rs +++ b/compiler/rustc_borrowck/src/borrow_set.rs @@ -29,7 +29,7 @@ pub struct BorrowSet<'tcx> { /// Map from local to all the borrows on that local. pub local_map: FxHashMap>, - crate locals_state_at_exit: LocalsStateAtExit, + pub(crate) locals_state_at_exit: LocalsStateAtExit, } impl<'tcx> Index for BorrowSet<'tcx> { @@ -148,23 +148,23 @@ impl<'tcx> BorrowSet<'tcx> { } } - crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] { + pub(crate) fn activations_at_location(&self, location: Location) -> &[BorrowIndex] { self.activation_map.get(&location).map_or(&[], |activations| &activations[..]) } - crate fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { self.location_map.len() } - crate fn indices(&self) -> impl Iterator { + pub(crate) fn indices(&self) -> impl Iterator { BorrowIndex::from_usize(0)..BorrowIndex::from_usize(self.len()) } - crate fn iter_enumerated(&self) -> impl Iterator)> { + pub(crate) fn iter_enumerated(&self) -> impl Iterator)> { self.indices().zip(self.location_map.values()) } - crate fn get_index_of(&self, location: &Location) -> Option { + pub(crate) fn get_index_of(&self, location: &Location) -> Option { self.location_map.get_index_of(location).map(BorrowIndex::from) } } diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 70f7f1e493..a1233d62cb 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { - crate fn cannot_move_when_borrowed( + pub(crate) fn cannot_move_when_borrowed( &self, span: Span, desc: &str, @@ -11,7 +11,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,) } - crate fn cannot_use_when_mutably_borrowed( + pub(crate) fn cannot_use_when_mutably_borrowed( &self, span: Span, desc: &str, @@ -31,7 +31,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_act_on_uninitialized_variable( + pub(crate) fn cannot_act_on_uninitialized_variable( &self, span: Span, verb: &str, @@ -47,7 +47,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { ) } - crate fn cannot_mutably_borrow_multiply( + pub(crate) fn cannot_mutably_borrow_multiply( &self, new_loan_span: Span, desc: &str, @@ -97,7 +97,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_uniquely_borrow_by_two_closures( + pub(crate) fn cannot_uniquely_borrow_by_two_closures( &self, new_loan_span: Span, desc: &str, @@ -126,7 +126,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_uniquely_borrow_by_one_closure( + pub(crate) fn cannot_uniquely_borrow_by_one_closure( &self, new_loan_span: Span, container_name: &str, @@ -157,7 +157,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_reborrow_already_uniquely_borrowed( + pub(crate) fn cannot_reborrow_already_uniquely_borrowed( &self, new_loan_span: Span, container_name: &str, @@ -193,7 +193,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_reborrow_already_borrowed( + pub(crate) fn cannot_reborrow_already_borrowed( &self, span: Span, desc_new: &str, @@ -242,7 +242,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_assign_to_borrowed( + pub(crate) fn cannot_assign_to_borrowed( &self, span: Span, borrow_span: Span, @@ -261,7 +261,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_reassign_immutable( + pub(crate) fn cannot_reassign_immutable( &self, span: Span, desc: &str, @@ -271,7 +271,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc) } - crate fn cannot_assign( + pub(crate) fn cannot_assign( &self, span: Span, desc: &str, @@ -279,7 +279,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { struct_span_err!(self, span, E0594, "cannot assign to {}", desc) } - crate fn cannot_move_out_of( + pub(crate) fn cannot_move_out_of( &self, move_from_span: Span, move_from_desc: &str, @@ -290,7 +290,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { /// Signal an error due to an attempt to move out of the interior /// of an array or slice. `is_index` is None when error origin /// didn't capture whether there was an indexing operation or not. - crate fn cannot_move_out_of_interior_noncopy( + pub(crate) fn cannot_move_out_of_interior_noncopy( &self, move_from_span: Span, ty: Ty<'_>, @@ -313,7 +313,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_move_out_of_interior_of_drop( + pub(crate) fn cannot_move_out_of_interior_of_drop( &self, move_from_span: Span, container_ty: Ty<'_>, @@ -329,7 +329,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_act_on_moved_value( + pub(crate) fn cannot_act_on_moved_value( &self, use_span: Span, verb: &str, @@ -349,7 +349,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { ) } - crate fn cannot_borrow_path_as_mutable_because( + pub(crate) fn cannot_borrow_path_as_mutable_because( &self, span: Span, path: &str, @@ -358,7 +358,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,) } - crate fn cannot_mutate_in_immutable_section( + pub(crate) fn cannot_mutate_in_immutable_section( &self, mutate_span: Span, immutable_span: Span, @@ -380,7 +380,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_borrow_across_generator_yield( + pub(crate) fn cannot_borrow_across_generator_yield( &self, span: Span, yield_span: Span, @@ -395,7 +395,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_borrow_across_destructor( + pub(crate) fn cannot_borrow_across_destructor( &self, borrow_span: Span, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { @@ -407,7 +407,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { ) } - crate fn path_does_not_live_long_enough( + pub(crate) fn path_does_not_live_long_enough( &self, span: Span, path: &str, @@ -415,7 +415,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { struct_span_err!(self, span, E0597, "{} does not live long enough", path,) } - crate fn cannot_return_reference_to_local( + pub(crate) fn cannot_return_reference_to_local( &self, span: Span, return_kind: &str, @@ -440,7 +440,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_capture_in_long_lived_closure( + pub(crate) fn cannot_capture_in_long_lived_closure( &self, closure_span: Span, closure_kind: &str, @@ -462,14 +462,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn thread_local_value_does_not_live_long_enough( + pub(crate) fn thread_local_value_does_not_live_long_enough( &self, span: Span, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",) } - crate fn temporary_value_borrowed_for_too_long( + pub(crate) fn temporary_value_borrowed_for_too_long( &self, span: Span, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { @@ -486,7 +486,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { } } -crate fn borrowed_data_escapes_closure<'tcx>( +pub(crate) fn borrowed_data_escapes_closure<'tcx>( tcx: TyCtxt<'tcx>, escape_span: Span, escapes_from: &str, diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index 22edee33c5..e4ffae38c3 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -140,9 +140,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { // A `Call` terminator's return value can be a local which has borrows, // so we need to record those as `killed` as well. if let TerminatorKind::Call { destination, .. } = terminator.kind { - if let Some((place, _)) = destination { - self.record_killed_borrows_for_place(place, location); - } + self.record_killed_borrows_for_place(destination, location); } self.super_terminator(terminator, location); diff --git a/compiler/rustc_borrowck/src/constraints/graph.rs b/compiler/rustc_borrowck/src/constraints/graph.rs index c19a39c393..609fbc2bc1 100644 --- a/compiler/rustc_borrowck/src/constraints/graph.rs +++ b/compiler/rustc_borrowck/src/constraints/graph.rs @@ -13,19 +13,19 @@ use crate::{ /// The construct graph organizes the constraints by their end-points. /// It can be used to view a `R1: R2` constraint as either an edge `R1 /// -> R2` or `R2 -> R1` depending on the direction type `D`. -crate struct ConstraintGraph { +pub(crate) struct ConstraintGraph { _direction: D, first_constraints: IndexVec>, next_constraints: IndexVec>, } -crate type NormalConstraintGraph = ConstraintGraph; +pub(crate) type NormalConstraintGraph = ConstraintGraph; -crate type ReverseConstraintGraph = ConstraintGraph; +pub(crate) type ReverseConstraintGraph = ConstraintGraph; /// Marker trait that controls whether a `R1: R2` constraint /// represents an edge `R1 -> R2` or `R2 -> R1`. -crate trait ConstraintGraphDirecton: Copy + 'static { +pub(crate) trait ConstraintGraphDirecton: Copy + 'static { fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid; fn end_region(c: &OutlivesConstraint<'_>) -> RegionVid; fn is_normal() -> bool; @@ -36,7 +36,7 @@ crate trait ConstraintGraphDirecton: Copy + 'static { /// inference. This is because we compute the value of R1 by union'ing /// all the things that it relies on. #[derive(Copy, Clone, Debug)] -crate struct Normal; +pub(crate) struct Normal; impl ConstraintGraphDirecton for Normal { fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid { @@ -57,7 +57,7 @@ impl ConstraintGraphDirecton for Normal { /// we wish to iterate from a region (e.g., R2) to all the regions /// that will outlive it (e.g., R1). #[derive(Copy, Clone, Debug)] -crate struct Reverse; +pub(crate) struct Reverse; impl ConstraintGraphDirecton for Reverse { fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid { @@ -78,7 +78,11 @@ impl ConstraintGraph { /// R2` is treated as an edge `R1 -> R2`. We use this graph to /// construct SCCs for region inference but also for error /// reporting. - crate fn new(direction: D, set: &OutlivesConstraintSet<'_>, num_region_vars: usize) -> Self { + pub(crate) fn new( + direction: D, + set: &OutlivesConstraintSet<'_>, + num_region_vars: usize, + ) -> Self { let mut first_constraints = IndexVec::from_elem_n(None, num_region_vars); let mut next_constraints = IndexVec::from_elem(None, &set.outlives); @@ -96,7 +100,7 @@ impl ConstraintGraph { /// Given the constraint set from which this graph was built /// creates a region graph so that you can iterate over *regions* /// and not constraints. - crate fn region_graph<'rg, 'tcx>( + pub(crate) fn region_graph<'rg, 'tcx>( &'rg self, set: &'rg OutlivesConstraintSet<'tcx>, static_region: RegionVid, @@ -105,7 +109,7 @@ impl ConstraintGraph { } /// Given a region `R`, iterate over all constraints `R: R1`. - crate fn outgoing_edges<'a, 'tcx>( + pub(crate) fn outgoing_edges<'a, 'tcx>( &'a self, region_sup: RegionVid, constraints: &'a OutlivesConstraintSet<'tcx>, @@ -129,7 +133,7 @@ impl ConstraintGraph { } } -crate struct Edges<'s, 'tcx, D: ConstraintGraphDirecton> { +pub(crate) struct Edges<'s, 'tcx, D: ConstraintGraphDirecton> { graph: &'s ConstraintGraph, constraints: &'s OutlivesConstraintSet<'tcx>, pointer: Option, @@ -169,7 +173,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> { /// This struct brings together a constraint set and a (normal, not /// reverse) constraint graph. It implements the graph traits and is /// usd for doing the SCC computation. -crate struct RegionGraph<'s, 'tcx, D: ConstraintGraphDirecton> { +pub(crate) struct RegionGraph<'s, 'tcx, D: ConstraintGraphDirecton> { set: &'s OutlivesConstraintSet<'tcx>, constraint_graph: &'s ConstraintGraph, static_region: RegionVid, @@ -180,7 +184,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> RegionGraph<'s, 'tcx, D> { /// R2` is treated as an edge `R1 -> R2`. We use this graph to /// construct SCCs for region inference but also for error /// reporting. - crate fn new( + pub(crate) fn new( set: &'s OutlivesConstraintSet<'tcx>, constraint_graph: &'s ConstraintGraph, static_region: RegionVid, @@ -190,14 +194,14 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> RegionGraph<'s, 'tcx, D> { /// Given a region `R`, iterate over all regions `R1` such that /// there exists a constraint `R: R1`. - crate fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'s, 'tcx, D> { + pub(crate) fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'s, 'tcx, D> { Successors { edges: self.constraint_graph.outgoing_edges(region_sup, self.set, self.static_region), } } } -crate struct Successors<'s, 'tcx, D: ConstraintGraphDirecton> { +pub(crate) struct Successors<'s, 'tcx, D: ConstraintGraphDirecton> { edges: Edges<'s, 'tcx, D>, } diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 14f0e5f620..a504d0c912 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -8,19 +8,19 @@ use std::ops::Index; use crate::type_check::Locations; -crate mod graph; +pub(crate) mod graph; /// A set of NLL region constraints. These include "outlives" /// constraints of the form `R1: R2`. Each constraint is identified by /// a unique `OutlivesConstraintIndex` and you can index into the set /// (`constraint_set[i]`) to access the constraint details. #[derive(Clone, Default)] -crate struct OutlivesConstraintSet<'tcx> { +pub(crate) struct OutlivesConstraintSet<'tcx> { outlives: IndexVec>, } impl<'tcx> OutlivesConstraintSet<'tcx> { - crate fn push(&mut self, constraint: OutlivesConstraint<'tcx>) { + pub(crate) fn push(&mut self, constraint: OutlivesConstraint<'tcx>) { debug!( "OutlivesConstraintSet::push({:?}: {:?} @ {:?}", constraint.sup, constraint.sub, constraint.locations @@ -38,20 +38,20 @@ impl<'tcx> OutlivesConstraintSet<'tcx> { /// N.B., this graph contains a "frozen" view of the current /// constraints. Any new constraints added to the `OutlivesConstraintSet` /// after the graph is built will not be present in the graph. - crate fn graph(&self, num_region_vars: usize) -> graph::NormalConstraintGraph { + pub(crate) fn graph(&self, num_region_vars: usize) -> graph::NormalConstraintGraph { graph::ConstraintGraph::new(graph::Normal, self, num_region_vars) } /// Like `graph`, but constraints a reverse graph where `R1: R2` /// represents an edge `R2 -> R1`. - crate fn reverse_graph(&self, num_region_vars: usize) -> graph::ReverseConstraintGraph { + pub(crate) fn reverse_graph(&self, num_region_vars: usize) -> graph::ReverseConstraintGraph { graph::ConstraintGraph::new(graph::Reverse, self, num_region_vars) } /// Computes cycles (SCCs) in the graph of regions. In particular, /// find all regions R1, R2 such that R1: R2 and R2: R1 and group /// them into an SCC, and find the relationships between SCCs. - crate fn compute_sccs( + pub(crate) fn compute_sccs( &self, constraint_graph: &graph::NormalConstraintGraph, static_region: RegionVid, @@ -60,7 +60,7 @@ impl<'tcx> OutlivesConstraintSet<'tcx> { Sccs::new(region_graph) } - crate fn outlives(&self) -> &IndexVec> { + pub(crate) fn outlives(&self) -> &IndexVec> { &self.outlives } } @@ -95,7 +95,7 @@ pub struct OutlivesConstraint<'tcx> { pub span: Span, /// What caused this constraint? - pub category: ConstraintCategory, + pub category: ConstraintCategory<'tcx>, /// Variance diagnostic information pub variance_info: VarianceDiagInfo<'tcx>, diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index d38e89cd79..97d5a8d158 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -199,7 +199,7 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> { // Add successor BBs to the work list, if necessary. let bb_data = &self.body[bb]; debug_assert!(hi == bb_data.statements.len()); - for &succ_bb in bb_data.terminator().successors() { + for succ_bb in bb_data.terminator().successors() { if !self.visited.insert(succ_bb) { if succ_bb == location.block && first_lo > 0 { // `succ_bb` has been seen before. If it wasn't @@ -233,7 +233,7 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> { } impl<'a, 'tcx> Borrows<'a, 'tcx> { - crate fn new( + pub(crate) fn new( tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, nonlexical_regioncx: &'a RegionInferenceContext<'tcx>, diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 8601fbe27f..07f182102f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -22,7 +22,7 @@ use crate::region_infer::values::RegionElement; use crate::MirBorrowckCtxt; #[derive(Clone)] -crate struct UniverseInfo<'tcx>(UniverseInfoInner<'tcx>); +pub(crate) struct UniverseInfo<'tcx>(UniverseInfoInner<'tcx>); /// What operation a universe was created for. #[derive(Clone)] @@ -36,15 +36,15 @@ enum UniverseInfoInner<'tcx> { } impl<'tcx> UniverseInfo<'tcx> { - crate fn other() -> UniverseInfo<'tcx> { + pub(crate) fn other() -> UniverseInfo<'tcx> { UniverseInfo(UniverseInfoInner::Other) } - crate fn relate(expected: Ty<'tcx>, found: Ty<'tcx>) -> UniverseInfo<'tcx> { + pub(crate) fn relate(expected: Ty<'tcx>, found: Ty<'tcx>) -> UniverseInfo<'tcx> { UniverseInfo(UniverseInfoInner::RelateTys { expected, found }) } - crate fn report_error( + pub(crate) fn report_error( &self, mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, placeholder: ty::PlaceholderRegion, @@ -76,7 +76,7 @@ impl<'tcx> UniverseInfo<'tcx> { } } -crate trait ToUniverseInfo<'tcx> { +pub(crate) trait ToUniverseInfo<'tcx> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx>; } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index a3c9da3021..73c0bf16a1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1,5 +1,6 @@ use either::Either; use rustc_const_eval::util::CallKind; +use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; @@ -224,7 +225,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .map(|n| format!("`{}`", n)) .unwrap_or_else(|| "the value".to_string()) ), - "ref ".to_string(), + "ref ", Applicability::MachineApplicable, ); in_pattern = true; @@ -275,7 +276,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .map(|n| format!("`{}`", n)) .unwrap_or_else(|| "the mutable reference".to_string()), ), - "&mut *".to_string(), + "&mut *", Applicability::MachineApplicable, ); } @@ -787,7 +788,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err: &mut Diagnostic, location: Location, issued_borrow: &BorrowData<'tcx>, - explanation: BorrowExplanation, + explanation: BorrowExplanation<'tcx>, ) { let used_in_call = matches!( explanation, @@ -1087,7 +1088,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { BorrowExplanation::MustBeValidFor { category: category @ (ConstraintCategory::Return(_) - | ConstraintCategory::CallArgument + | ConstraintCategory::CallArgument(_) | ConstraintCategory::OpaqueType), from_closure: false, ref region_name, @@ -1146,7 +1147,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow: &BorrowData<'tcx>, drop_span: Span, borrow_spans: UseSpans<'tcx>, - explanation: BorrowExplanation, + explanation: BorrowExplanation<'tcx>, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { debug!( "report_local_value_does_not_live_long_enough(\ @@ -1351,7 +1352,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { drop_span: Span, borrow_spans: UseSpans<'tcx>, proper_span: Span, - explanation: BorrowExplanation, + explanation: BorrowExplanation<'tcx>, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { debug!( "report_temporary_value_does_not_live_long_enough(\ @@ -1409,7 +1410,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow: &BorrowData<'tcx>, borrow_span: Span, return_span: Span, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, opt_place_desc: Option<&String>, ) -> Option> { let return_kind = match category { @@ -1507,7 +1508,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { use_span: UseSpans<'tcx>, var_span: Span, fr_name: &RegionName, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, constraint_span: Span, captured_var: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { @@ -1518,15 +1519,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Ok(string) => { if string.starts_with("async ") { let pos = args_span.lo() + BytePos(6); - (args_span.with_lo(pos).with_hi(pos), "move ".to_string()) + (args_span.with_lo(pos).with_hi(pos), "move ") } else if string.starts_with("async|") { let pos = args_span.lo() + BytePos(5); - (args_span.with_lo(pos).with_hi(pos), " move".to_string()) + (args_span.with_lo(pos).with_hi(pos), " move") } else { - (args_span.shrink_to_lo(), "move ".to_string()) + (args_span.shrink_to_lo(), "move ") } } - Err(_) => (args_span, "move || ".to_string()), + Err(_) => (args_span, "move || "), }; let kind = match use_span.generator_kind() { Some(generator_kind) => match generator_kind { @@ -1558,7 +1559,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let msg = format!("{} is returned here", kind); err.span_note(constraint_span, &msg); } - ConstraintCategory::CallArgument => { + ConstraintCategory::CallArgument(_) => { fr_name.highlight_region_name(&mut err); if matches!(use_span.generator_kind(), Some(GeneratorKind::Async(_))) { err.note( @@ -1622,10 +1623,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location: Location, mpi: MovePathIndex, ) -> (Vec, Vec) { - fn predecessor_locations<'a>( - body: &'a mir::Body<'_>, + fn predecessor_locations<'tcx, 'a>( + body: &'a mir::Body<'tcx>, location: Location, - ) -> impl Iterator + 'a { + ) -> impl Iterator + Captures<'tcx> + 'a { if location.statement_index == 0 { let predecessors = body.predecessors()[location.block].to_vec(); Either::Left(predecessors.into_iter().map(move |bb| body.terminator_loc(bb))) @@ -2197,10 +2198,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "annotate_argument_and_return_for_borrow: target={:?} terminator={:?}", target, terminator ); - if let TerminatorKind::Call { destination: Some((place, _)), args, .. } = + if let TerminatorKind::Call { destination, target: Some(_), args, .. } = &terminator.kind { - if let Some(assigned_to) = place.as_local() { + if let Some(assigned_to) = destination.as_local() { debug!( "annotate_argument_and_return_for_borrow: assigned_to={:?} args={:?}", assigned_to, args diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index ffea15bdc3..230ccf5199 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -24,7 +24,7 @@ use crate::{ use super::{find_use, RegionName, UseSpans}; #[derive(Debug)] -pub(crate) enum BorrowExplanation { +pub(crate) enum BorrowExplanation<'tcx> { UsedLater(LaterUseKind, Span, Option), UsedLaterInLoop(LaterUseKind, Span, Option), UsedLaterWhenDropped { @@ -33,7 +33,7 @@ pub(crate) enum BorrowExplanation { should_note_order: bool, }, MustBeValidFor { - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, from_closure: bool, span: Span, region_name: RegionName, @@ -51,11 +51,11 @@ pub(crate) enum LaterUseKind { Other, } -impl BorrowExplanation { +impl<'tcx> BorrowExplanation<'tcx> { pub(crate) fn is_explained(&self) -> bool { !matches!(self, BorrowExplanation::Unexplained) } - pub(crate) fn add_explanation_to_diagnostic<'tcx>( + pub(crate) fn add_explanation_to_diagnostic( &self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>, @@ -212,7 +212,7 @@ impl BorrowExplanation { "consider adding semicolon after the expression so its \ temporaries are dropped sooner, before the local variables \ declared by the block are dropped", - ";".to_string(), + ";", Applicability::MaybeIncorrect, ); } @@ -276,7 +276,7 @@ impl BorrowExplanation { pub(crate) fn add_lifetime_bound_suggestion_to_diagnostic( &self, err: &mut Diagnostic, - category: &ConstraintCategory, + category: &ConstraintCategory<'tcx>, span: Span, region_name: &RegionName, ) { @@ -305,7 +305,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self, borrow_region: RegionVid, outlived_region: RegionVid, - ) -> (ConstraintCategory, bool, Span, Option) { + ) -> (ConstraintCategory<'tcx>, bool, Span, Option) { let BlameConstraint { category, from_closure, cause, variance_info: _ } = self.regioncx.best_blame_constraint( &self.body, @@ -337,7 +337,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location: Location, borrow: &BorrowData<'tcx>, kind_place: Option<(WriteKind, Place<'tcx>)>, - ) -> BorrowExplanation { + ) -> BorrowExplanation<'tcx> { debug!( "explain_why_borrow_contains_point(location={:?}, borrow={:?}, kind_place={:?})", location, borrow, kind_place @@ -467,7 +467,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { block .terminator() .successors() - .map(|bb| Location { statement_index: 0, block: *bb }) + .map(|bb| Location { statement_index: 0, block: bb }) .filter(|s| visited_locations.insert(*s)) .map(|s| { if self.is_back_edge(location, s) { @@ -526,7 +526,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } else { for bb in block.terminator().successors() { - let successor = Location { statement_index: 0, block: *bb }; + let successor = Location { statement_index: 0, block: bb }; if !visited_locations.contains(&successor) && self.find_loop_head_dfs(successor, loop_head, visited_locations) @@ -705,10 +705,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let terminator = block.terminator(); debug!("was_captured_by_trait_object: terminator={:?}", terminator); - if let TerminatorKind::Call { destination: Some((place, block)), args, .. } = + if let TerminatorKind::Call { destination, target: Some(block), args, .. } = &terminator.kind { - if let Some(dest) = place.as_local() { + if let Some(dest) = destination.as_local() { debug!( "was_captured_by_trait_object: target={:?} dest={:?} args={:?}", target, dest, args diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index ab4536f00f..06fca4db0c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -11,7 +11,7 @@ use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor}; use rustc_middle::mir::{Body, Local, Location}; use rustc_middle::ty::{RegionVid, TyCtxt}; -crate fn find<'tcx>( +pub(crate) fn find<'tcx>( body: &Body<'tcx>, regioncx: &Rc>, tcx: TyCtxt<'tcx>, @@ -67,8 +67,8 @@ impl<'cx, 'tcx> UseFinder<'cx, 'tcx> { block_data .terminator() .successors() - .filter(|&bb| Some(&Some(*bb)) != block_data.terminator().unwind()) - .map(|&bb| Location { statement_index: 0, block: bb }), + .filter(|&bb| Some(&Some(bb)) != block_data.terminator().unwind()) + .map(|bb| Location { statement_index: 0, block: bb }), ); } } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 05d2950318..fbc3a8cc08 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -35,12 +35,12 @@ mod move_errors; mod mutability_errors; mod region_errors; -crate use bound_region_errors::{ToUniverseInfo, UniverseInfo}; -crate use mutability_errors::AccessKind; -crate use outlives_suggestion::OutlivesSuggestionBuilder; -crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors}; -crate use region_name::{RegionName, RegionNameSource}; -crate use rustc_const_eval::util::CallKind; +pub(crate) use bound_region_errors::{ToUniverseInfo, UniverseInfo}; +pub(crate) use mutability_errors::AccessKind; +pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder; +pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors}; +pub(crate) use region_name::{RegionName, RegionNameSource}; +pub(crate) use rustc_const_eval::util::CallKind; use rustc_middle::mir::tcx::PlaceTy; pub(super) struct IncludingDowncast(pub(super) bool); @@ -896,7 +896,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(local_did); let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); - if let hir::ExprKind::Closure(.., body_id, args_span, _) = expr { + if let hir::ExprKind::Closure { body, fn_decl_span, .. } = expr { for (captured_place, place) in self .infcx .tcx @@ -909,11 +909,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if target_place == place.as_ref() => { debug!("closure_span: found captured local {:?}", place); - let body = self.infcx.tcx.hir().body(*body_id); + let body = self.infcx.tcx.hir().body(*body); let generator_kind = body.generator_kind(); return Some(( - *args_span, + *fn_decl_span, generator_kind, captured_place.get_capture_kind_span(self.infcx.tcx), captured_place.get_path_span(self.infcx.tcx), @@ -1023,7 +1023,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { avoid moving into the `for` loop", ty, ), - "&".to_string(), + "&", Applicability::MaybeIncorrect, ); } @@ -1049,7 +1049,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .map(|n| format!("`{}`", n)) .unwrap_or_else(|| "the mutable reference".to_string()), ), - "&mut *".to_string(), + "&mut *", Applicability::MachineApplicable, ); } @@ -1067,7 +1067,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_suggestion_verbose( fn_call_span.shrink_to_lo(), "consider calling `.as_ref()` to borrow the type's contents", - "as_ref().".to_string(), + "as_ref().", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index e7fd89c140..eb5e61fa06 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -417,7 +417,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_hi(), &format!("consider borrowing the `{}`'s content", diag_name.unwrap()), - ".as_ref()".to_string(), + ".as_ref()", Applicability::MaybeIncorrect, ); } else if let Some(use_spans) = use_spans { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index fe5e3c5a81..861c5e973f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -295,7 +295,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_suggestion_verbose( source_info.span.with_hi(source_info.span.lo() + BytePos(5)), "try removing `&mut` here", - String::new(), + "", Applicability::MachineApplicable, ); } else { @@ -316,7 +316,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_suggestion_verbose( decl.source_info.span.shrink_to_lo(), "consider making the binding mutable", - "mut ".to_string(), + "mut ", Applicability::MachineApplicable, ); } @@ -402,7 +402,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_suggestion( span, "try removing `&mut` here", - String::new(), + "", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index ab9c206a46..d359d7efb6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -62,7 +62,8 @@ impl OutlivesSuggestionBuilder { | RegionNameSource::AnonRegionFromUpvar(..) | RegionNameSource::AnonRegionFromOutput(..) | RegionNameSource::AnonRegionFromYieldTy(..) - | RegionNameSource::AnonRegionFromAsyncFn(..) => { + | RegionNameSource::AnonRegionFromAsyncFn(..) + | RegionNameSource::AnonRegionFromImplSignature(..) => { debug!("Region {:?} is NOT suggestable", name); false } @@ -149,7 +150,7 @@ impl OutlivesSuggestionBuilder { } /// Add the outlives constraint `fr: outlived_fr` to the set of constraints we need to suggest. - crate fn collect_constraint(&mut self, fr: RegionVid, outlived_fr: RegionVid) { + pub(crate) fn collect_constraint(&mut self, fr: RegionVid, outlived_fr: RegionVid) { debug!("Collected {:?}: {:?}", fr, outlived_fr); // Add to set of constraints for final help note. @@ -158,10 +159,10 @@ impl OutlivesSuggestionBuilder { /// Emit an intermediate note on the given `Diagnostic` if the involved regions are /// suggestable. - crate fn intermediate_suggestion( + pub(crate) fn intermediate_suggestion( &mut self, mbcx: &MirBorrowckCtxt<'_, '_>, - errci: &ErrorConstraintInfo, + errci: &ErrorConstraintInfo<'_>, diag: &mut Diagnostic, ) { // Emit an intermediate note. @@ -179,7 +180,7 @@ impl OutlivesSuggestionBuilder { /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final /// suggestion including all collected constraints. - crate fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) { + pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) { // No constraints to add? Done. if self.constraints_to_add.is_empty() { debug!("No constraints to suggest."); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 6f1c8daf42..e0f8da1c87 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1,10 +1,14 @@ //! Error reporting machinery for lifetime errors. -use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_data_structures::stable_set::FxHashSet; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; +use rustc_hir::def_id::DefId; +use rustc_hir::intravisit::Visitor; +use rustc_hir::{self as hir, Item, ItemKind, Node}; use rustc_infer::infer::{ error_reporting::nice_region_error::{ self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params, - NiceRegionError, + HirTraitObjectVisitor, NiceRegionError, TraitObjectVisitor, }, error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin, RelateParamBound, @@ -12,8 +16,11 @@ use rustc_infer::infer::{ use rustc_middle::hir::place::PlaceBase; use rustc_middle::mir::{ConstraintCategory, ReturnConstraint}; use rustc_middle::ty::subst::InternalSubsts; +use rustc_middle::ty::Region; +use rustc_middle::ty::TypeVisitor; use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_span::symbol::sym; +use rustc_span::symbol::Ident; use rustc_span::Span; use crate::borrowck_errors; @@ -27,7 +34,7 @@ use crate::{ MirBorrowckCtxt, }; -impl ConstraintDescription for ConstraintCategory { +impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> { fn description(&self) -> &'static str { // Must end with a space. Allows for empty names to be provided. match self { @@ -37,7 +44,7 @@ impl ConstraintDescription for ConstraintCategory { ConstraintCategory::UseAsConst => "using this value as a constant ", ConstraintCategory::UseAsStatic => "using this value as a static ", ConstraintCategory::Cast => "cast ", - ConstraintCategory::CallArgument => "argument ", + ConstraintCategory::CallArgument(_) => "argument ", ConstraintCategory::TypeAnnotation => "type annotation ", ConstraintCategory::ClosureBounds => "closure body ", ConstraintCategory::SizedBound => "proving this value is `Sized` ", @@ -58,10 +65,10 @@ impl ConstraintDescription for ConstraintCategory { /// /// Usually we expect this to either be empty or contain a small number of items, so we can avoid /// allocation most of the time. -crate type RegionErrors<'tcx> = Vec>; +pub(crate) type RegionErrors<'tcx> = Vec>; #[derive(Clone, Debug)] -crate enum RegionErrorKind<'tcx> { +pub(crate) enum RegionErrorKind<'tcx> { /// A generic bound failure for a type test (`T: 'a`). TypeTestError { type_test: TypeTest<'tcx> }, @@ -101,7 +108,7 @@ crate enum RegionErrorKind<'tcx> { /// Information about the various region constraints involved in a borrow checker error. #[derive(Clone, Debug)] -pub struct ErrorConstraintInfo { +pub struct ErrorConstraintInfo<'tcx> { // fr: outlived_fr pub(super) fr: RegionVid, pub(super) fr_is_local: bool, @@ -109,7 +116,7 @@ pub struct ErrorConstraintInfo { pub(super) outlived_fr_is_local: bool, // Category and span for best blame constraint - pub(super) category: ConstraintCategory, + pub(super) category: ConstraintCategory<'tcx>, pub(super) span: Span, } @@ -256,6 +263,70 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { outlives_suggestion.add_suggestion(self); } + fn get_impl_ident_and_self_ty_from_trait( + &self, + def_id: DefId, + trait_objects: &FxHashSet, + ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> { + let tcx = self.infcx.tcx; + match tcx.hir().get_if_local(def_id) { + Some(Node::ImplItem(impl_item)) => { + match tcx.hir().find_by_def_id(tcx.hir().get_parent_item(impl_item.hir_id())) { + Some(Node::Item(Item { + kind: ItemKind::Impl(hir::Impl { self_ty, .. }), + .. + })) => Some((impl_item.ident, self_ty)), + _ => None, + } + } + Some(Node::TraitItem(trait_item)) => { + let trait_did = tcx.hir().get_parent_item(trait_item.hir_id()); + match tcx.hir().find_by_def_id(trait_did) { + Some(Node::Item(Item { kind: ItemKind::Trait(..), .. })) => { + // The method being called is defined in the `trait`, but the `'static` + // obligation comes from the `impl`. Find that `impl` so that we can point + // at it in the suggestion. + let trait_did = trait_did.to_def_id(); + match tcx + .hir() + .trait_impls(trait_did) + .iter() + .filter_map(|&impl_did| { + match tcx.hir().get_if_local(impl_did.to_def_id()) { + Some(Node::Item(Item { + kind: ItemKind::Impl(hir::Impl { self_ty, .. }), + .. + })) if trait_objects.iter().all(|did| { + // FIXME: we should check `self_ty` against the receiver + // type in the `UnifyReceiver` context, but for now, use + // this imperfect proxy. This will fail if there are + // multiple `impl`s for the same trait like + // `impl Foo for Box` and `impl Foo for dyn Bar`. + // In that case, only the first one will get suggestions. + let mut traits = vec![]; + let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); + hir_v.visit_ty(self_ty); + !traits.is_empty() + }) => + { + Some(self_ty) + } + _ => None, + } + }) + .next() + { + Some(self_ty) => Some((trait_item.ident, self_ty)), + _ => None, + } + } + _ => None, + } + } + _ => None, + } + } + /// Report an error because the universal region `fr` was required to outlive /// `outlived_fr` but it is not known to do so. For example: /// @@ -279,6 +350,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }); debug!("report_region_error: category={:?} {:?} {:?}", category, cause, variance_info); + // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { let nice = NiceRegionError::new_from_span(self.infcx, cause.span, o, f); @@ -312,7 +384,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { self.report_fnmut_error(&errci, kind) } (ConstraintCategory::Assignment, true, false) - | (ConstraintCategory::CallArgument, true, false) => { + | (ConstraintCategory::CallArgument(_), true, false) => { let mut db = self.report_escaping_data_error(&errci); outlives_suggestion.intermediate_suggestion(self, &errci, &mut db); @@ -405,7 +477,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// ``` fn report_fnmut_error( &self, - errci: &ErrorConstraintInfo, + errci: &ErrorConstraintInfo<'tcx>, kind: ReturnConstraint, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; @@ -450,10 +522,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { _ => None, }; - if defined_hir.is_some() { + if let Some(def_hir) = defined_hir { let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap(); - let upvar_def_span = self.infcx.tcx.hir().span(defined_hir.unwrap()); - let upvar_span = upvars_map.get(&defined_hir.unwrap()).unwrap().span; + let upvar_def_span = self.infcx.tcx.hir().span(def_hir); + let upvar_span = upvars_map.get(&def_hir).unwrap().span; diag.span_label(upvar_def_span, "variable defined here"); diag.span_label(upvar_span, "variable captured here"); } @@ -486,7 +558,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// ``` fn report_escaping_data_error( &self, - errci: &ErrorConstraintInfo, + errci: &ErrorConstraintInfo<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let ErrorConstraintInfo { span, category, .. } = errci; @@ -548,24 +620,28 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // Only show an extra note if we can find an 'error region' for both of the region // variables. This avoids showing a noisy note that just mentions 'synthetic' regions // that don't help the user understand the error. - if self.to_error_region(errci.fr).is_some() - && self.to_error_region(errci.outlived_fr).is_some() - { - let fr_region_name = self.give_region_a_name(errci.fr).unwrap(); - fr_region_name.highlight_region_name(&mut diag); - let outlived_fr_region_name = self.give_region_a_name(errci.outlived_fr).unwrap(); - outlived_fr_region_name.highlight_region_name(&mut diag); + match (self.to_error_region(errci.fr), self.to_error_region(errci.outlived_fr)) { + (Some(f), Some(o)) => { + self.maybe_suggest_constrain_dyn_trait_impl(&mut diag, f, o, category); - diag.span_label( - *span, - format!( - "{}requires that `{}` must outlive `{}`", - category.description(), - fr_region_name, - outlived_fr_region_name, - ), - ); + let fr_region_name = self.give_region_a_name(errci.fr).unwrap(); + fr_region_name.highlight_region_name(&mut diag); + let outlived_fr_region_name = self.give_region_a_name(errci.outlived_fr).unwrap(); + outlived_fr_region_name.highlight_region_name(&mut diag); + + diag.span_label( + *span, + format!( + "{}requires that `{}` must outlive `{}`", + category.description(), + fr_region_name, + outlived_fr_region_name, + ), + ); + } + _ => {} } + diag } @@ -586,7 +662,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// ``` fn report_general_error( &self, - errci: &ErrorConstraintInfo, + errci: &ErrorConstraintInfo<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let ErrorConstraintInfo { fr, @@ -699,6 +775,100 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } + fn maybe_suggest_constrain_dyn_trait_impl( + &self, + diag: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, + f: Region<'tcx>, + o: Region<'tcx>, + category: &ConstraintCategory<'tcx>, + ) { + if !o.is_static() { + return; + } + + let tcx = self.infcx.tcx; + + let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category { + let (fn_did, substs) = match func_ty.kind() { + ty::FnDef(fn_did, substs) => (fn_did, substs), + _ => return, + }; + debug!(?fn_did, ?substs); + + // Only suggest this on function calls, not closures + let ty = tcx.type_of(fn_did); + debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind()); + if let ty::Closure(_, _) = ty.kind() { + return; + } + + if let Ok(Some(instance)) = ty::Instance::resolve( + tcx, + self.param_env, + *fn_did, + self.infcx.resolve_vars_if_possible(substs), + ) { + instance + } else { + return; + } + } else { + return; + }; + + let param = match find_param_with_region(tcx, f, o) { + Some(param) => param, + None => return, + }; + debug!(?param); + + let mut visitor = TraitObjectVisitor(FxHashSet::default()); + visitor.visit_ty(param.param_ty); + + let Some((ident, self_ty)) = + self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &visitor.0) else {return}; + + self.suggest_constrain_dyn_trait_in_impl(diag, &visitor.0, ident, self_ty); + } + + #[instrument(skip(self, err), level = "debug")] + fn suggest_constrain_dyn_trait_in_impl( + &self, + err: &mut Diagnostic, + found_dids: &FxHashSet, + ident: Ident, + self_ty: &hir::Ty<'_>, + ) -> bool { + debug!("err: {:#?}", err); + let mut suggested = false; + for found_did in found_dids { + let mut traits = vec![]; + let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did); + hir_v.visit_ty(&self_ty); + debug!("trait spans found: {:?}", traits); + for span in &traits { + let mut multi_span: MultiSpan = vec![*span].into(); + multi_span.push_span_label( + *span, + "this has an implicit `'static` lifetime requirement".to_string(), + ); + multi_span.push_span_label( + ident.span, + "calling this method introduces the `impl`'s 'static` requirement".to_string(), + ); + err.span_note(multi_span, "the used `impl` has a `'static` requirement"); + err.span_suggestion_verbose( + span.shrink_to_hi(), + "consider relaxing the implicit `'static` requirement", + " + '_", + Applicability::MaybeIncorrect, + ); + suggested = true; + } + } + suggested + } + fn suggest_adding_lifetime_params( &self, diag: &mut Diagnostic, diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index c4cef5710a..8f3699553d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -6,7 +6,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, RegionVid, Ty}; +use rustc_middle::ty::{self, DefIdTree, RegionVid, Ty}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -15,18 +15,18 @@ use crate::{nll::ToRegionVid, universal_regions::DefiningTy, MirBorrowckCtxt}; /// A name for a particular region used in emitting diagnostics. This name could be a generated /// name like `'1`, a name used by the user like `'a`, or a name like `'static`. #[derive(Debug, Clone)] -crate struct RegionName { +pub(crate) struct RegionName { /// The name of the region (interned). - crate name: Symbol, + pub(crate) name: Symbol, /// Where the region comes from. - crate source: RegionNameSource, + pub(crate) source: RegionNameSource, } /// Denotes the source of a region that is named by a `RegionName`. For example, a free region that /// was named by the user would get `NamedFreeRegion` and `'static` lifetime would get `Static`. /// This helps to print the right kinds of diagnostics. #[derive(Debug, Clone)] -crate enum RegionNameSource { +pub(crate) enum RegionNameSource { /// A bound (not free) region that was substituted at the def site (not an HRTB). NamedEarlyBoundRegion(Span), /// A free region that the user has a name (`'a`) for. @@ -45,12 +45,14 @@ crate enum RegionNameSource { AnonRegionFromYieldTy(Span, String), /// An anonymous region from an async fn. AnonRegionFromAsyncFn(Span), + /// An anonymous region from an impl self type or trait + AnonRegionFromImplSignature(Span, &'static str), } /// Describes what to highlight to explain to the user that we're giving an anonymous region a /// synthesized name, and how to highlight it. #[derive(Debug, Clone)] -crate enum RegionNameHighlight { +pub(crate) enum RegionNameHighlight { /// The anonymous region corresponds to a reference that was found by traversing the type in the HIR. MatchedHirTy(Span), /// The anonymous region corresponds to a `'_` in the generics list of a struct/enum/union. @@ -65,7 +67,7 @@ crate enum RegionNameHighlight { } impl RegionName { - crate fn was_named(&self) -> bool { + pub(crate) fn was_named(&self) -> bool { match self.source { RegionNameSource::NamedEarlyBoundRegion(..) | RegionNameSource::NamedFreeRegion(..) @@ -75,11 +77,12 @@ impl RegionName { | RegionNameSource::AnonRegionFromUpvar(..) | RegionNameSource::AnonRegionFromOutput(..) | RegionNameSource::AnonRegionFromYieldTy(..) - | RegionNameSource::AnonRegionFromAsyncFn(..) => false, + | RegionNameSource::AnonRegionFromAsyncFn(..) + | RegionNameSource::AnonRegionFromImplSignature(..) => false, } } - crate fn span(&self) -> Option { + pub(crate) fn span(&self) -> Option { match self.source { RegionNameSource::Static => None, RegionNameSource::NamedEarlyBoundRegion(span) @@ -87,7 +90,8 @@ impl RegionName { | RegionNameSource::SynthesizedFreeEnvRegion(span, _) | RegionNameSource::AnonRegionFromUpvar(span, _) | RegionNameSource::AnonRegionFromYieldTy(span, _) - | RegionNameSource::AnonRegionFromAsyncFn(span) => Some(span), + | RegionNameSource::AnonRegionFromAsyncFn(span) + | RegionNameSource::AnonRegionFromImplSignature(span, _) => Some(span), RegionNameSource::AnonRegionFromArgument(ref highlight) | RegionNameSource::AnonRegionFromOutput(ref highlight, _) => match *highlight { RegionNameHighlight::MatchedHirTy(span) @@ -98,7 +102,7 @@ impl RegionName { } } - crate fn highlight_region_name(&self, diag: &mut Diagnostic) { + pub(crate) fn highlight_region_name(&self, diag: &mut Diagnostic) { match &self.source { RegionNameSource::NamedFreeRegion(span) | RegionNameSource::NamedEarlyBoundRegion(span) => { @@ -166,6 +170,12 @@ impl RegionName { RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { diag.span_label(*span, format!("yield type is {type_name}")); } + RegionNameSource::AnonRegionFromImplSignature(span, location) => { + diag.span_label( + *span, + format!("lifetime `{self}` appears in the `impl`'s {location}"), + ); + } RegionNameSource::Static => {} } } @@ -178,11 +188,11 @@ impl Display for RegionName { } impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { - crate fn mir_def_id(&self) -> hir::def_id::LocalDefId { + pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId { self.body.source.def_id().as_local().unwrap() } - crate fn mir_hir_id(&self) -> hir::HirId { + pub(crate) fn mir_hir_id(&self) -> hir::HirId { self.infcx.tcx.hir().local_def_id_to_hir_id(self.mir_def_id()) } @@ -222,7 +232,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// ``` /// /// and then return the name `'1` for us to use. - crate fn give_region_a_name(&self, fr: RegionVid) -> Option { + pub(crate) fn give_region_a_name(&self, fr: RegionVid) -> Option { debug!( "give_region_a_name(fr={:?}, counter={:?})", fr, @@ -240,7 +250,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr)) .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr)) .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr)); + .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr)); if let Some(ref value) = value { self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone()); @@ -254,6 +265,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// *user* has a name for. In that case, we'll be able to map /// `fr` to a `Region<'tcx>`, and that region will be one of /// named variants. + #[tracing::instrument(level = "trace", skip(self))] fn give_name_from_error_region(&self, fr: RegionVid) -> Option { let error_region = self.to_error_region(fr)?; @@ -290,7 +302,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { if free_region.bound_region.is_named() { // A named region that is actually named. Some(RegionName { name, source: RegionNameSource::NamedFreeRegion(span) }) - } else { + } else if let hir::IsAsync::Async = tcx.asyncness(self.mir_hir_id().owner) { // If we spuriously thought that the region is named, we should let the // system generate a true name for error messages. Currently this can // happen if we have an elided name in an async fn for example: the @@ -301,6 +313,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { name, source: RegionNameSource::AnonRegionFromAsyncFn(span), }) + } else { + None } } @@ -311,8 +325,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // Can't have BrEnv in functions, constants or generators. bug!("BrEnv outside of closure."); }; - let hir::ExprKind::Closure(_, _, _, args_span, _) = - tcx.hir().expect_expr(self.mir_hir_id()).kind else { + let hir::ExprKind::Closure { fn_decl_span, .. } + = tcx.hir().expect_expr(self.mir_hir_id()).kind + else { bug!("Closure is not defined by a closure expr"); }; let region_name = self.synthesize_region_name(); @@ -336,7 +351,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { Some(RegionName { name: region_name, source: RegionNameSource::SynthesizedFreeEnvRegion( - args_span, + fn_decl_span, note.to_string(), ), }) @@ -361,6 +376,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// | fn foo(x: &u32) { .. } /// ------- fully elaborated type of `x` is `&'1 u32` /// ``` + #[tracing::instrument(level = "trace", skip(self))] fn give_name_if_anonymous_region_appears_in_arguments( &self, fr: RegionVid, @@ -567,15 +583,17 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let lifetime = self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?; match lifetime.name { - hir::LifetimeName::Param(_) + hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error) | hir::LifetimeName::Error - | hir::LifetimeName::Static - | hir::LifetimeName::Underscore => { + | hir::LifetimeName::Static => { let lifetime_span = lifetime.span; Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span)) } - hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit => { + hir::LifetimeName::Param(_, hir::ParamName::Fresh) + | hir::LifetimeName::ImplicitObjectLifetimeDefault + | hir::LifetimeName::Implicit + | hir::LifetimeName::Underscore => { // In this case, the user left off the lifetime; so // they wrote something like: // @@ -648,6 +666,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// | let x = Some(&22); /// - fully elaborated type of `x` is `Option<&'1 u32>` /// ``` + #[tracing::instrument(level = "trace", skip(self))] fn give_name_if_anonymous_region_appears_in_upvars(&self, fr: RegionVid) -> Option { let upvar_index = self.regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?; let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region( @@ -667,6 +686,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// must be a closure since, in a free fn, such an argument would /// have to either also appear in an argument (if using elision) /// or be early bound (named, not in argument). + #[tracing::instrument(level = "trace", skip(self))] fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option { let tcx = self.infcx.tcx; let hir = tcx.hir(); @@ -681,16 +701,16 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) { hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_, return_ty, body_id, span, _), + kind: hir::ExprKind::Closure { fn_decl, body, fn_decl_span, .. }, .. }) => { - let (mut span, mut hir_ty) = match return_ty.output { + let (mut span, mut hir_ty) = match fn_decl.output { hir::FnRetTy::DefaultReturn(_) => { - (tcx.sess.source_map().end_point(*span), None) + (tcx.sess.source_map().end_point(*fn_decl_span), None) } - hir::FnRetTy::Return(hir_ty) => (return_ty.output.span(), Some(hir_ty)), + hir::FnRetTy::Return(hir_ty) => (fn_decl.output.span(), Some(hir_ty)), }; - let mir_description = match hir.body(*body_id).generator_kind { + let mir_description = match hir.body(*body).generator_kind { Some(hir::GeneratorKind::Async(gen)) => match gen { hir::AsyncGeneratorKind::Block => " of async block", hir::AsyncGeneratorKind::Closure => " of async closure", @@ -798,6 +818,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } } + #[tracing::instrument(level = "trace", skip(self))] fn give_name_if_anonymous_region_appears_in_yield_ty( &self, fr: RegionVid, @@ -820,8 +841,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let yield_span = match tcx.hir().get(self.mir_hir_id()) { hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_, _, _, span, _), .. - }) => (tcx.sess.source_map().end_point(*span)), + kind: hir::ExprKind::Closure { fn_decl_span, .. }, + .. + }) => (tcx.sess.source_map().end_point(*fn_decl_span)), _ => self.body.span, }; @@ -836,4 +858,43 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name), }) } + + fn give_name_if_anonymous_region_appears_in_impl_signature( + &self, + fr: RegionVid, + ) -> Option { + let ty::ReEarlyBound(region) = *self.to_error_region(fr)? else { + return None; + }; + if region.has_name() { + return None; + }; + + let tcx = self.infcx.tcx; + let body_parent_did = tcx.opt_parent(self.mir_def_id().to_def_id())?; + if tcx.parent(region.def_id) != body_parent_did + || tcx.def_kind(body_parent_did) != DefKind::Impl + { + return None; + } + + let mut found = false; + tcx.fold_regions(tcx.type_of(body_parent_did), &mut true, |r: ty::Region<'tcx>, _| { + if *r == ty::ReEarlyBound(region) { + found = true; + } + r + }); + + Some(RegionName { + name: self.synthesize_region_name(), + source: RegionNameSource::AnonRegionFromImplSignature( + tcx.def_span(region.def_id), + // FIXME(compiler-errors): Does this ever actually show up + // anywhere other than the self type? I couldn't create an + // example of a `'_` in the impl's trait being referenceable. + if found { "self type" } else { "header" }, + ), + }) + } } diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs index 00f6280675..9ba29f04b1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -7,7 +7,7 @@ use rustc_span::source_map::Span; use rustc_span::symbol::Symbol; impl<'tcx> RegionInferenceContext<'tcx> { - crate fn get_var_name_and_span_for_region( + pub(crate) fn get_var_name_and_span_for_region( &self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>, @@ -34,7 +34,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Search the upvars (if any) to find one that references fr. Return its index. - crate fn get_upvar_index_for_region(&self, tcx: TyCtxt<'tcx>, fr: RegionVid) -> Option { + pub(crate) fn get_upvar_index_for_region( + &self, + tcx: TyCtxt<'tcx>, + fr: RegionVid, + ) -> Option { let upvar_index = self.universal_regions().defining_ty.upvar_tys().position(|upvar_ty| { debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty); @@ -57,7 +61,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Given the index of an upvar, finds its name and the span from where it was /// declared. - crate fn get_upvar_name_and_span_for_region( + pub(crate) fn get_upvar_name_and_span_for_region( &self, tcx: TyCtxt<'tcx>, upvars: &[Upvar<'tcx>], @@ -81,7 +85,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// /// N.B., in the case of a closure, the index is indexing into the signature as seen by the /// user - in particular, index 0 is not the implicit self parameter. - crate fn get_argument_index_for_region( + pub(crate) fn get_argument_index_for_region( &self, tcx: TyCtxt<'tcx>, fr: RegionVid, @@ -107,7 +111,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Given the index of an argument, finds its name (if any) and the span from where it was /// declared. - crate fn get_argument_name_and_span_for_region( + pub(crate) fn get_argument_name_and_span_for_region( &self, body: &Body<'tcx>, local_names: &IndexVec>, diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs index 86b719bdfa..7f0a637c9d 100644 --- a/compiler/rustc_borrowck/src/facts.rs +++ b/compiler/rustc_borrowck/src/facts.rs @@ -25,7 +25,7 @@ impl polonius_engine::FactTypes for RustcFacts { pub type AllFacts = PoloniusFacts; -crate trait AllFactsExt { +pub(crate) trait AllFactsExt { /// Returns `true` if there is a need to gather `AllFacts` given the /// current `-Z` flags. fn enabled(tcx: TyCtxt<'_>) -> bool; diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 76d240bb89..0425c53d9d 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -124,6 +124,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { ref func, ref args, destination, + target: _, cleanup: _, from_hir_call: _, fn_span: _, @@ -132,9 +133,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { for arg in args { self.consume_operand(location, arg); } - if let Some((dest, _ /*bb*/)) = destination { - self.mutate_place(location, *dest, Deep); - } + self.mutate_place(location, *destination, Deep); } TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => { self.consume_operand(location, cond); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4661805bb1..8ef2974c37 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,7 +2,6 @@ #![allow(rustc::potential_query_instability)] #![feature(box_patterns)] -#![feature(crate_visibility_modifier)] #![feature(let_chains)] #![feature(let_else)] #![feature(min_specialization)] @@ -99,7 +98,11 @@ struct Upvar<'tcx> { by_ref: bool, } -const DEREF_PROJECTION: &[PlaceElem<'_>; 1] = &[ProjectionElem::Deref]; +/// Associate some local constants with the `'tcx` lifetime +struct TyCtxtConsts<'tcx>(TyCtxt<'tcx>); +impl<'tcx> TyCtxtConsts<'tcx> { + const DEREF_PROJECTION: &'tcx [PlaceElem<'tcx>; 1] = &[ProjectionElem::Deref]; +} pub fn provide(providers: &mut Providers) { *providers = Providers { @@ -423,7 +426,7 @@ fn do_mir_borrowck<'a, 'tcx>( .span_suggestion_short( mut_span, "remove this `mut`", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -662,7 +665,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx TerminatorKind::Call { ref func, ref args, - ref destination, + destination, + target: _, cleanup: _, from_hir_call: _, fn_span: _, @@ -671,9 +675,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx for arg in args { self.consume_operand(loc, (arg, span), flow_state); } - if let Some((dest, _ /*bb*/)) = *destination { - self.mutate_place(loc, (dest, span), Deep, flow_state); - } + self.mutate_place(loc, (destination, span), Deep, flow_state); } TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => { self.consume_operand(loc, (cond, span), flow_state); @@ -1445,7 +1447,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Thread-locals might be dropped after the function exits // We have to dereference the outer reference because // borrows don't conflict behind shared references. - root_place.projection = DEREF_PROJECTION; + root_place.projection = TyCtxtConsts::DEREF_PROJECTION; (true, true) } else { (false, self.locals_are_invalidated_at_exit) diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs index c89da5514f..70a3116949 100644 --- a/compiler/rustc_borrowck/src/location.rs +++ b/compiler/rustc_borrowck/src/location.rs @@ -30,7 +30,7 @@ pub enum RichLocation { } impl LocationTable { - crate fn new(body: &Body<'_>) -> Self { + pub(crate) fn new(body: &Body<'_>) -> Self { let mut num_points = 0; let statements_before_block = body .basic_blocks() diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index f920d9d5c3..e91fcf1472 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -1,3 +1,4 @@ +use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_index::vec::IndexVec; use rustc_middle::infer::MemberConstraint; @@ -8,7 +9,7 @@ use std::ops::Index; /// Compactly stores a set of `R0 member of [R1...Rn]` constraints, /// indexed by the region `R0`. -crate struct MemberConstraintSet<'tcx, R> +pub(crate) struct MemberConstraintSet<'tcx, R> where R: Copy + Eq, { @@ -28,17 +29,17 @@ where } /// Represents a `R0 member of [R1..Rn]` constraint -crate struct NllMemberConstraint<'tcx> { +pub(crate) struct NllMemberConstraint<'tcx> { next_constraint: Option, /// The span where the hidden type was instantiated. - crate definition_span: Span, + pub(crate) definition_span: Span, /// The hidden type in which `R0` appears. (Used in error reporting.) - crate hidden_ty: Ty<'tcx>, + pub(crate) hidden_ty: Ty<'tcx>, /// The region `R0`. - crate member_region_vid: ty::RegionVid, + pub(crate) member_region_vid: ty::RegionVid, /// Index of `R1` in `choice_regions` vector from `MemberConstraintSet`. start_index: usize, @@ -48,7 +49,7 @@ crate struct NllMemberConstraint<'tcx> { } rustc_index::newtype_index! { - crate struct NllMemberConstraintIndex { + pub(crate) struct NllMemberConstraintIndex { DEBUG_FORMAT = "MemberConstraintIndex({})" } } @@ -73,7 +74,7 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> { /// within into `RegionVid` format -- it typically consults the /// `UniversalRegions` data structure that is known to the caller /// (but which this code is unaware of). - crate fn push_constraint( + pub(crate) fn push_constraint( &mut self, m_c: &MemberConstraint<'tcx>, mut to_region_vid: impl FnMut(ty::Region<'tcx>) -> ty::RegionVid, @@ -106,7 +107,7 @@ where /// the original `RegionVid` to an scc index. In some cases, we /// may have multiple `R1` values mapping to the same `R2` key -- that /// is ok, the two sets will be merged. - crate fn into_mapped( + pub(crate) fn into_mapped( self, mut map_fn: impl FnMut(R1) -> R2, ) -> MemberConstraintSet<'tcx, R2> @@ -140,21 +141,23 @@ where } } -impl MemberConstraintSet<'_, R> +impl<'tcx, R> MemberConstraintSet<'tcx, R> where R: Copy + Hash + Eq, { - crate fn all_indices(&self) -> impl Iterator + '_ { + pub(crate) fn all_indices( + &self, + ) -> impl Iterator + Captures<'tcx> + '_ { self.constraints.indices() } /// Iterate down the constraint indices associated with a given /// peek-region. You can then use `choice_regions` and other /// methods to access data. - crate fn indices( + pub(crate) fn indices( &self, member_region_vid: R, - ) -> impl Iterator + '_ { + ) -> impl Iterator + Captures<'tcx> + '_ { let mut next = self.first_constraints.get(&member_region_vid).cloned(); std::iter::from_fn(move || -> Option { if let Some(current) = next { @@ -172,7 +175,7 @@ where /// ```text /// R0 member of [R1..Rn] /// ``` - crate fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] { + pub(crate) fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] { let NllMemberConstraint { start_index, end_index, .. } = &self.constraints[pci]; &self.choice_regions[*start_index..*end_index] } diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 927eb080b2..3a919e954a 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -42,7 +42,7 @@ pub type PoloniusOutput = Output; /// The output of `nll::compute_regions`. This includes the computed `RegionInferenceContext`, any /// closure requirements to propagate, and any generated errors. -crate struct NllOutput<'tcx> { +pub(crate) struct NllOutput<'tcx> { pub regioncx: RegionInferenceContext<'tcx>, pub opaque_type_values: VecMap>, pub polonius_input: Option>, @@ -108,7 +108,7 @@ fn populate_polonius_move_facts( // We are at the terminator of an init that has a panic path, // and where the init should not happen on panic - for &successor in block_data.terminator().successors() { + for successor in block_data.terminator().successors() { if body[successor].is_cleanup { continue; } @@ -299,7 +299,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( // Solve the region constraints. let (closure_region_requirements, nll_errors) = - regioncx.solve(infcx, &body, polonius_output.clone()); + regioncx.solve(infcx, param_env, &body, polonius_output.clone()); if !nll_errors.is_empty() { // Suppress unhelpful extra errors in `infer_opaque_types`. @@ -457,6 +457,6 @@ impl ToRegionVid for RegionVid { } } -crate trait ConstraintDescription { +pub(crate) trait ConstraintDescription { fn description(&self) -> &'static str; } diff --git a/compiler/rustc_borrowck/src/place_ext.rs b/compiler/rustc_borrowck/src/place_ext.rs index 83ff1595b0..93d202e49a 100644 --- a/compiler/rustc_borrowck/src/place_ext.rs +++ b/compiler/rustc_borrowck/src/place_ext.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::{Body, Mutability, Place}; use rustc_middle::ty::{self, TyCtxt}; /// Extension methods for the `Place` type. -crate trait PlaceExt<'tcx> { +pub(crate) trait PlaceExt<'tcx> { /// Returns `true` if we can safely ignore borrows of this place. /// This is true whenever there is no action that the user can do /// to the place `self` that would invalidate the borrow. This is true diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 5a935c3b8f..97335fd0df 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -14,7 +14,7 @@ use std::iter; /// being run in the calling context, the conservative choice is to assume the compared indices /// are disjoint (and therefore, do not overlap). #[derive(Copy, Clone, Debug, Eq, PartialEq)] -crate enum PlaceConflictBias { +pub(crate) enum PlaceConflictBias { Overlap, NoOverlap, } @@ -22,7 +22,7 @@ crate enum PlaceConflictBias { /// Helper function for checking if places conflict with a mutable borrow and deep access depth. /// This is used to check for places conflicting outside of the borrow checking code (such as in /// dataflow). -crate fn places_conflict<'tcx>( +pub(crate) fn places_conflict<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, borrow_place: Place<'tcx>, diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs index 95048d50f1..f31ccd74ca 100644 --- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs +++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs @@ -11,12 +11,12 @@ use rustc_graphviz as dot; impl<'tcx> RegionInferenceContext<'tcx> { /// Write out the region constraint graph. - crate fn dump_graphviz_raw_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> { + pub(crate) fn dump_graphviz_raw_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> { dot::render(&RawConstraints { regioncx: self }, &mut w) } /// Write out the region constraint graph. - crate fn dump_graphviz_scc_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> { + pub(crate) fn dump_graphviz_scc_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> { let mut nodes_per_scc: IndexVec = self.constraint_sccs.all_sccs().map(|_| Vec::new()).collect(); diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index b2fa16ce12..44a0e6205b 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -10,7 +10,8 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::CRATE_HIR_ID; use rustc_index::vec::IndexVec; use rustc_infer::infer::canonical::QueryOutlivesConstraint; -use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound}; +use rustc_infer::infer::outlives::test_type_match; +use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; use rustc_middle::mir::{ Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, @@ -46,6 +47,7 @@ pub mod values; pub struct RegionInferenceContext<'tcx> { pub var_infos: VarInfos, + /// Contains the definition for every region variable. Region /// variables are identified by their index (`RegionVid`). The /// definition contains information about where the region came @@ -87,7 +89,7 @@ pub struct RegionInferenceContext<'tcx> { /// Map closure bounds to a `Span` that should be used for error reporting. closure_bounds_mapping: - FxHashMap>, + FxHashMap, Span)>>, /// Map universe indexes to information on why we created it. universe_causes: FxHashMap>, @@ -259,7 +261,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, closure_bounds_mapping: FxHashMap< Location, - FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>, + FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>, >, universe_causes: FxHashMap>, type_tests: Vec>, @@ -500,7 +502,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Returns an iterator over all the region indices. - pub fn regions(&self) -> impl Iterator + '_ { + pub fn regions(&self) -> impl Iterator + 'tcx { self.definitions.indices() } @@ -513,26 +515,26 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`. - crate fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { + pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { self.universal_regions.annotate(tcx, err) } /// Returns `true` if the region `r` contains the point `p`. /// /// Panics if called before `solve()` executes, - crate fn region_contains(&self, r: impl ToRegionVid, p: impl ToElementIndex) -> bool { + pub(crate) fn region_contains(&self, r: impl ToRegionVid, p: impl ToElementIndex) -> bool { let scc = self.constraint_sccs.scc(r.to_region_vid()); self.scc_values.contains(scc, p) } /// Returns access to the value of `r` for debugging purposes. - crate fn region_value_str(&self, r: RegionVid) -> String { + pub(crate) fn region_value_str(&self, r: RegionVid) -> String { let scc = self.constraint_sccs.scc(r.to_region_vid()); self.scc_values.region_value_str(scc) } /// Returns access to the value of `r` for debugging purposes. - crate fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex { + pub(crate) fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex { let scc = self.constraint_sccs.scc(r.to_region_vid()); self.scc_universes[scc] } @@ -559,6 +561,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(super) fn solve( &mut self, infcx: &InferCtxt<'_, 'tcx>, + param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, polonius_output: Option>, ) -> (Option>, RegionErrors<'tcx>) { @@ -574,7 +577,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { // eagerly. let mut outlives_requirements = infcx.tcx.is_typeck_child(mir_def_id).then(Vec::new); - self.check_type_tests(infcx, body, outlives_requirements.as_mut(), &mut errors_buffer); + self.check_type_tests( + infcx, + param_env, + body, + outlives_requirements.as_mut(), + &mut errors_buffer, + ); // In Polonius mode, the errors about missing universal region relations are in the output // and need to be emitted or propagated. Otherwise, we need to check whether the @@ -823,6 +832,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn check_type_tests( &self, infcx: &InferCtxt<'_, 'tcx>, + param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, mut propagated_outlives_requirements: Option<&mut Vec>>, errors_buffer: &mut RegionErrors<'tcx>, @@ -839,7 +849,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { let generic_ty = type_test.generic_kind.to_ty(tcx); if self.eval_verify_bound( - tcx, + infcx, + param_env, body, generic_ty, type_test.lower_bound, @@ -851,6 +862,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements { if self.try_promote_type_test( infcx, + param_env, body, type_test, propagated_outlives_requirements, @@ -904,9 +916,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// The idea then is to lower the `T: 'X` constraint into multiple /// bounds -- e.g., if `'X` is the union of two free lifetimes, /// `'1` and `'2`, then we would create `T: '1` and `T: '2`. + #[instrument(level = "debug", skip(self, infcx, propagated_outlives_requirements))] fn try_promote_type_test( &self, infcx: &InferCtxt<'_, 'tcx>, + param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, type_test: &TypeTest<'tcx>, propagated_outlives_requirements: &mut Vec>, @@ -920,11 +934,41 @@ impl<'tcx> RegionInferenceContext<'tcx> { return false; }; + debug!("subject = {:?}", subject); + + let r_scc = self.constraint_sccs.scc(*lower_bound); + + debug!( + "lower_bound = {:?} r_scc={:?} universe={:?}", + lower_bound, r_scc, self.scc_universes[r_scc] + ); + + // If the type test requires that `T: 'a` where `'a` is a + // placeholder from another universe, that effectively requires + // `T: 'static`, so we have to propagate that requirement. + // + // It doesn't matter *what* universe because the promoted `T` will + // always be in the root universe. + if let Some(p) = self.scc_values.placeholders_contained_in(r_scc).next() { + debug!("encountered placeholder in higher universe: {:?}, requiring 'static", p); + let static_r = self.universal_regions.fr_static; + propagated_outlives_requirements.push(ClosureOutlivesRequirement { + subject, + outlived_free_region: static_r, + blame_span: locations.span(body), + category: ConstraintCategory::Boring, + }); + + // we can return here -- the code below might push add'l constraints + // but they would all be weaker than this one. + return true; + } + // For each region outlived by lower_bound find a non-local, // universal region (it may be the same region) and add it to // `ClosureOutlivesRequirement`. - let r_scc = self.constraint_sccs.scc(*lower_bound); for ur in self.scc_values.universal_regions_outlived_by(r_scc) { + debug!("universal_region_outlived_by ur={:?}", ur); // Check whether we can already prove that the "subject" outlives `ur`. // If so, we don't have to propagate this requirement to our caller. // @@ -938,12 +982,17 @@ impl<'tcx> RegionInferenceContext<'tcx> { // where `ur` is a local bound -- we are sometimes in a // position to prove things that our caller cannot. See // #53570 for an example. - if self.eval_verify_bound(tcx, body, generic_ty, ur, &type_test.verify_bound) { + if self.eval_verify_bound( + infcx, + param_env, + body, + generic_ty, + ur, + &type_test.verify_bound, + ) { continue; } - debug!("try_promote_type_test: ur={:?}", ur); - let non_local_ub = self.universal_region_relations.non_local_upper_bounds(ur); debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub); @@ -980,6 +1029,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// will use it's *external name*, which will be a `RegionKind` /// variant that can be used in query responses such as /// `ReEarlyBound`. + #[instrument(level = "debug", skip(self, infcx))] fn try_promote_type_test_subject( &self, infcx: &InferCtxt<'_, 'tcx>, @@ -987,8 +1037,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) -> Option> { let tcx = infcx.tcx; - debug!("try_promote_type_test_subject(ty = {:?})", ty); - let ty = tcx.fold_regions(ty, &mut false, |r, _depth| { let region_vid = self.to_region_vid(r); @@ -1161,7 +1209,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// `point`. fn eval_verify_bound( &self, - tcx: TyCtxt<'tcx>, + infcx: &InferCtxt<'_, 'tcx>, + param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, generic_ty: Ty<'tcx>, lower_bound: RegionVid, @@ -1170,8 +1219,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("eval_verify_bound(lower_bound={:?}, verify_bound={:?})", lower_bound, verify_bound); match verify_bound { - VerifyBound::IfEq(test_ty, verify_bound1) => { - self.eval_if_eq(tcx, body, generic_ty, lower_bound, *test_ty, verify_bound1) + VerifyBound::IfEq(verify_if_eq_b) => { + self.eval_if_eq(infcx, param_env, generic_ty, lower_bound, *verify_if_eq_b) } VerifyBound::IsEmpty => { @@ -1185,30 +1234,50 @@ impl<'tcx> RegionInferenceContext<'tcx> { } VerifyBound::AnyBound(verify_bounds) => verify_bounds.iter().any(|verify_bound| { - self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound) + self.eval_verify_bound( + infcx, + param_env, + body, + generic_ty, + lower_bound, + verify_bound, + ) }), VerifyBound::AllBounds(verify_bounds) => verify_bounds.iter().all(|verify_bound| { - self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound) + self.eval_verify_bound( + infcx, + param_env, + body, + generic_ty, + lower_bound, + verify_bound, + ) }), } } fn eval_if_eq( &self, - tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, + infcx: &InferCtxt<'_, 'tcx>, + param_env: ty::ParamEnv<'tcx>, generic_ty: Ty<'tcx>, lower_bound: RegionVid, - test_ty: Ty<'tcx>, - verify_bound: &VerifyBound<'tcx>, + verify_if_eq_b: ty::Binder<'tcx, VerifyIfEq<'tcx>>, ) -> bool { - let generic_ty_normalized = self.normalize_to_scc_representatives(tcx, generic_ty); - let test_ty_normalized = self.normalize_to_scc_representatives(tcx, test_ty); - if generic_ty_normalized == test_ty_normalized { - self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound) - } else { - false + let generic_ty = self.normalize_to_scc_representatives(infcx.tcx, generic_ty); + let verify_if_eq_b = self.normalize_to_scc_representatives(infcx.tcx, verify_if_eq_b); + match test_type_match::extract_verify_if_eq( + infcx.tcx, + param_env, + &verify_if_eq_b, + generic_ty, + ) { + Some(r) => { + let r_vid = self.to_region_vid(r); + self.eval_outlives(r_vid, lower_bound) + } + None => false, } } @@ -1278,6 +1347,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { let sub_region_scc = self.constraint_sccs.scc(sub_region); let sup_region_scc = self.constraint_sccs.scc(sup_region); + // If we are checking that `'sup: 'sub`, and `'sub` contains + // some placeholder that `'sup` cannot name, then this is only + // true if `'sup` outlives static. + if !self.universe_compatible(sub_region_scc, sup_region_scc) { + debug!( + "eval_outlives: sub universe `{sub_region_scc:?}` is not nameable \ + by super `{sup_region_scc:?}`, promoting to static", + ); + + return self.eval_outlives(sup_region, self.universal_regions.fr_static); + } + // Both the `sub_region` and `sup_region` consist of the union // of some number of universal regions (along with the union // of various points in the CFG; ignore those points for @@ -1292,6 +1373,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); if !universal_outlives { + debug!( + "eval_outlives: returning false because sub region contains a universal region not present in super" + ); return false; } @@ -1300,10 +1384,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { if self.universal_regions.is_universal_region(sup_region) { // Micro-opt: universal regions contain all points. + debug!( + "eval_outlives: returning true because super is universal and hence contains all points" + ); return true; } - self.scc_values.contains_points(sup_region_scc, sub_region_scc) + let result = self.scc_values.contains_points(sup_region_scc, sub_region_scc); + debug!("returning {} because of comparison between points in sup/sub", result); + result } /// Once regions have been propagated, this method is used to see @@ -1693,7 +1782,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// that cannot be named by `fr1`; in that case, we will require /// that `fr1: 'static` because it is the only way to `fr1: r` to /// be satisfied. (See `add_incompatible_universe`.) - crate fn provides_universal_region( + pub(crate) fn provides_universal_region( &self, r: RegionVid, fr1: RegionVid, @@ -1712,7 +1801,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// If `r2` represents a placeholder region, then this returns /// `true` if `r1` cannot name that placeholder in its /// value; otherwise, returns `false`. - crate fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool { + pub(crate) fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool { debug!("cannot_name_value_of(r1={:?}, r2={:?})", r1, r2); match self.definitions[r2].origin { @@ -1731,7 +1820,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - crate fn retrieve_closure_constraint_info( + pub(crate) fn retrieve_closure_constraint_info( &self, _body: &Body<'tcx>, constraint: &OutlivesConstraint<'tcx>, @@ -1766,13 +1855,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`. - crate fn find_outlives_blame_span( + pub(crate) fn find_outlives_blame_span( &self, body: &Body<'tcx>, fr1: RegionVid, fr1_origin: NllRegionVariableOrigin, fr2: RegionVid, - ) -> (ConstraintCategory, ObligationCause<'tcx>) { + ) -> (ConstraintCategory<'tcx>, ObligationCause<'tcx>) { let BlameConstraint { category, cause, .. } = self.best_blame_constraint(body, fr1, fr1_origin, |r| { self.provides_universal_region(r, fr1, fr2) @@ -1788,7 +1877,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// /// Returns: a series of constraints as well as the region `R` /// that passed the target test. - crate fn find_constraint_paths_between_regions( + pub(crate) fn find_constraint_paths_between_regions( &self, from_region: RegionVid, target_test: impl Fn(RegionVid) -> bool, @@ -1882,7 +1971,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Finds some region R such that `fr1: R` and `R` is live at `elem`. #[instrument(skip(self), level = "trace")] - crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid { + pub(crate) fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid { trace!(scc = ?self.constraint_sccs.scc(fr1)); trace!(universe = ?self.scc_universes[self.constraint_sccs.scc(fr1)]); self.find_constraint_paths_between_regions(fr1, |r| { @@ -1919,7 +2008,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Get the region outlived by `longer_fr` and live at `element`. - crate fn region_from_element( + pub(crate) fn region_from_element( &self, longer_fr: RegionVid, element: &RegionElement, @@ -1939,17 +2028,17 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Get the region definition of `r`. - crate fn region_definition(&self, r: RegionVid) -> &RegionDefinition<'tcx> { + pub(crate) fn region_definition(&self, r: RegionVid) -> &RegionDefinition<'tcx> { &self.definitions[r] } /// Check if the SCC of `r` contains `upper`. - crate fn upper_bound_in_region_scc(&self, r: RegionVid, upper: RegionVid) -> bool { + pub(crate) fn upper_bound_in_region_scc(&self, r: RegionVid, upper: RegionVid) -> bool { let r_scc = self.constraint_sccs.scc(r); self.scc_values.contains(r_scc, upper) } - crate fn universal_regions(&self) -> &UniversalRegions<'tcx> { + pub(crate) fn universal_regions(&self) -> &UniversalRegions<'tcx> { self.universal_regions.as_ref() } @@ -1959,7 +2048,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// creating a constraint path that forces `R` to outlive /// `from_region`, and then finding the best choices within that /// path to blame. - crate fn best_blame_constraint( + pub(crate) fn best_blame_constraint( &self, body: &Body<'tcx>, from_region: RegionVid, @@ -2171,7 +2260,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { categorized_path.remove(0) } - crate fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { + pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { self.universe_causes[&universe].clone() } } @@ -2270,7 +2359,7 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx #[derive(Clone, Debug)] pub struct BlameConstraint<'tcx> { - pub category: ConstraintCategory, + pub category: ConstraintCategory<'tcx>, pub from_closure: bool, pub cause: ObligationCause<'tcx>, pub variance_info: ty::VarianceDiagInfo<'tcx>, diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index 056907dcb1..1e6798eee3 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::RegionVid; use std::ops::Range; use std::rc::Rc; -crate struct ReverseSccGraph { +pub(crate) struct ReverseSccGraph { graph: VecGraph, /// For each SCC, the range of `universal_regions` that use that SCC as /// their value. diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 4a70535c63..c81ef10f7c 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -10,7 +10,7 @@ use std::fmt::Debug; use std::rc::Rc; /// Maps between a `Location` and a `PointIndex` (and vice versa). -crate struct RegionValueElements { +pub(crate) struct RegionValueElements { /// For each basic block, how many points are contained within? statements_before_block: IndexVec, @@ -22,7 +22,7 @@ crate struct RegionValueElements { } impl RegionValueElements { - crate fn new(body: &Body<'_>) -> Self { + pub(crate) fn new(body: &Body<'_>) -> Self { let mut num_points = 0; let statements_before_block: IndexVec = body .basic_blocks() @@ -45,30 +45,30 @@ impl RegionValueElements { } /// Total number of point indices - crate fn num_points(&self) -> usize { + pub(crate) fn num_points(&self) -> usize { self.num_points } /// Converts a `Location` into a `PointIndex`. O(1). - crate fn point_from_location(&self, location: Location) -> PointIndex { + pub(crate) fn point_from_location(&self, location: Location) -> PointIndex { let Location { block, statement_index } = location; let start_index = self.statements_before_block[block]; PointIndex::new(start_index + statement_index) } /// Converts a `Location` into a `PointIndex`. O(1). - crate fn entry_point(&self, block: BasicBlock) -> PointIndex { + pub(crate) fn entry_point(&self, block: BasicBlock) -> PointIndex { let start_index = self.statements_before_block[block]; PointIndex::new(start_index) } /// Return the PointIndex for the block start of this index. - crate fn to_block_start(&self, index: PointIndex) -> PointIndex { + pub(crate) fn to_block_start(&self, index: PointIndex) -> PointIndex { PointIndex::new(self.statements_before_block[self.basic_blocks[index]]) } /// Converts a `PointIndex` back to a location. O(1). - crate fn to_location(&self, index: PointIndex) -> Location { + pub(crate) fn to_location(&self, index: PointIndex) -> Location { assert!(index.index() < self.num_points); let block = self.basic_blocks[index]; let start_index = self.statements_before_block[block]; @@ -80,7 +80,7 @@ impl RegionValueElements { /// out of range (because they round up to the nearest 2^N number /// of bits). Use this function to filter such points out if you /// like. - crate fn point_in_range(&self, index: PointIndex) -> bool { + pub(crate) fn point_in_range(&self, index: PointIndex) -> bool { index.index() < self.num_points } } @@ -99,7 +99,7 @@ rustc_index::newtype_index! { /// An individual element in a region value -- the value of a /// particular region variable consists of a set of these elements. #[derive(Debug, Clone)] -crate enum RegionElement { +pub(crate) enum RegionElement { /// A point in the control-flow graph. Location(Location), @@ -114,7 +114,7 @@ crate enum RegionElement { /// When we initially compute liveness, we use an interval matrix storing /// liveness ranges for each region-vid. -crate struct LivenessValues { +pub(crate) struct LivenessValues { elements: Rc, points: SparseIntervalMatrix, } @@ -123,18 +123,18 @@ impl LivenessValues { /// Creates a new set of "region values" that tracks causal information. /// Each of the regions in num_region_variables will be initialized with an /// empty set of points and no causal information. - crate fn new(elements: Rc) -> Self { + pub(crate) fn new(elements: Rc) -> Self { Self { points: SparseIntervalMatrix::new(elements.num_points), elements } } /// Iterate through each region that has a value in this set. - crate fn rows(&self) -> impl Iterator { + pub(crate) fn rows(&self) -> impl Iterator { self.points.rows() } /// Adds the given element to the value for the given region. Returns whether /// the element is newly added (i.e., was not already present). - crate fn add_element(&mut self, row: N, location: Location) -> bool { + pub(crate) fn add_element(&mut self, row: N, location: Location) -> bool { debug!("LivenessValues::add(r={:?}, location={:?})", row, location); let index = self.elements.point_from_location(location); self.points.insert(row, index) @@ -142,24 +142,24 @@ impl LivenessValues { /// Adds all the elements in the given bit array into the given /// region. Returns whether any of them are newly added. - crate fn add_elements(&mut self, row: N, locations: &IntervalSet) -> bool { + pub(crate) fn add_elements(&mut self, row: N, locations: &IntervalSet) -> bool { debug!("LivenessValues::add_elements(row={:?}, locations={:?})", row, locations); self.points.union_row(row, locations) } /// Adds all the control-flow points to the values for `r`. - crate fn add_all_points(&mut self, row: N) { + pub(crate) fn add_all_points(&mut self, row: N) { self.points.insert_all_into_row(row); } /// Returns `true` if the region `r` contains the given element. - crate fn contains(&self, row: N, location: Location) -> bool { + pub(crate) fn contains(&self, row: N, location: Location) -> bool { let index = self.elements.point_from_location(location); self.points.row(row).map_or(false, |r| r.contains(index)) } /// Returns an iterator of all the elements contained by the region `r` - crate fn get_elements(&self, row: N) -> impl Iterator + '_ { + pub(crate) fn get_elements(&self, row: N) -> impl Iterator + '_ { self.points .row(row) .into_iter() @@ -169,7 +169,7 @@ impl LivenessValues { } /// Returns a "pretty" string value of the region. Meant for debugging. - crate fn region_value_str(&self, r: N) -> String { + pub(crate) fn region_value_str(&self, r: N) -> String { region_value_str(self.get_elements(r).map(RegionElement::Location)) } } @@ -178,25 +178,28 @@ impl LivenessValues { /// rustc to the internal `PlaceholderIndex` values that are used in /// NLL. #[derive(Default)] -crate struct PlaceholderIndices { +pub(crate) struct PlaceholderIndices { indices: FxIndexSet, } impl PlaceholderIndices { - crate fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { + pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { let (index, _) = self.indices.insert_full(placeholder); index.into() } - crate fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { + pub(crate) fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { self.indices.get_index_of(&placeholder).unwrap().into() } - crate fn lookup_placeholder(&self, placeholder: PlaceholderIndex) -> ty::PlaceholderRegion { + pub(crate) fn lookup_placeholder( + &self, + placeholder: PlaceholderIndex, + ) -> ty::PlaceholderRegion { self.indices[placeholder.index()] } - crate fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { self.indices.len() } } @@ -220,7 +223,7 @@ impl PlaceholderIndices { /// because (since it is returned) it must live for at least `'a`. But /// it would also contain various points from within the function. #[derive(Clone)] -crate struct RegionValues { +pub(crate) struct RegionValues { elements: Rc, placeholder_indices: Rc, points: SparseIntervalMatrix, @@ -235,7 +238,7 @@ impl RegionValues { /// Creates a new set of "region values" that tracks causal information. /// Each of the regions in num_region_variables will be initialized with an /// empty set of points and no causal information. - crate fn new( + pub(crate) fn new( elements: &Rc, num_universal_regions: usize, placeholder_indices: &Rc, @@ -252,33 +255,33 @@ impl RegionValues { /// Adds the given element to the value for the given region. Returns whether /// the element is newly added (i.e., was not already present). - crate fn add_element(&mut self, r: N, elem: impl ToElementIndex) -> bool { + pub(crate) fn add_element(&mut self, r: N, elem: impl ToElementIndex) -> bool { debug!("add(r={:?}, elem={:?})", r, elem); elem.add_to_row(self, r) } /// Adds all the control-flow points to the values for `r`. - crate fn add_all_points(&mut self, r: N) { + pub(crate) fn add_all_points(&mut self, r: N) { self.points.insert_all_into_row(r); } /// Adds all elements in `r_from` to `r_to` (because e.g., `r_to: /// r_from`). - crate fn add_region(&mut self, r_to: N, r_from: N) -> bool { + pub(crate) fn add_region(&mut self, r_to: N, r_from: N) -> bool { self.points.union_rows(r_from, r_to) | self.free_regions.union_rows(r_from, r_to) | self.placeholders.union_rows(r_from, r_to) } /// Returns `true` if the region `r` contains the given element. - crate fn contains(&self, r: N, elem: impl ToElementIndex) -> bool { + pub(crate) fn contains(&self, r: N, elem: impl ToElementIndex) -> bool { elem.contained_in_row(self, r) } /// `self[to] |= values[from]`, essentially: that is, take all the /// elements for the region `from` from `values` and add them to /// the region `to` in `self`. - crate fn merge_liveness(&mut self, to: N, from: M, values: &LivenessValues) { + pub(crate) fn merge_liveness(&mut self, to: N, from: M, values: &LivenessValues) { if let Some(set) = values.points.row(from) { self.points.union_row(to, set); } @@ -286,7 +289,7 @@ impl RegionValues { /// Returns `true` if `sup_region` contains all the CFG points that /// `sub_region` contains. Ignores universal regions. - crate fn contains_points(&self, sup_region: N, sub_region: N) -> bool { + pub(crate) fn contains_points(&self, sup_region: N, sub_region: N) -> bool { if let Some(sub_row) = self.points.row(sub_region) { if let Some(sup_row) = self.points.row(sup_region) { sup_row.superset(sub_row) @@ -301,7 +304,7 @@ impl RegionValues { } /// Returns the locations contained within a given region `r`. - crate fn locations_outlived_by<'a>(&'a self, r: N) -> impl Iterator + 'a { + pub(crate) fn locations_outlived_by<'a>(&'a self, r: N) -> impl Iterator + 'a { self.points.row(r).into_iter().flat_map(move |set| { set.iter() .take_while(move |&p| self.elements.point_in_range(p)) @@ -310,7 +313,7 @@ impl RegionValues { } /// Returns just the universal regions that are contained in a given region's value. - crate fn universal_regions_outlived_by<'a>( + pub(crate) fn universal_regions_outlived_by<'a>( &'a self, r: N, ) -> impl Iterator + 'a { @@ -318,7 +321,7 @@ impl RegionValues { } /// Returns all the elements contained in a given region's value. - crate fn placeholders_contained_in<'a>( + pub(crate) fn placeholders_contained_in<'a>( &'a self, r: N, ) -> impl Iterator + 'a { @@ -330,7 +333,10 @@ impl RegionValues { } /// Returns all the elements contained in a given region's value. - crate fn elements_contained_in<'a>(&'a self, r: N) -> impl Iterator + 'a { + pub(crate) fn elements_contained_in<'a>( + &'a self, + r: N, + ) -> impl Iterator + 'a { let points_iter = self.locations_outlived_by(r).map(RegionElement::Location); let free_regions_iter = @@ -343,12 +349,12 @@ impl RegionValues { } /// Returns a "pretty" string value of the region. Meant for debugging. - crate fn region_value_str(&self, r: N) -> String { + pub(crate) fn region_value_str(&self, r: N) -> String { region_value_str(self.elements_contained_in(r)) } } -crate trait ToElementIndex: Debug + Copy { +pub(crate) trait ToElementIndex: Debug + Copy { fn add_to_row(self, values: &mut RegionValues, row: N) -> bool; fn contained_in_row(self, values: &RegionValues, row: N) -> bool; @@ -388,7 +394,7 @@ impl ToElementIndex for ty::PlaceholderRegion { } } -crate fn location_set_str( +pub(crate) fn location_set_str( elements: &RegionValueElements, points: impl IntoIterator, ) -> String { diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 3856b7f4a4..55c0bf05b4 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -28,7 +28,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { pub(super) fn fully_perform_op( &mut self, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, op: Op, ) -> Fallible where @@ -83,11 +83,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { instantiated } + #[instrument(skip(self), level = "debug")] pub(super) fn prove_trait_ref( &mut self, trait_ref: ty::TraitRef<'tcx>, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, ) { self.prove_predicates( Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { @@ -113,6 +114,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .into_iter() .zip(instantiated_predicates.spans.into_iter()) { + debug!(?predicate); let predicate = self.normalize(predicate, locations); self.prove_predicate(predicate, locations, ConstraintCategory::Predicate(span)); } @@ -122,7 +124,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &mut self, predicates: impl IntoIterator>, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, ) { for predicate in predicates { let predicate = predicate.to_predicate(self.tcx()); @@ -137,7 +139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &mut self, predicate: ty::Predicate<'tcx>, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, ) { let param_env = self.param_env; self.fully_perform_op( diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 21190a850b..3c9e3870ae 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -18,7 +18,7 @@ use crate::{ universal_regions::UniversalRegions, }; -crate struct ConstraintConversion<'a, 'tcx> { +pub(crate) struct ConstraintConversion<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, tcx: TyCtxt<'tcx>, universal_regions: &'a UniversalRegions<'tcx>, @@ -27,12 +27,12 @@ crate struct ConstraintConversion<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, locations: Locations, span: Span, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, } impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { - crate fn new( + pub(crate) fn new( infcx: &'a InferCtxt<'a, 'tcx>, universal_regions: &'a UniversalRegions<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, @@ -40,7 +40,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, locations: Locations, span: Span, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, ) -> Self { Self { diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index f08f2e1b12..813307356c 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -19,7 +19,7 @@ use crate::{ }; #[derive(Debug)] -crate struct UniversalRegionRelations<'tcx> { +pub(crate) struct UniversalRegionRelations<'tcx> { universal_regions: Rc>, /// Stores the outlives relations that are known to hold from the @@ -52,13 +52,13 @@ type RegionBoundPairs<'tcx> = Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>; /// then the output type as the last element. type NormalizedInputsAndOutput<'tcx> = Vec>; -crate struct CreateResult<'tcx> { - crate universal_region_relations: Frozen>, - crate region_bound_pairs: RegionBoundPairs<'tcx>, - crate normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>, +pub(crate) struct CreateResult<'tcx> { + pub(crate) universal_region_relations: Frozen>, + pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>, + pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>, } -crate fn create<'tcx>( +pub(crate) fn create<'tcx>( infcx: &InferCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, implicit_region_bound: Option>, @@ -96,7 +96,7 @@ impl UniversalRegionRelations<'_> { /// /// (See `TransitiveRelation::postdom_upper_bound` for details on /// the postdominating upper bound in general.) - crate fn postdom_upper_bound(&self, fr1: RegionVid, fr2: RegionVid) -> RegionVid { + pub(crate) fn postdom_upper_bound(&self, fr1: RegionVid, fr2: RegionVid) -> RegionVid { assert!(self.universal_regions.is_universal_region(fr1)); assert!(self.universal_regions.is_universal_region(fr2)); self.inverse_outlives @@ -109,7 +109,7 @@ impl UniversalRegionRelations<'_> { /// outlives `fr` and (b) is not local. /// /// (*) If there are multiple competing choices, we return all of them. - crate fn non_local_upper_bounds<'a>(&'a self, fr: RegionVid) -> Vec { + pub(crate) fn non_local_upper_bounds<'a>(&'a self, fr: RegionVid) -> Vec { debug!("non_local_upper_bound(fr={:?})", fr); let res = self.non_local_bounds(&self.inverse_outlives, fr); assert!(!res.is_empty(), "can't find an upper bound!?"); @@ -118,7 +118,7 @@ impl UniversalRegionRelations<'_> { /// Returns the "postdominating" bound of the set of /// `non_local_upper_bounds` for the given region. - crate fn non_local_upper_bound(&self, fr: RegionVid) -> RegionVid { + pub(crate) fn non_local_upper_bound(&self, fr: RegionVid) -> RegionVid { let upper_bounds = self.non_local_upper_bounds(fr); // In case we find more than one, reduce to one for @@ -147,7 +147,7 @@ impl UniversalRegionRelations<'_> { /// /// (*) If there are multiple competing choices, we pick the "postdominating" /// one. See `TransitiveRelation::postdom_upper_bound` for details. - crate fn non_local_lower_bound(&self, fr: RegionVid) -> Option { + pub(crate) fn non_local_lower_bound(&self, fr: RegionVid) -> Option { debug!("non_local_lower_bound(fr={:?})", fr); let lower_bounds = self.non_local_bounds(&self.outlives, fr); @@ -203,18 +203,18 @@ impl UniversalRegionRelations<'_> { /// Returns `true` if fr1 is known to outlive fr2. /// /// This will only ever be true for universally quantified regions. - crate fn outlives(&self, fr1: RegionVid, fr2: RegionVid) -> bool { + pub(crate) fn outlives(&self, fr1: RegionVid, fr2: RegionVid) -> bool { self.outlives.contains(fr1, fr2) } /// Returns a vector of free regions `x` such that `fr1: x` is /// known to hold. - crate fn regions_outlived_by(&self, fr1: RegionVid) -> Vec { + pub(crate) fn regions_outlived_by(&self, fr1: RegionVid) -> Vec { self.outlives.reachable_from(fr1) } /// Returns the _non-transitive_ set of known `outlives` constraints between free regions. - crate fn known_outlives(&self) -> impl Iterator + '_ { + pub(crate) fn known_outlives(&self) -> impl Iterator + '_ { self.outlives.base_edges() } } @@ -232,7 +232,7 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> { } impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { - crate fn create(mut self) -> CreateResult<'tcx> { + pub(crate) fn create(mut self) -> CreateResult<'tcx> { let unnormalized_input_output_tys = self .universal_regions .unnormalized_input_tys @@ -334,8 +334,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { /// either the return type of the MIR or one of its arguments. At /// the same time, compute and add any implied bounds that come /// from this local. + #[instrument(level = "debug", skip(self))] fn add_implied_bounds(&mut self, ty: Ty<'tcx>) -> Option>> { - debug!("add_implied_bounds(ty={:?})", ty); let TypeOpOutput { output: bounds, constraints, .. } = self .param_env .and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty }) diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index e6f996491a..2259a59e19 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -60,13 +60,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // Replace the bound items in the fn sig with fresh // variables, so that they represent the view from // "inside" the closure. - self.infcx - .replace_bound_vars_with_fresh_vars( - body.span, - LateBoundRegionConversionTime::FnCall, - poly_sig, - ) - .0 + self.infcx.replace_bound_vars_with_fresh_vars( + body.span, + LateBoundRegionConversionTime::FnCall, + poly_sig, + ) }, ); } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs index dd23683fae..b88f6e689c 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs @@ -18,7 +18,7 @@ use crate::region_infer::values::{PointIndex, RegionValueElements}; /// (and code simplicity) was favored. The rationale is that we only keep /// a small number of `IndexVec`s throughout the entire analysis while, in /// contrast, we're accessing each `Local` *many* times. -crate struct LocalUseMap { +pub(crate) struct LocalUseMap { /// Head of a linked list of **definitions** of each variable -- /// definition in this context means assignment, e.g., `x` is /// defined in `x = y` but not `y`; that first def is the head of @@ -58,7 +58,11 @@ impl vll::LinkElem for Appearance { } impl LocalUseMap { - crate fn build(live_locals: &[Local], elements: &RegionValueElements, body: &Body<'_>) -> Self { + pub(crate) fn build( + live_locals: &[Local], + elements: &RegionValueElements, + body: &Body<'_>, + ) -> Self { let nones = IndexVec::from_elem_n(None, body.local_decls.len()); let mut local_use_map = LocalUseMap { first_def_at: nones.clone(), @@ -81,17 +85,17 @@ impl LocalUseMap { local_use_map } - crate fn defs(&self, local: Local) -> impl Iterator + '_ { + pub(crate) fn defs(&self, local: Local) -> impl Iterator + '_ { vll::iter(self.first_def_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } - crate fn uses(&self, local: Local) -> impl Iterator + '_ { + pub(crate) fn uses(&self, local: Local) -> impl Iterator + '_ { vll::iter(self.first_use_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } - crate fn drops(&self, local: Local) -> impl Iterator + '_ { + pub(crate) fn drops(&self, local: Local) -> impl Iterator + '_ { vll::iter(self.first_drop_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs index ee067c4872..8070f35791 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs @@ -10,17 +10,17 @@ use super::TypeChecker; type VarPointRelation = Vec<(Local, LocationIndex)>; type PathPointRelation = Vec<(MovePathIndex, LocationIndex)>; -struct UseFactsExtractor<'me> { +struct UseFactsExtractor<'me, 'tcx> { var_defined_at: &'me mut VarPointRelation, var_used_at: &'me mut VarPointRelation, location_table: &'me LocationTable, var_dropped_at: &'me mut VarPointRelation, - move_data: &'me MoveData<'me>, + move_data: &'me MoveData<'tcx>, path_accessed_at_base: &'me mut PathPointRelation, } // A Visitor to walk through the MIR and extract point-wise facts -impl UseFactsExtractor<'_> { +impl UseFactsExtractor<'_, '_> { fn location_to_index(&self, location: Location) -> LocationIndex { self.location_table.mid_index(location) } @@ -53,7 +53,7 @@ impl UseFactsExtractor<'_> { } } -impl Visitor<'_> for UseFactsExtractor<'_> { +impl<'a, 'tcx> Visitor<'tcx> for UseFactsExtractor<'a, 'tcx> { fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) { match def_use::categorize(context) { Some(DefUse::Def) => self.insert_def(local, location), @@ -63,7 +63,7 @@ impl Visitor<'_> for UseFactsExtractor<'_> { } } - fn visit_place(&mut self, place: &Place<'_>, context: PlaceContext, location: Location) { + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { self.super_place(place, context, location); match context { PlaceContext::NonMutatingUse(_) => { @@ -82,11 +82,11 @@ impl Visitor<'_> for UseFactsExtractor<'_> { } } -pub(super) fn populate_access_facts<'tcx>( - typeck: &mut TypeChecker<'_, 'tcx>, +pub(super) fn populate_access_facts<'a, 'tcx>( + typeck: &mut TypeChecker<'a, 'tcx>, body: &Body<'tcx>, location_table: &LocationTable, - move_data: &MoveData<'_>, + move_data: &MoveData<'tcx>, dropped_at: &mut Vec<(Local, Location)>, ) { debug!("populate_access_facts()"); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 4b905c23e1..355254fe94 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -20,7 +20,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{ - InferCtxt, InferOk, LateBoundRegionConversionTime, NllRegionVariableOrigin, + InferCtxt, InferOk, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin, }; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; @@ -94,7 +94,7 @@ mod canonical; mod constraint_conversion; pub mod free_region_relations; mod input_output; -crate mod liveness; +pub(crate) mod liveness; mod relate_tys; /// Type checks the given `mir` in the context of the inference @@ -162,6 +162,8 @@ pub(crate) fn type_check<'mir, 'tcx>( &mut constraints, ); + debug!(?normalized_inputs_and_output); + for u in ty::UniverseIndex::ROOT..infcx.universe() { let info = UniverseInfo::other(); constraints.universe_causes.insert(u, info); @@ -185,6 +187,7 @@ pub(crate) fn type_check<'mir, 'tcx>( implicit_region_bound, &mut borrowck_context, |mut cx| { + debug!("inside extra closure of type_check_internal"); cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output); liveness::generate( &mut cx, @@ -257,6 +260,7 @@ fn type_check_internal<'a, 'tcx, R>( borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, extra: impl FnOnce(TypeChecker<'a, 'tcx>) -> R, ) -> R { + debug!("body: {:#?}", body); let mut checker = TypeChecker::new( infcx, body, @@ -353,12 +357,20 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { .add_element(live_region_vid, location); }); + // HACK(compiler-errors): Constants that are gathered into Body.required_consts + // have their locations erased... + let locations = if location != Location::START { + location.to_locations() + } else { + Locations::All(constant.span) + }; + if let Some(annotation_index) = constant.user_ty { if let Err(terr) = self.cx.relate_type_and_user_type( constant.literal.ty(), ty::Variance::Invariant, &UserTypeProjection { base: annotation_index, projs: vec![] }, - location.to_locations(), + locations, ConstraintCategory::Boring, ) { let annotation = &self.cx.user_type_annotations[annotation_index]; @@ -374,7 +386,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } else { let tcx = self.tcx(); let maybe_uneval = match constant.literal { - ConstantKind::Ty(ct) => match ct.val() { + ConstantKind::Ty(ct) => match ct.kind() { ty::ConstKind::Unevaluated(uv) => Some(uv), _ => None, }, @@ -386,12 +398,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { promoted: &Body<'tcx>, ty, san_ty| { - if let Err(terr) = verifier.cx.eq_types( - ty, - san_ty, - location.to_locations(), - ConstraintCategory::Boring, - ) { + if let Err(terr) = + verifier.cx.eq_types(ty, san_ty, locations, ConstraintCategory::Boring) + { span_mirbug!( verifier, promoted, @@ -412,7 +421,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } else { if let Err(terr) = self.cx.fully_perform_op( - location.to_locations(), + locations, ConstraintCategory::Boring, self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( constant.literal.ty(), @@ -431,7 +440,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } else if let Some(static_def_id) = constant.check_static_ptr(tcx) { let unnormalized_ty = tcx.type_of(static_def_id); - let locations = location.to_locations(); let normalized_ty = self.cx.normalize(unnormalized_ty, locations); let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty; @@ -450,7 +458,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { self.cx.normalize_and_prove_instantiated_predicates( def_id, instantiated_predicates, - location.to_locations(), + locations, ); } } @@ -897,28 +905,29 @@ struct BorrowCheckContext<'a, 'tcx> { upvars: &'a [Upvar<'tcx>], } -crate struct MirTypeckResults<'tcx> { - crate constraints: MirTypeckRegionConstraints<'tcx>, - crate universal_region_relations: Frozen>, - crate opaque_type_values: VecMap, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, +pub(crate) struct MirTypeckResults<'tcx> { + pub(crate) constraints: MirTypeckRegionConstraints<'tcx>, + pub(crate) universal_region_relations: Frozen>, + pub(crate) opaque_type_values: + VecMap, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, } /// A collection of region constraints that must be satisfied for the /// program to be considered well-typed. -crate struct MirTypeckRegionConstraints<'tcx> { +pub(crate) struct MirTypeckRegionConstraints<'tcx> { /// Maps from a `ty::Placeholder` to the corresponding /// `PlaceholderIndex` bit that we will use for it. /// /// To keep everything in sync, do not insert this set /// directly. Instead, use the `placeholder_region` helper. - crate placeholder_indices: PlaceholderIndices, + pub(crate) placeholder_indices: PlaceholderIndices, /// Each time we add a placeholder to `placeholder_indices`, we /// also create a corresponding "representative" region vid for /// that wraps it. This vector tracks those. This way, when we /// convert the same `ty::RePlaceholder(p)` twice, we can map to /// the same underlying `RegionVid`. - crate placeholder_index_to_region: IndexVec>, + pub(crate) placeholder_index_to_region: IndexVec>, /// In general, the type-checker is not responsible for enforcing /// liveness constraints; this job falls to the region inferencer, @@ -927,18 +936,18 @@ crate struct MirTypeckRegionConstraints<'tcx> { /// not otherwise appear in the MIR -- in particular, the /// late-bound regions that it instantiates at call-sites -- and /// hence it must report on their liveness constraints. - crate liveness_constraints: LivenessValues, + pub(crate) liveness_constraints: LivenessValues, - crate outlives_constraints: OutlivesConstraintSet<'tcx>, + pub(crate) outlives_constraints: OutlivesConstraintSet<'tcx>, - crate member_constraints: MemberConstraintSet<'tcx, RegionVid>, + pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>, - crate closure_bounds_mapping: - FxHashMap>, + pub(crate) closure_bounds_mapping: + FxHashMap, Span)>>, - crate universe_causes: FxHashMap>, + pub(crate) universe_causes: FxHashMap>, - crate type_tests: Vec>, + pub(crate) type_tests: Vec>, } impl<'tcx> MirTypeckRegionConstraints<'tcx> { @@ -1124,7 +1133,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn push_region_constraints( &mut self, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, data: &QueryRegionConstraints<'tcx>, ) { debug!("constraints generated: {:#?}", data); @@ -1149,7 +1158,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { sub: Ty<'tcx>, sup: Ty<'tcx>, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, ) -> Fallible<()> { // Use this order of parameters because the sup type is usually the // "expected" type in diagnostics. @@ -1162,7 +1171,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, ) -> Fallible<()> { self.relate_types(expected, ty::Variance::Invariant, found, locations, category) } @@ -1174,7 +1183,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { v: ty::Variance, user_ty: &UserTypeProjection, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, ) -> Fallible<()> { let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty; let mut curr_projected_ty = PlaceTy::from_ty(annotated_type); @@ -1211,6 +1220,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { #[instrument(skip(self, body, location), level = "debug")] fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) { let tcx = self.tcx(); + debug!("stmt kind: {:?}", stmt.kind); match stmt.kind { StatementKind::Assign(box (ref place, ref rv)) => { // Assignments to temporaries are not "interesting"; @@ -1250,9 +1260,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); let place_ty = place.ty(body, tcx).ty; + debug!(?place_ty); let place_ty = self.normalize(place_ty, location); + debug!("place_ty normalized: {:?}", place_ty); let rv_ty = rv.ty(body, tcx); + debug!(?rv_ty); let rv_ty = self.normalize(rv_ty, location); + debug!("normalized rv_ty: {:?}", rv_ty); if let Err(terr) = self.sub_types(rv_ty, place_ty, location.to_locations(), category) { @@ -1346,6 +1360,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { term_location: Location, ) { let tcx = self.tcx(); + debug!("terminator kind: {:?}", term.kind); match term.kind { TerminatorKind::Goto { .. } | TerminatorKind::Resume @@ -1402,14 +1417,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // FIXME: check the values } - TerminatorKind::Call { ref func, ref args, ref destination, from_hir_call, .. } => { + TerminatorKind::Call { + ref func, + ref args, + ref destination, + from_hir_call, + target, + .. + } => { self.check_operand(func, term_location); for arg in args { self.check_operand(arg, term_location); } let func_ty = func.ty(body, tcx); - debug!("check_terminator: call, func_ty={:?}", func_ty); + debug!("func_ty.kind: {:?}", func_ty.kind()); + let sig = match func_ty.kind() { ty::FnDef(..) | ty::FnPtr(_) => func_ty.fn_sig(tcx), _ => { @@ -1417,13 +1440,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return; } }; - let (sig, map) = self.infcx.replace_bound_vars_with_fresh_vars( - term.source_info.span, - LateBoundRegionConversionTime::FnCall, - sig, - ); + let (sig, map) = tcx.replace_late_bound_regions(sig, |br| { + self.infcx.next_region_var(LateBoundRegion( + term.source_info.span, + br.kind, + LateBoundRegionConversionTime::FnCall, + )) + }); + debug!(?sig); let sig = self.normalize(sig, term_location); - self.check_call_dest(body, term, &sig, destination, term_location); + self.check_call_dest(body, term, &sig, *destination, target, term_location); self.prove_predicates( sig.inputs_and_output @@ -1501,15 +1527,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { body: &Body<'tcx>, term: &Terminator<'tcx>, sig: &ty::FnSig<'tcx>, - destination: &Option<(Place<'tcx>, BasicBlock)>, + destination: Place<'tcx>, + target: Option, term_location: Location, ) { let tcx = self.tcx(); - match *destination { - Some((ref dest, _target_block)) => { - let dest_ty = dest.ty(body, tcx).ty; + match target { + Some(_) => { + let dest_ty = destination.ty(body, tcx).ty; let dest_ty = self.normalize(dest_ty, term_location); - let category = match dest.as_local() { + let category = match destination.as_local() { Some(RETURN_PLACE) => { if let BorrowCheckContext { universal_regions: @@ -1581,11 +1608,20 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); } + + let func_ty = if let TerminatorKind::Call { func, .. } = &term.kind { + Some(func.ty(body, self.infcx.tcx)) + } else { + None + }; + debug!(?func_ty); + for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { let op_arg_ty = op_arg.ty(body, self.tcx()); + let op_arg_ty = self.normalize(op_arg_ty, term_location); let category = if from_hir_call { - ConstraintCategory::CallArgument + ConstraintCategory::CallArgument(func_ty) } else { ConstraintCategory::Boring }; @@ -1658,8 +1694,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.assert_iscleanup(body, block_data, unwind, true); } } - TerminatorKind::Call { ref destination, cleanup, .. } => { - if let &Some((_, target)) = destination { + TerminatorKind::Call { ref target, cleanup, .. } => { + if let &Some(target) = target { self.assert_iscleanup(body, block_data, target, is_cleanup); } if let Some(cleanup) = cleanup { @@ -1809,7 +1845,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) { if let Operand::Constant(constant) = op { let maybe_uneval = match constant.literal { - ConstantKind::Ty(ct) => match ct.val() { + ConstantKind::Ty(ct) => match ct.kind() { ty::ConstKind::Unevaluated(uv) => Some(uv), _ => None, }, @@ -1837,6 +1873,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } + #[instrument(skip(self, body), level = "debug")] fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { let tcx = self.tcx(); @@ -2116,24 +2153,62 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::Misc => { + CastKind::PointerExposeAddress => { let ty_from = op.ty(body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { - (None, _) - | (_, None | Some(CastTy::FnPtr)) - | (Some(CastTy::Float), Some(CastTy::Ptr(_))) - | (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Float)) => { - span_mirbug!(self, rvalue, "Invalid cast {:?} -> {:?}", ty_from, ty,) + (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => (), + _ => { + span_mirbug!( + self, + rvalue, + "Invalid PointerExposeAddress cast {:?} -> {:?}", + ty_from, + ty + ) } + } + } + + CastKind::PointerFromExposedAddress => { + let ty_from = op.ty(body, tcx); + let cast_ty_from = CastTy::from_ty(ty_from); + let cast_ty_to = CastTy::from_ty(*ty); + match (cast_ty_from, cast_ty_to) { + (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => (), + _ => { + span_mirbug!( + self, + rvalue, + "Invalid PointerFromExposedAddress cast {:?} -> {:?}", + ty_from, + ty + ) + } + } + } + + CastKind::Misc => { + let ty_from = op.ty(body, tcx); + let cast_ty_from = CastTy::from_ty(ty_from); + let cast_ty_to = CastTy::from_ty(*ty); + // Misc casts are either between floats and ints, or one ptr type to another. + match (cast_ty_from, cast_ty_to) { ( - Some(CastTy::Int(_)), - Some(CastTy::Int(_) | CastTy::Float | CastTy::Ptr(_)), + Some(CastTy::Int(_) | CastTy::Float), + Some(CastTy::Int(_) | CastTy::Float), ) - | (Some(CastTy::Float), Some(CastTy::Int(_) | CastTy::Float)) - | (Some(CastTy::Ptr(_)), Some(CastTy::Int(_) | CastTy::Ptr(_))) - | (Some(CastTy::FnPtr), Some(CastTy::Int(_) | CastTy::Ptr(_))) => (), + | (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Ptr(_))) => (), + _ => { + span_mirbug!( + self, + rvalue, + "Invalid Misc cast {:?} -> {:?}", + ty_from, + ty, + ) + } } } } diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index f98d2c3128..c45850c6d8 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -28,7 +28,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { v: ty::Variance, b: Ty<'tcx>, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, ) -> Fallible<()> { TypeRelating::new( self.infcx, @@ -47,7 +47,7 @@ struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> { locations: Locations, /// What category do we assign the resulting `'a: 'b` relationships? - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, /// Information so that error reporting knows what types we are relating /// when reporting a bound region error. @@ -58,7 +58,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelatingDelegate<'me, 'bccx, 'tcx> { fn new( type_checker: &'me mut TypeChecker<'bccx, 'tcx>, locations: Locations, - category: ConstraintCategory, + category: ConstraintCategory<'tcx>, universe_info: UniverseInfo<'tcx>, ) -> Self { Self { type_checker, locations, category, universe_info } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 0fcac9a1c6..c2c093f9f2 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -336,7 +336,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// that this region imposes on others. The methods in this file /// handle the part about dumping the inference context internal /// state. - crate fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { + pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { match self.defining_ty { DefiningTy::Closure(def_id, substs) => { err.note(&format!( @@ -830,11 +830,11 @@ fn for_each_late_bound_region_defined_on<'tcx>( fn_def_id: DefId, mut f: impl FnMut(ty::Region<'tcx>), ) { - if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) { + if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) { for ®ion_def_id in late_bounds.iter() { let name = tcx.item_name(region_def_id.to_def_id()); let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: owner.to_def_id(), + scope: fn_def_id, bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name), })); f(liberated_region); diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index 6022a98095..1093167fa8 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -22,7 +22,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// been assigned to - this set is used as a proxy for locals that were not initialized due to /// unreachable code. These locals are then considered "used" to silence the lint for them. /// See #55344 for context. - crate fn gather_used_muts( + pub(crate) fn gather_used_muts( &mut self, temporary_used_locals: FxHashSet, mut never_initialized_mut_locals: FxHashSet, @@ -66,8 +66,8 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { debug!("visit_terminator: terminator={:?}", terminator); match &terminator.kind { - TerminatorKind::Call { destination: Some((into, _)), .. } => { - self.remove_never_initialized_mut_locals(*into); + TerminatorKind::Call { destination, .. } => { + self.remove_never_initialized_mut_locals(*destination); } TerminatorKind::DropAndReplace { place, .. } => { self.remove_never_initialized_mut_locals(*place); diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 9031c3b2ec..7dc947f7d9 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -16,6 +16,7 @@ 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_parse = { path = "../rustc_parse" } rustc_target = { path = "../rustc_target" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index c95d714717..42bddd1b6e 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -363,7 +363,7 @@ fn err_duplicate_option<'a>(p: &mut Parser<'a>, symbol: Symbol, span: Span) { err.tool_only_span_suggestion( full_span, "remove this option", - String::new(), + "", Applicability::MachineApplicable, ); diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index a984980dea..925c36edb5 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -1,11 +1,13 @@ +mod context; + use crate::edition_panic::use_panic_2021; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; -use rustc_ast::{self as ast, *}; +use rustc_ast::{Expr, ExprKind, MacArgs, MacCall, MacDelimiter, Path, PathSegment, UnOp}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, PResult}; -use rustc_expand::base::*; +use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult}; use rustc_parse::parser::Parser; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -25,13 +27,13 @@ pub fn expand_assert<'cx>( // `core::panic` and `std::panic` are different macros, so we use call-site // context to pick up whichever is currently in scope. - let sp = cx.with_call_site_ctxt(span); + let call_site_span = cx.with_call_site_ctxt(span); - let panic_call = if let Some(tokens) = custom_message { - let path = if use_panic_2021(span) { + let panic_path = || { + if use_panic_2021(span) { // On edition 2021, we always call `$crate::panic::panic_2021!()`. Path { - span: sp, + span: call_site_span, segments: cx .std_path(&[sym::panic, sym::panic_2021]) .into_iter() @@ -42,27 +44,40 @@ pub fn expand_assert<'cx>( } else { // Before edition 2021, we call `panic!()` unqualified, // such that it calls either `std::panic!()` or `core::panic!()`. - Path::from_ident(Ident::new(sym::panic, sp)) - }; - // Pass the custom message to panic!(). - cx.expr( - sp, + Path::from_ident(Ident::new(sym::panic, call_site_span)) + } + }; + + // Simply uses the user provided message instead of generating custom outputs + let expr = if let Some(tokens) = custom_message { + let then = cx.expr( + call_site_span, ExprKind::MacCall(MacCall { - path, + path: panic_path(), args: P(MacArgs::Delimited( - DelimSpan::from_single(sp), + DelimSpan::from_single(call_site_span), MacDelimiter::Parenthesis, tokens, )), prior_type_ascription: None, }), - ) - } else { + ); + expr_if_not(cx, call_site_span, cond_expr, then, None) + } + // If `generic_assert` is enabled, generates rich captured outputs + // + // FIXME(c410-f3r) See https://github.com/rust-lang/rust/issues/96949 + else if let Some(features) = cx.ecfg.features && features.generic_assert { + context::Context::new(cx, call_site_span).build(cond_expr, panic_path()) + } + // If `generic_assert` is not enabled, only outputs a literal "assertion failed: ..." + // string + else { // Pass our own message directly to $crate::panicking::panic(), // because it might contain `{` and `}` that should always be // passed literally. - cx.expr_call_global( - sp, + let then = cx.expr_call_global( + call_site_span, cx.std_path(&[sym::panicking, sym::panic]), vec![cx.expr_str( DUMMY_SP, @@ -71,18 +86,29 @@ pub fn expand_assert<'cx>( pprust::expr_to_string(&cond_expr).escape_debug() )), )], - ) + ); + expr_if_not(cx, call_site_span, cond_expr, then, None) }; - let if_expr = - cx.expr_if(sp, cx.expr(sp, ExprKind::Unary(UnOp::Not, cond_expr)), panic_call, None); - MacEager::expr(if_expr) + + MacEager::expr(expr) } struct Assert { - cond_expr: P, + cond_expr: P, custom_message: Option, } +// if !{ ... } { ... } else { ... } +fn expr_if_not( + cx: &ExtCtxt<'_>, + span: Span, + cond: P, + then: P, + els: Option>, +) -> P { + cx.expr_if(span, cx.expr(span, ExprKind::Unary(UnOp::Not, cond)), then, els) +} + fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PResult<'a, Assert> { let mut parser = cx.new_parser_from_tts(stream); @@ -106,7 +132,7 @@ fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PRes err.span_suggestion( parser.token.span, "try removing semicolon", - String::new(), + "", Applicability::MaybeIncorrect, ); err.emit(); @@ -127,7 +153,7 @@ fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PRes err.span_suggestion_short( comma_span, "try adding a comma", - ", ".to_string(), + ", ", Applicability::MaybeIncorrect, ); err.emit(); diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs new file mode 100644 index 0000000000..cad3018121 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -0,0 +1,387 @@ +use crate::assert::expr_if_not; +use rustc_ast::{ + attr, + ptr::P, + token, + tokenstream::{DelimSpan, TokenStream, TokenTree}, + BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, Mutability, Path, + PathSegment, Stmt, StructRest, UseTree, UseTreeKind, DUMMY_NODE_ID, +}; +use rustc_ast_pretty::pprust; +use rustc_data_structures::fx::FxHashSet; +use rustc_expand::base::ExtCtxt; +use rustc_span::{ + symbol::{sym, Ident, Symbol}, + Span, +}; + +pub(super) struct Context<'cx, 'a> { + // Top-level `let captureN = Capture::new()` statements + capture_decls: Vec, + cx: &'cx ExtCtxt<'a>, + // Formatting string used for debugging + fmt_string: String, + // Top-level `let __local_bindN = &expr` statements + local_bind_decls: Vec, + // Used to avoid capturing duplicated paths + // + // ```rust + // let a = 1i32; + // assert!(add(a, a) == 3); + // ``` + paths: FxHashSet, + span: Span, +} + +impl<'cx, 'a> Context<'cx, 'a> { + pub(super) fn new(cx: &'cx ExtCtxt<'a>, span: Span) -> Self { + Self { + capture_decls: <_>::default(), + cx, + fmt_string: <_>::default(), + local_bind_decls: <_>::default(), + paths: <_>::default(), + span, + } + } + + /// Builds the whole `assert!` expression. For example, `let elem = 1; assert!(elem == 1);` expands to: + /// + /// ```rust + /// let elem = 1; + /// { + /// #[allow(unused_imports)] + /// use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable}; + /// let mut __capture0 = ::core::asserting::Capture::new(); + /// let __local_bind0 = &elem; + /// if !( + /// *{ + /// (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); + /// __local_bind0 + /// } == 1 + /// ) { + /// panic!("Assertion failed: elem == 1\nWith captures:\n elem = {}", __capture0) + /// } + /// } + /// ``` + pub(super) fn build(mut self, mut cond_expr: P, panic_path: Path) -> P { + let expr_str = pprust::expr_to_string(&cond_expr); + self.manage_cond_expr(&mut cond_expr); + let initial_imports = self.build_initial_imports(); + let panic = self.build_panic(&expr_str, panic_path); + + let Self { capture_decls, cx, local_bind_decls, span, .. } = self; + + let mut stmts = Vec::with_capacity(4); + stmts.push(initial_imports); + stmts.extend(capture_decls.into_iter().map(|c| c.decl)); + stmts.extend(local_bind_decls); + stmts.push(cx.stmt_expr(expr_if_not(cx, span, cond_expr, panic, None))); + cx.expr_block(cx.block(span, stmts)) + } + + /// Initial **trait** imports + /// + /// use ::core::asserting::{ ... }; + fn build_initial_imports(&self) -> Stmt { + let nested_tree = |this: &Self, sym| { + ( + UseTree { + prefix: this.cx.path(this.span, vec![Ident::with_dummy_span(sym)]), + kind: UseTreeKind::Simple(None, DUMMY_NODE_ID, DUMMY_NODE_ID), + span: this.span, + }, + DUMMY_NODE_ID, + ) + }; + self.cx.stmt_item( + self.span, + self.cx.item( + self.span, + Ident::empty(), + vec![self.cx.attribute(attr::mk_list_item( + Ident::new(sym::allow, self.span), + vec![attr::mk_nested_word_item(Ident::new(sym::unused_imports, self.span))], + ))], + ItemKind::Use(UseTree { + prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])), + kind: UseTreeKind::Nested(vec![ + nested_tree(self, sym::TryCaptureGeneric), + nested_tree(self, sym::TryCapturePrintable), + ]), + span: self.span, + }), + ), + ) + } + + /// The necessary custom `panic!(...)` expression. + /// + /// panic!( + /// "Assertion failed: ... \n With expansion: ...", + /// __capture0, + /// ... + /// ); + fn build_panic(&self, expr_str: &str, panic_path: Path) -> P { + let escaped_expr_str = escape_to_fmt(expr_str); + let initial = [ + TokenTree::token( + token::Literal(token::Lit { + kind: token::LitKind::Str, + symbol: Symbol::intern(&if self.fmt_string.is_empty() { + format!("Assertion failed: {escaped_expr_str}") + } else { + format!( + "Assertion failed: {escaped_expr_str}\nWith captures:\n{}", + &self.fmt_string + ) + }), + suffix: None, + }), + self.span, + ), + TokenTree::token(token::Comma, self.span), + ]; + let captures = self.capture_decls.iter().flat_map(|cap| { + [ + TokenTree::token(token::Ident(cap.ident.name, false), cap.ident.span), + TokenTree::token(token::Comma, self.span), + ] + }); + self.cx.expr( + self.span, + ExprKind::MacCall(MacCall { + path: panic_path, + args: P(MacArgs::Delimited( + DelimSpan::from_single(self.span), + MacDelimiter::Parenthesis, + initial.into_iter().chain(captures).collect::(), + )), + prior_type_ascription: None, + }), + ) + } + + /// Recursive function called until `cond_expr` and `fmt_str` are fully modified. + /// + /// See [Self::manage_initial_capture] and [Self::manage_try_capture] + fn manage_cond_expr(&mut self, expr: &mut P) { + match (*expr).kind { + ExprKind::AddrOf(_, _, ref mut local_expr) => { + self.manage_cond_expr(local_expr); + } + ExprKind::Array(ref mut local_exprs) => { + for local_expr in local_exprs { + self.manage_cond_expr(local_expr); + } + } + ExprKind::Binary(_, ref mut lhs, ref mut rhs) => { + self.manage_cond_expr(lhs); + self.manage_cond_expr(rhs); + } + ExprKind::Call(_, ref mut local_exprs) => { + for local_expr in local_exprs { + self.manage_cond_expr(local_expr); + } + } + ExprKind::Cast(ref mut local_expr, _) => { + self.manage_cond_expr(local_expr); + } + ExprKind::Index(ref mut prefix, ref mut suffix) => { + self.manage_cond_expr(prefix); + self.manage_cond_expr(suffix); + } + ExprKind::MethodCall(_, ref mut local_exprs, _) => { + for local_expr in local_exprs.iter_mut().skip(1) { + self.manage_cond_expr(local_expr); + } + } + ExprKind::Path(_, Path { ref segments, .. }) if let &[ref path_segment] = &segments[..] => { + let path_ident = path_segment.ident; + self.manage_initial_capture(expr, path_ident); + } + ExprKind::Paren(ref mut local_expr) => { + self.manage_cond_expr(local_expr); + } + ExprKind::Range(ref mut prefix, ref mut suffix, _) => { + if let Some(ref mut elem) = prefix { + self.manage_cond_expr(elem); + } + if let Some(ref mut elem) = suffix { + self.manage_cond_expr(elem); + } + } + ExprKind::Repeat(ref mut local_expr, ref mut elem) => { + self.manage_cond_expr(local_expr); + self.manage_cond_expr(&mut elem.value); + } + ExprKind::Struct(ref mut elem) => { + for field in &mut elem.fields { + self.manage_cond_expr(&mut field.expr); + } + if let StructRest::Base(ref mut local_expr) = elem.rest { + self.manage_cond_expr(local_expr); + } + } + ExprKind::Tup(ref mut local_exprs) => { + for local_expr in local_exprs { + self.manage_cond_expr(local_expr); + } + } + ExprKind::Unary(_, ref mut local_expr) => { + self.manage_cond_expr(local_expr); + } + // Expressions that are not worth or can not be captured. + // + // Full list instead of `_` to catch possible future inclusions and to + // sync with the `rfc-2011-nicer-assert-messages/all-expr-kinds.rs` test. + ExprKind::Assign(_, _, _) + | ExprKind::AssignOp(_, _, _) + | ExprKind::Async(_, _, _) + | ExprKind::Await(_) + | ExprKind::Block(_, _) + | ExprKind::Box(_) + | ExprKind::Break(_, _) + | ExprKind::Closure(_, _, _, _, _, _) + | ExprKind::ConstBlock(_) + | ExprKind::Continue(_) + | ExprKind::Err + | ExprKind::Field(_, _) + | ExprKind::ForLoop(_, _, _, _) + | ExprKind::If(_, _, _) + | ExprKind::InlineAsm(_) + | ExprKind::Let(_, _, _) + | ExprKind::Lit(_) + | ExprKind::Loop(_, _) + | ExprKind::MacCall(_) + | ExprKind::Match(_, _) + | ExprKind::Path(_, _) + | ExprKind::Ret(_) + | ExprKind::Try(_) + | ExprKind::TryBlock(_) + | ExprKind::Type(_, _) + | ExprKind::Underscore + | ExprKind::While(_, _, _) + | ExprKind::Yeet(_) + | ExprKind::Yield(_) => {} + } + } + + /// Pushes the top-level declarations and modifies `expr` to try capturing variables. + /// + /// `fmt_str`, the formatting string used for debugging, is constructed to show possible + /// captured variables. + fn manage_initial_capture(&mut self, expr: &mut P, path_ident: Ident) { + if self.paths.contains(&path_ident) { + return; + } else { + self.fmt_string.push_str(" "); + self.fmt_string.push_str(path_ident.as_str()); + self.fmt_string.push_str(" = {:?}\n"); + let _ = self.paths.insert(path_ident); + } + let curr_capture_idx = self.capture_decls.len(); + let capture_string = format!("__capture{curr_capture_idx}"); + let ident = Ident::new(Symbol::intern(&capture_string), self.span); + let init_std_path = self.cx.std_path(&[sym::asserting, sym::Capture, sym::new]); + let init = self.cx.expr_call( + self.span, + self.cx.expr_path(self.cx.path(self.span, init_std_path)), + vec![], + ); + let capture = Capture { decl: self.cx.stmt_let(self.span, true, ident, init), ident }; + self.capture_decls.push(capture); + self.manage_try_capture(ident, curr_capture_idx, expr); + } + + /// Tries to copy `__local_bindN` into `__captureN`. + /// + /// *{ + /// (&Wrapper(__local_bindN)).try_capture(&mut __captureN); + /// __local_bindN + /// } + fn manage_try_capture(&mut self, capture: Ident, curr_capture_idx: usize, expr: &mut P) { + let local_bind_string = format!("__local_bind{curr_capture_idx}"); + let local_bind = Ident::new(Symbol::intern(&local_bind_string), self.span); + self.local_bind_decls.push(self.cx.stmt_let( + self.span, + false, + local_bind, + self.cx.expr_addr_of(self.span, expr.clone()), + )); + let wrapper = self.cx.expr_call( + self.span, + self.cx.expr_path( + self.cx.path(self.span, self.cx.std_path(&[sym::asserting, sym::Wrapper])), + ), + vec![self.cx.expr_path(Path::from_ident(local_bind))], + ); + let try_capture_call = self + .cx + .stmt_expr(expr_method_call( + self.cx, + PathSegment { + args: None, + id: DUMMY_NODE_ID, + ident: Ident::new(sym::try_capture, self.span), + }, + vec![ + expr_paren(self.cx, self.span, self.cx.expr_addr_of(self.span, wrapper)), + expr_addr_of_mut( + self.cx, + self.span, + self.cx.expr_path(Path::from_ident(capture)), + ), + ], + self.span, + )) + .add_trailing_semicolon(); + let local_bind_path = self.cx.expr_path(Path::from_ident(local_bind)); + let ret = self.cx.stmt_expr(local_bind_path); + let block = self.cx.expr_block(self.cx.block(self.span, vec![try_capture_call, ret])); + *expr = self.cx.expr_deref(self.span, block); + } +} + +/// Information about a captured element. +#[derive(Debug)] +struct Capture { + // Generated indexed `Capture` statement. + // + // `let __capture{} = Capture::new();` + decl: Stmt, + // The name of the generated indexed `Capture` variable. + // + // `__capture{}` + ident: Ident, +} + +/// Escapes to use as a formatting string. +fn escape_to_fmt(s: &str) -> String { + let mut rslt = String::with_capacity(s.len()); + for c in s.chars() { + rslt.extend(c.escape_debug()); + match c { + '{' | '}' => rslt.push(c), + _ => {} + } + } + rslt +} + +fn expr_addr_of_mut(cx: &ExtCtxt<'_>, sp: Span, e: P) -> P { + cx.expr(sp, ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, e)) +} + +fn expr_method_call( + cx: &ExtCtxt<'_>, + path: PathSegment, + args: Vec>, + span: Span, +) -> P { + cx.expr(span, ExprKind::MethodCall(path, args, span)) +} + +fn expr_paren(cx: &ExtCtxt<'_>, sp: Span, e: P) -> P { + cx.expr(sp, ExprKind::Paren(e)) +} diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index f5ef4765df..c75d83bd0a 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -8,6 +8,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_attr as attr; use rustc_errors::PResult; use rustc_expand::base::{self, *}; +use rustc_macros::SessionDiagnostic; use rustc_span::Span; pub fn expand_cfg( @@ -34,13 +35,26 @@ pub fn expand_cfg( } } -fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> { +#[derive(SessionDiagnostic)] +#[error(slug = "builtin-macros-requires-cfg-pattern")] +struct RequiresCfgPattern { + #[primary_span] + #[label] + span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(slug = "builtin-macros-expected-one-cfg-pattern")] +struct OneCfgPattern { + #[primary_span] + span: Span, +} + +fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { - let mut err = cx.struct_span_err(sp, "macro requires a cfg-pattern as an argument"); - err.span_label(sp, "cfg-pattern required"); - return Err(err); + return Err(cx.create_err(RequiresCfgPattern { span })); } let cfg = p.parse_meta_item()?; @@ -48,7 +62,7 @@ fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a let _ = p.eat(&token::Comma); if !p.eat(&token::Eof) { - return Err(cx.struct_span_err(sp, "expected 1 cfg-pattern")); + return Err(cx.create_err(OneCfgPattern { span })); } Ok(cfg) diff --git a/compiler/rustc_builtin_macros/src/cfg_accessible.rs b/compiler/rustc_builtin_macros/src/cfg_accessible.rs index 7b7db3eaea..cb5359dd1e 100644 --- a/compiler/rustc_builtin_macros/src/cfg_accessible.rs +++ b/compiler/rustc_builtin_macros/src/cfg_accessible.rs @@ -7,7 +7,7 @@ use rustc_parse::validate_attr; use rustc_span::symbol::sym; use rustc_span::Span; -crate struct Expander; +pub(crate) struct Expander; fn validate_input<'a>(ecx: &mut ExtCtxt<'_>, mi: &'a ast::MetaItem) -> Option<&'a ast::Path> { match mi.meta_item_list() { diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 4278fedfee..89b2c32923 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -3,7 +3,6 @@ use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute}; use rustc_ast as ast; use rustc_ast::mut_visit::MutVisitor; use rustc_ast::ptr::P; -use rustc_ast::tokenstream::CanSynthesizeMissingTokens; use rustc_ast::visit::Visitor; use rustc_ast::NodeId; use rustc_ast::{mut_visit, visit}; @@ -13,13 +12,12 @@ use rustc_expand::config::StripUnconfigured; use rustc_expand::configure; use rustc_feature::Features; use rustc_parse::parser::{ForceCollect, Parser}; -use rustc_session::utils::FlattenNonterminals; use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::Span; use smallvec::SmallVec; -crate fn expand( +pub(crate) fn expand( ecx: &mut ExtCtxt<'_>, _span: Span, meta_item: &ast::MetaItem, @@ -30,7 +28,7 @@ crate fn expand( vec![cfg_eval(ecx.sess, ecx.ecfg.features, annotatable, ecx.current_expansion.lint_node_id)] } -crate fn cfg_eval( +pub(crate) fn cfg_eval( sess: &Session, features: Option<&Features>, annotatable: Annotatable, @@ -174,8 +172,6 @@ impl CfgEval<'_, '_> { _ => unreachable!(), }; - let mut orig_tokens = annotatable.to_tokens(&self.cfg.sess.parse_sess); - // 'Flatten' all nonterminals (i.e. `TokenKind::Interpolated`) // to `None`-delimited groups containing the corresponding tokens. This // is normally delayed until the proc-macro server actually needs to @@ -189,12 +185,7 @@ impl CfgEval<'_, '_> { // where `$item` is `#[cfg_attr] struct Foo {}`. We want to make // sure to evaluate *all* `#[cfg]` and `#[cfg_attr]` attributes - the simplest // way to do this is to do a single parse of a stream without any nonterminals. - let mut flatten = FlattenNonterminals { - nt_to_tokenstream: rustc_parse::nt_to_tokenstream, - parse_sess: &self.cfg.sess.parse_sess, - synthesize_tokens: CanSynthesizeMissingTokens::No, - }; - orig_tokens = flatten.process_token_stream(orig_tokens); + let orig_tokens = annotatable.to_tokens().flattened(); // Re-parse the tokens, setting the `capture_cfg` flag to save extra information // to the captured `AttrAnnotatedTokenStream` (specifically, we capture diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index 391c46d181..d3de10ca4a 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -10,7 +10,7 @@ use rustc_session::Session; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; -crate struct Expander; +pub(crate) struct Expander; impl MultiItemModifier for Expander { fn expand( @@ -142,7 +142,7 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) { let report_error = |title, action| { let span = meta.span.with_lo(meta.path.span.hi()); sess.struct_span_err(span, title) - .span_suggestion(span, action, String::new(), Applicability::MachineApplicable) + .span_suggestion(span, action, "", Applicability::MachineApplicable) .emit(); }; match meta.kind { diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 0fd23fd281..53369afae2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -257,7 +257,7 @@ pub struct Substructure<'a> { pub type_ident: Ident, /// ident of the method pub method_ident: Ident, - /// dereferenced access to any [`Self_`] or [`Ptr(Self_, _)][ptr]` arguments + /// dereferenced access to any [`Self_`] or [`Ptr(Self_, _)`][ptr] arguments /// /// [`Self_`]: ty::Ty::Self_ /// [ptr]: ty::Ty::Ptr @@ -1039,7 +1039,9 @@ impl<'a> MethodDef<'a> { let span = trait_.span; let mut patterns = Vec::new(); for i in 0..self_args.len() { - let struct_path = cx.path(span, vec![type_ident]); + // We could use `type_ident` instead of `Self`, but in the case of a type parameter + // shadowing the struct name, that causes a second, unnecessary E0578 error. #97343 + let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]); let (pat, ident_expr) = trait_.create_struct_pattern( cx, struct_path, diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 812d86af6e..c678c8cbd1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -38,8 +38,8 @@ pub mod partial_ord; pub mod generic; -crate struct BuiltinDerive( - crate fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)), +pub(crate) struct BuiltinDerive( + pub(crate) fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)), ); impl MultiItemModifier for BuiltinDerive { diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 60b96399b5..10348c4967 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -330,7 +330,7 @@ impl<'a, 'b> Context<'a, 'b> { err.tool_only_span_suggestion( sp, &format!("use the `{}` trait", name), - (*fmt).to_string(), + *fmt, Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 468ca7d7aa..11565ba72d 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -1,18 +1,18 @@ //! This crate contains implementations of built-in macros and other code generating facilities //! injecting code into the crate before it is lowered to HIR. +#![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] #![feature(box_patterns)] -#![feature(crate_visibility_modifier)] #![feature(decl_macro)] +#![feature(if_let_guard)] #![feature(is_sorted)] -#![feature(nll)] +#![feature(let_chains)] #![feature(let_else)] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] #![recursion_limit = "256"] -#![allow(rustc::potential_query_instability)] extern crate proc_macro; diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 407ca2301e..03159d4395 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -22,21 +22,16 @@ struct ProcMacroDerive { attrs: Vec, } -enum ProcMacroDefType { - Attr, - Bang, -} - struct ProcMacroDef { id: NodeId, function_name: Ident, span: Span, - def_type: ProcMacroDefType, } enum ProcMacro { Derive(ProcMacroDerive), - Def(ProcMacroDef), + Attr(ProcMacroDef), + Bang(ProcMacroDef), } struct CollectProcMacros<'a> { @@ -128,11 +123,10 @@ impl<'a> CollectProcMacros<'a> { fn collect_attr_proc_macro(&mut self, item: &'a ast::Item) { if self.in_root && item.vis.kind.is_pub() { - self.macros.push(ProcMacro::Def(ProcMacroDef { + self.macros.push(ProcMacro::Attr(ProcMacroDef { id: item.id, span: item.span, function_name: item.ident, - def_type: ProcMacroDefType::Attr, })); } else { let msg = if !self.in_root { @@ -147,11 +141,10 @@ impl<'a> CollectProcMacros<'a> { fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) { if self.in_root && item.vis.kind.is_pub() { - self.macros.push(ProcMacro::Def(ProcMacroDef { + self.macros.push(ProcMacro::Bang(ProcMacroDef { id: item.id, span: item.span, function_name: item.ident, - def_type: ProcMacroDefType::Bang, })); } else { let msg = if !self.in_root { @@ -301,53 +294,57 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P { // that we generate expressions. The position of each NodeId // in the 'proc_macros' Vec corresponds to its position // in the static array that will be generated - let decls = { - let local_path = |cx: &ExtCtxt<'_>, sp: Span, name| { - cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![name])) - }; - let proc_macro_ty_method_path = |cx: &ExtCtxt<'_>, method| { - cx.expr_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty, method])) - }; - macros - .iter() - .map(|m| match m { + let decls = macros + .iter() + .map(|m| { + let harness_span = span; + let span = match m { + ProcMacro::Derive(m) => m.span, + ProcMacro::Attr(m) | ProcMacro::Bang(m) => m.span, + }; + let local_path = |cx: &ExtCtxt<'_>, name| cx.expr_path(cx.path(span, vec![name])); + let proc_macro_ty_method_path = |cx: &ExtCtxt<'_>, method| { + cx.expr_path(cx.path( + span.with_ctxt(harness_span.ctxt()), + vec![proc_macro, bridge, client, proc_macro_ty, method], + )) + }; + match m { ProcMacro::Derive(cd) => { cx.resolver.declare_proc_macro(cd.id); cx.expr_call( span, proc_macro_ty_method_path(cx, custom_derive), vec![ - cx.expr_str(cd.span, cd.trait_name), + cx.expr_str(span, cd.trait_name), cx.expr_vec_slice( span, - cd.attrs - .iter() - .map(|&s| cx.expr_str(cd.span, s)) - .collect::>(), + cd.attrs.iter().map(|&s| cx.expr_str(span, s)).collect::>(), ), - local_path(cx, cd.span, cd.function_name), + local_path(cx, cd.function_name), ], ) } - ProcMacro::Def(ca) => { + ProcMacro::Attr(ca) | ProcMacro::Bang(ca) => { cx.resolver.declare_proc_macro(ca.id); - let ident = match ca.def_type { - ProcMacroDefType::Attr => attr, - ProcMacroDefType::Bang => bang, + let ident = match m { + ProcMacro::Attr(_) => attr, + ProcMacro::Bang(_) => bang, + ProcMacro::Derive(_) => unreachable!(), }; cx.expr_call( span, proc_macro_ty_method_path(cx, ident), vec![ - cx.expr_str(ca.span, ca.function_name.name), - local_path(cx, ca.span, ca.function_name), + cx.expr_str(span, ca.function_name.name), + local_path(cx, ca.function_name), ], ) } - }) - .collect() - }; + } + }) + .collect(); let decls_static = cx .item_static( diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 0c2d20b8f2..e20375689f 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -118,7 +118,7 @@ pub fn expand_test_or_bench( }; err.span_label(attr_sp, "the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions") .span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr())) - .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", String::from("#[cfg(test)]"), Applicability::MaybeIncorrect) + .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", "#[cfg(test)]", Applicability::MaybeIncorrect) .emit(); return vec![Annotatable::Item(item)]; diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index db8dce804a..a08495f767 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -147,7 +147,7 @@ fn entry_point_type(sess: &Session, item: &ast::Item, depth: usize) -> EntryPoin if sess.contains_name(&item.attrs, sym::start) { EntryPointType::Start } else if sess.contains_name(&item.attrs, sym::rustc_main) { - EntryPointType::MainAttr + EntryPointType::RustcMainAttr } else if item.ident.name == sym::main { if depth == 0 { // This is a top-level function so can be 'main' @@ -177,12 +177,12 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> { let item = noop_flat_map_item(i, self).expect_one("noop did something"); self.depth -= 1; - // Remove any #[main] or #[start] from the AST so it doesn't + // Remove any #[rustc_main] or #[start] from the AST so it doesn't // clash with the one we're going to add, but mark it as // #[allow(dead_code)] to avoid printing warnings. let item = match entry_point_type(self.sess, &item, self.depth) { - EntryPointType::MainNamed | EntryPointType::MainAttr | EntryPointType::Start => item - .map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| { + EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => { + item.map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| { let allow_ident = Ident::new(sym::allow, self.def_site); let dc_nested = attr::mk_nested_word_item(Ident::new(sym::dead_code, self.def_site)); @@ -197,7 +197,8 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> { .collect(); ast::Item { id, ident, attrs, kind, vis, span, tokens } - }), + }) + } EntryPointType::None | EntryPointType::OtherMain => item, }; diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml index 3aba528abf..aa556a21bf 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install rustfmt run: | @@ -39,7 +39,7 @@ jobs: TARGET_TRIPLE: aarch64-unknown-linux-gnu steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache cargo installed crates uses: actions/cache@v2 @@ -127,7 +127,7 @@ jobs: timeout-minutes: 60 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 #- name: Cache cargo installed crates # uses: actions/cache@v2 diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml b/compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml index a019793edd..0a3e7ca073 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml @@ -11,7 +11,7 @@ jobs: timeout-minutes: 60 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache cargo installed crates uses: actions/cache@v2 @@ -34,7 +34,7 @@ jobs: sed -i 's/cranelift-jit = { version = "\w*.\w*.\w*", optional = true }/cranelift-jit = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git", optional = true }/' Cargo.toml sed -i 's/cranelift-object = "\w*.\w*.\w*"/cranelift-object = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml - sed -i 's/gimli = { version = "0.25.0", default-features = false, features = \["write"\]}/gimli = { version = "0.26.1", default-features = false, features = ["write"] }/' Cargo.toml + sed -i 's/object = { version = "0.27.0"/object = { version = "0.28.0"/' Cargo.toml cat Cargo.toml diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml index 1c08e5ece3..b8a98b83eb 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache cargo installed crates uses: actions/cache@v2 @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache cargo installed crates uses: actions/cache@v2 diff --git a/compiler/rustc_codegen_cranelift/.vscode/settings.json b/compiler/rustc_codegen_cranelift/.vscode/settings.json index 74fde9c27c..ecb20f22d8 100644 --- a/compiler/rustc_codegen_cranelift/.vscode/settings.json +++ b/compiler/rustc_codegen_cranelift/.vscode/settings.json @@ -5,7 +5,7 @@ "rust-analyzer.assist.importEnforceGranularity": true, "rust-analyzer.assist.importPrefix": "crate", "rust-analyzer.cargo.runBuildScripts": true, - "rust-analyzer.cargo.features": ["unstable-features"] + "rust-analyzer.cargo.features": ["unstable-features"], "rust-analyzer.linkedProjects": [ "./Cargo.toml", //"./build_sysroot/sysroot_src/src/libstd/Cargo.toml", diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock index 7b8e43b639..dac1cef383 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/Cargo.lock @@ -163,15 +163,15 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", "hashbrown", diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml index 74f50808a9..781f26b24d 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/Cargo.toml @@ -19,7 +19,7 @@ gimli = { version = "0.26.0", default-features = false, features = ["write"]} object = { version = "0.27.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" } -indexmap = "1.8.0" +indexmap = "1.9.1" libloading = { version = "0.6.0", optional = true } once_cell = "1.10.0" smallvec = "1.6.1" @@ -41,15 +41,5 @@ unstable-features = ["jit", "inline_asm"] jit = ["cranelift-jit", "libloading"] inline_asm = [] -# Disable optimizations and debuginfo of build scripts and some of the heavy build deps, as the -# execution time of build scripts is so fast that optimizing them slows down the total build time. -[profile.release.build-override] -opt-level = 0 -debug = false - -[profile.release.package.cranelift-codegen-meta] -opt-level = 0 -debug = false - [package.metadata.rust-analyzer] rustc_private = true diff --git a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock index 51ba0dbfcc..efee6ef3f3 100644 --- a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock @@ -112,9 +112,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", @@ -134,18 +134,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.124" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" dependencies = [ "rustc-std-workspace-core", ] [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", diff --git a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs index 0a56eb131e..48faec8bc4 100644 --- a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs +++ b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs @@ -34,18 +34,6 @@ pub(crate) fn build_backend( _ => unreachable!(), } - // Set the rpath to make the cg_clif executable find librustc_codegen_cranelift without changing - // LD_LIBRARY_PATH - if cfg!(unix) { - if cfg!(target_os = "macos") { - rustflags += " -Csplit-debuginfo=unpacked \ - -Clink-arg=-Wl,-rpath,@loader_path/../lib \ - -Zosx-rpath-install-name"; - } else { - rustflags += " -Clink-arg=-Wl,-rpath=$ORIGIN/../lib "; - } - } - cmd.env("RUSTFLAGS", rustflags); eprintln!("[BUILD] rustc_codegen_cranelift"); diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs index c9c003d461..8682204f4f 100644 --- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs +++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs @@ -1,4 +1,3 @@ -use std::env; use std::fs; use std::path::{Path, PathBuf}; use std::process::{self, Command}; @@ -22,35 +21,28 @@ pub(crate) fn build_sysroot( fs::create_dir_all(target_dir.join("lib")).unwrap(); // Copy the backend - for file in ["cg_clif", "cg_clif_build_sysroot"] { - try_hard_link( - cg_clif_build_dir.join(get_file_name(file, "bin")), - target_dir.join("bin").join(get_file_name(file, "bin")), - ); - } - let cg_clif_dylib = get_file_name("rustc_codegen_cranelift", "dylib"); - try_hard_link( - cg_clif_build_dir.join(&cg_clif_dylib), - target_dir - .join(if cfg!(windows) { - // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the - // binaries. - "bin" - } else { - "lib" - }) - .join(cg_clif_dylib), - ); - - // Build and copy cargo wrapper - let mut build_cargo_wrapper_cmd = Command::new("rustc"); - build_cargo_wrapper_cmd - .arg("scripts/cargo-clif.rs") - .arg("-o") - .arg(target_dir.join("cargo-clif")) - .arg("-g"); - spawn_and_wait(build_cargo_wrapper_cmd); + let cg_clif_dylib_path = target_dir + .join(if cfg!(windows) { + // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the + // binaries. + "bin" + } else { + "lib" + }) + .join(&cg_clif_dylib); + try_hard_link(cg_clif_build_dir.join(cg_clif_dylib), &cg_clif_dylib_path); + + // Build and copy rustc and cargo wrappers + for wrapper in ["rustc-clif", "cargo-clif"] { + let mut build_cargo_wrapper_cmd = Command::new("rustc"); + build_cargo_wrapper_cmd + .arg(PathBuf::from("scripts").join(format!("{wrapper}.rs"))) + .arg("-o") + .arg(target_dir.join(wrapper)) + .arg("-g"); + spawn_and_wait(build_cargo_wrapper_cmd); + } let default_sysroot = super::rustc_info::get_default_sysroot(); @@ -117,7 +109,13 @@ pub(crate) fn build_sysroot( } } SysrootKind::Clif => { - build_clif_sysroot_for_triple(channel, target_dir, host_triple, None); + build_clif_sysroot_for_triple( + channel, + target_dir, + host_triple, + &cg_clif_dylib_path, + None, + ); if host_triple != target_triple { // When cross-compiling it is often necessary to manually pick the right linker @@ -126,14 +124,21 @@ pub(crate) fn build_sysroot( } else { None }; - build_clif_sysroot_for_triple(channel, target_dir, target_triple, linker); + build_clif_sysroot_for_triple( + channel, + target_dir, + target_triple, + &cg_clif_dylib_path, + linker, + ); } // Copy std for the host to the lib dir. This is necessary for the jit mode to find // libstd. for file in fs::read_dir(host_rustlib_lib).unwrap() { let file = file.unwrap().path(); - if file.file_name().unwrap().to_str().unwrap().contains("std-") { + let filename = file.file_name().unwrap().to_str().unwrap(); + if filename.contains("std-") && !filename.contains(".rlib") { try_hard_link(&file, target_dir.join("lib").join(file.file_name().unwrap())); } } @@ -145,6 +150,7 @@ fn build_clif_sysroot_for_triple( channel: &str, target_dir: &Path, triple: &str, + cg_clif_dylib_path: &Path, linker: Option<&str>, ) { match fs::read_to_string(Path::new("build_sysroot").join("rustc_version")) { @@ -168,18 +174,18 @@ fn build_clif_sysroot_for_triple( let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel); if !super::config::get_bool("keep_sysroot") { - // Cleanup the target dir with the exception of build scripts and the incremental cache - for dir in ["build", "deps", "examples", "native"] { - if build_dir.join(dir).exists() { - fs::remove_dir_all(build_dir.join(dir)).unwrap(); - } + // Cleanup the deps dir, but keep build scripts and the incremental cache for faster + // recompilation as they are not affected by changes in cg_clif. + if build_dir.join("deps").exists() { + fs::remove_dir_all(build_dir.join("deps")).unwrap(); } } // Build sysroot let mut build_cmd = Command::new("cargo"); build_cmd.arg("build").arg("--target").arg(triple).current_dir("build_sysroot"); - let mut rustflags = "--clif -Zforce-unstable-if-unmarked".to_string(); + let mut rustflags = "-Zforce-unstable-if-unmarked -Cpanic=abort".to_string(); + rustflags.push_str(&format!(" -Zcodegen-backend={}", cg_clif_dylib_path.to_str().unwrap())); if channel == "release" { build_cmd.arg("--release"); rustflags.push_str(" -Zmir-opt-level=3"); @@ -189,10 +195,6 @@ fn build_clif_sysroot_for_triple( write!(rustflags, " -Clinker={}", linker).unwrap(); } build_cmd.env("RUSTFLAGS", rustflags); - build_cmd.env( - "RUSTC", - env::current_dir().unwrap().join(target_dir).join("bin").join("cg_clif_build_sysroot"), - ); build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif"); spawn_and_wait(build_cmd); diff --git a/compiler/rustc_codegen_cranelift/build_system/mod.rs b/compiler/rustc_codegen_cranelift/build_system/mod.rs index b228da3981..b897b7fbac 100644 --- a/compiler/rustc_codegen_cranelift/build_system/mod.rs +++ b/compiler/rustc_codegen_cranelift/build_system/mod.rs @@ -86,6 +86,7 @@ pub fn main() { arg => arg_error!("Unexpected argument {}", arg), } } + target_dir = std::env::current_dir().unwrap().join(target_dir); let host_triple = if let Ok(host_triple) = std::env::var("HOST_TRIPLE") { host_triple diff --git a/compiler/rustc_codegen_cranelift/docs/usage.md b/compiler/rustc_codegen_cranelift/docs/usage.md index 785c738378..33f146e7ba 100644 --- a/compiler/rustc_codegen_cranelift/docs/usage.md +++ b/compiler/rustc_codegen_cranelift/docs/usage.md @@ -19,7 +19,7 @@ This will build your project with rustc_codegen_cranelift instead of the usual L > You should prefer using the Cargo method. ```bash -$ $cg_clif_dir/build/bin/cg_clif my_crate.rs +$ $cg_clif_dir/build/rustc-clif my_crate.rs ``` ## Jit mode @@ -38,7 +38,7 @@ $ $cg_clif_dir/build/cargo-clif jit or ```bash -$ $cg_clif_dir/build/bin/cg_clif -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs +$ $cg_clif_dir/build/rustc-clif -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs ``` There is also an experimental lazy jit mode. In this mode functions are only compiled once they are @@ -54,7 +54,7 @@ These are a few functions that allow you to easily run rust code from the shell ```bash function jit_naked() { - echo "$@" | $cg_clif_dir/build/bin/cg_clif - -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic + echo "$@" | $cg_clif_dir/build/rustc-clif - -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic } function jit() { diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 8da705e0cb..489259d1a6 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -567,7 +567,7 @@ pub mod intrinsics { pub fn copy(src: *const T, dst: *mut T, count: usize); pub fn transmute(e: T) -> U; pub fn ctlz_nonzero(x: T) -> T; - pub fn needs_drop() -> bool; + pub fn needs_drop() -> bool; pub fn bitreverse(x: T) -> T; pub fn bswap(x: T) -> T; pub fn write_bytes(dst: *mut T, val: u8, count: usize); diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index 85ca908d0a..0f1245c275 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs @@ -55,6 +55,11 @@ struct NoisyDrop { inner: NoisyDropInner, } +struct NoisyDropUnsized { + inner: NoisyDropInner, + text: str, +} + struct NoisyDropInner; impl Drop for NoisyDrop { @@ -170,7 +175,9 @@ fn main() { assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8); assert!(!intrinsics::needs_drop::()); + assert!(!intrinsics::needs_drop::<[u8]>()); assert!(intrinsics::needs_drop::()); + assert!(intrinsics::needs_drop::()); Unique { pointer: NonNull(1 as *mut &str), diff --git a/compiler/rustc_codegen_cranelift/patches/0027-sysroot-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-sysroot-128bit-atomic-operations.patch index 8e6652af37..ce1c6c99b4 100644 --- a/compiler/rustc_codegen_cranelift/patches/0027-sysroot-128bit-atomic-operations.patch +++ b/compiler/rustc_codegen_cranelift/patches/0027-sysroot-128bit-atomic-operations.patch @@ -21,7 +21,7 @@ index 092b7cf..158cf71 100644 -#[cfg(target_has_atomic_load_store = "128")] -#[unstable(feature = "integer_atomics", issue = "32976")] -impl RefUnwindSafe for crate::sync::atomic::AtomicI128 {} - + #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] @@ -235,9 +232,6 @@ impl RefUnwindSafe for crate::sync::atomic::AtomicU32 {} @@ -31,14 +31,14 @@ index 092b7cf..158cf71 100644 -#[cfg(target_has_atomic_load_store = "128")] -#[unstable(feature = "integer_atomics", issue = "32976")] -impl RefUnwindSafe for crate::sync::atomic::AtomicU128 {} - + #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index d9de37e..8293fce 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs -@@ -2234,44 +2234,6 @@ atomic_int! { +@@ -2234,46 +2234,6 @@ atomic_int! { "AtomicU64::new(0)", u64 AtomicU64 ATOMIC_U64_INIT } @@ -54,6 +54,7 @@ index d9de37e..8293fce 100644 - unstable(feature = "integer_atomics", issue = "32976"), - rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), - unstable(feature = "integer_atomics", issue = "32976"), +- cfg_attr(not(test), rustc_diagnostic_item = "AtomicI128"), - "i128", - "#![feature(integer_atomics)]\n\n", - atomic_min, atomic_max, @@ -73,6 +74,7 @@ index d9de37e..8293fce 100644 - unstable(feature = "integer_atomics", issue = "32976"), - rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), - unstable(feature = "integer_atomics", issue = "32976"), +- cfg_attr(not(test), rustc_diagnostic_item = "AtomicU128"), - "u128", - "#![feature(integer_atomics)]\n\n", - atomic_umin, atomic_umax, @@ -98,6 +100,6 @@ index b735957..ea728b6 100644 #[cfg(target_has_atomic = "ptr")] assert_eq!(align_of::(), size_of::()); #[cfg(target_has_atomic = "ptr")] --- +-- 2.26.2.7.g19db9cfb68 diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain index 966097c248..e98e92e468 100644 --- a/compiler/rustc_codegen_cranelift/rust-toolchain +++ b/compiler/rustc_codegen_cranelift/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2022-04-21" +channel = "nightly-2022-05-15" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs b/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs index 41d82b581c..9362b47fa6 100644 --- a/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs +++ b/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs @@ -5,20 +5,11 @@ use std::path::PathBuf; use std::process::Command; fn main() { - if env::var("RUSTC_WRAPPER").map_or(false, |wrapper| wrapper.contains("sccache")) { - eprintln!( - "\x1b[1;93m=== Warning: Unsetting RUSTC_WRAPPER to prevent interference with sccache ===\x1b[0m" - ); - env::remove_var("RUSTC_WRAPPER"); - } - let sysroot = PathBuf::from(env::current_exe().unwrap().parent().unwrap()); - env::set_var("RUSTC", sysroot.join("bin/cg_clif".to_string() + env::consts::EXE_SUFFIX)); - - let mut rustdoc_flags = env::var("RUSTDOCFLAGS").unwrap_or(String::new()); - rustdoc_flags.push_str(" -Cpanic=abort -Zpanic-abort-tests -Zcodegen-backend="); - rustdoc_flags.push_str( + let mut rustflags = String::new(); + rustflags.push_str(" -Cpanic=abort -Zpanic-abort-tests -Zcodegen-backend="); + rustflags.push_str( sysroot .join(if cfg!(windows) { "bin" } else { "lib" }) .join( @@ -29,9 +20,10 @@ fn main() { .to_str() .unwrap(), ); - rustdoc_flags.push_str(" --sysroot "); - rustdoc_flags.push_str(sysroot.to_str().unwrap()); - env::set_var("RUSTDOCFLAGS", rustdoc_flags); + rustflags.push_str(" --sysroot "); + rustflags.push_str(sysroot.to_str().unwrap()); + env::set_var("RUSTFLAGS", env::var("RUSTFLAGS").unwrap_or(String::new()) + &rustflags); + env::set_var("RUSTDOCFLAGS", env::var("RUSTDOCFLAGS").unwrap_or(String::new()) + &rustflags); // Ensure that the right toolchain is used env::set_var("RUSTUP_TOOLCHAIN", env!("RUSTUP_TOOLCHAIN")); @@ -46,7 +38,7 @@ fn main() { .chain(env::args().skip(2)) .chain([ "--".to_string(), - "-Zunstable-features".to_string(), + "-Zunstable-options".to_string(), "-Cllvm-args=mode=jit".to_string(), ]) .collect() @@ -60,7 +52,7 @@ fn main() { .chain(env::args().skip(2)) .chain([ "--".to_string(), - "-Zunstable-features".to_string(), + "-Zunstable-options".to_string(), "-Cllvm-args=mode=jit-lazy".to_string(), ]) .collect() diff --git a/compiler/rustc_codegen_cranelift/scripts/config.sh b/compiler/rustc_codegen_cranelift/scripts/config.sh deleted file mode 100644 index 53ada369b0..0000000000 --- a/compiler/rustc_codegen_cranelift/scripts/config.sh +++ /dev/null @@ -1,6 +0,0 @@ -# Note to people running shellcheck: this file should only be sourced, not executed directly. - -set -e - -export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH" -export DYLD_LIBRARY_PATH="$(rustc --print sysroot)/lib:$DYLD_LIBRARY_PATH" diff --git a/compiler/rustc_codegen_cranelift/scripts/ext_config.sh b/compiler/rustc_codegen_cranelift/scripts/ext_config.sh deleted file mode 100644 index 11d6c4c831..0000000000 --- a/compiler/rustc_codegen_cranelift/scripts/ext_config.sh +++ /dev/null @@ -1,32 +0,0 @@ -# Note to people running shellcheck: this file should only be sourced, not executed directly. - -# Various env vars that should only be set for the build system - -set -e - -export CG_CLIF_DISPLAY_CG_TIME=1 -export CG_CLIF_DISABLE_INCR_CACHE=1 - -export HOST_TRIPLE=$(rustc -vV | grep host | cut -d: -f2 | tr -d " ") -export TARGET_TRIPLE=${TARGET_TRIPLE:-$HOST_TRIPLE} - -export RUN_WRAPPER='' -export JIT_SUPPORTED=1 -if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then - export JIT_SUPPORTED=0 - if [[ "$TARGET_TRIPLE" == "aarch64-unknown-linux-gnu" ]]; then - # We are cross-compiling for aarch64. Use the correct linker and run tests in qemu. - export RUSTFLAGS='-Clinker=aarch64-linux-gnu-gcc '$RUSTFLAGS - export RUN_WRAPPER='qemu-aarch64 -L /usr/aarch64-linux-gnu' - elif [[ "$TARGET_TRIPLE" == "x86_64-pc-windows-gnu" ]]; then - # We are cross-compiling for Windows. Run tests in wine. - export RUN_WRAPPER='wine' - else - echo "Unknown non-native platform" - fi -fi - -# FIXME fix `#[linkage = "extern_weak"]` without this -if [[ "$(uname)" == 'Darwin' ]]; then - export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup" -fi diff --git a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs index f4e863e549..e6f60d1c0c 100755 --- a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs +++ b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs @@ -2,8 +2,7 @@ #![forbid(unsafe_code)]/* This line is ignored by bash # This block is ignored by rustc pushd $(dirname "$0")/../ -source scripts/config.sh -RUSTC="$(pwd)/build/bin/cg_clif" +RUSTC="$(pwd)/build/rustc-clif" popd PROFILE=$1 OUTPUT=$2 exec $RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic $0 #*/ diff --git a/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs b/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs new file mode 100644 index 0000000000..3abfcd8ddc --- /dev/null +++ b/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs @@ -0,0 +1,36 @@ +use std::env; +use std::ffi::OsString; +#[cfg(unix)] +use std::os::unix::process::CommandExt; +use std::path::PathBuf; +use std::process::Command; + +fn main() { + let sysroot = PathBuf::from(env::current_exe().unwrap().parent().unwrap()); + + let cg_clif_dylib_path = sysroot.join(if cfg!(windows) { "bin" } else { "lib" }).join( + env::consts::DLL_PREFIX.to_string() + "rustc_codegen_cranelift" + env::consts::DLL_SUFFIX, + ); + + let mut args = std::env::args_os().skip(1).collect::>(); + args.push(OsString::from("-Cpanic=abort")); + args.push(OsString::from("-Zpanic-abort-tests")); + let mut codegen_backend_arg = OsString::from("-Zcodegen-backend="); + codegen_backend_arg.push(cg_clif_dylib_path); + args.push(codegen_backend_arg); + if !args.contains(&OsString::from("--sysroot")) { + args.push(OsString::from("--sysroot")); + args.push(OsString::from(sysroot.to_str().unwrap())); + } + + // Ensure that the right toolchain is used + env::set_var("RUSTUP_TOOLCHAIN", env!("RUSTUP_TOOLCHAIN")); + + #[cfg(unix)] + Command::new("rustc").args(args).exec(); + + #[cfg(not(unix))] + std::process::exit( + Command::new("rustc").args(args).spawn().unwrap().wait().unwrap().code().unwrap_or(1), + ); +} diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh index cabbaaa892..4d0dfa16c5 100644 --- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh +++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh @@ -2,7 +2,6 @@ set -e ./y.rs build --no-unstable-features -source scripts/config.sh echo "[SETUP] Rust fork" git clone https://github.com/rust-lang/rust.git || true @@ -26,21 +25,6 @@ index d95b5b7f17f..00b6f0e3635 100644 [dev-dependencies] rand = "0.7" rand_xorshift = "0.2" -diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs -index 887d27fd6dca4..2c2239f2b83d1 100644 ---- a/src/tools/compiletest/src/header.rs -+++ b/src/tools/compiletest/src/header.rs -@@ -806,8 +806,8 @@ pub fn make_test_description( - cfg: Option<&str>, - ) -> test::TestDesc { - let mut ignore = false; - #[cfg(not(bootstrap))] -- let ignore_message: Option = None; -+ let ignore_message: Option<&str> = None; - let mut should_fail = false; - - let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some(); - diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8431aa7b818..a3ff7e68ce5 100644 --- a/src/tools/compiletest/src/runtest.rs @@ -67,7 +51,7 @@ changelog-seen = 2 ninja = false [build] -rustc = "$(pwd)/../build/bin/cg_clif" +rustc = "$(pwd)/../build/rustc-clif" cargo = "$(rustup which cargo)" full-bootstrap = true local-rebuild = true diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 4cf24c0223..9bdb9f22c5 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -101,11 +101,10 @@ rm src/test/incremental/spike-neg1.rs # errors out for some reason rm src/test/incremental/spike-neg2.rs # same rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs rm src/test/ui/mir/ssa-analysis-regression-50041.rs # produces ICE +rm src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs # produces ICE rm src/test/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors -rm src/test/ui/rfc-2091-track-caller/intrinsic-wrapper.rs # wrong result from `Location::caller()` - # bugs in the test suite # ====================== rm src/test/ui/backtrace.rs # TODO warning diff --git a/compiler/rustc_codegen_cranelift/scripts/tests.sh b/compiler/rustc_codegen_cranelift/scripts/tests.sh index aae626081f..9b5ffa4096 100755 --- a/compiler/rustc_codegen_cranelift/scripts/tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/tests.sh @@ -2,10 +2,43 @@ set -e -source scripts/config.sh -source scripts/ext_config.sh -export RUSTC=false # ensure that cg_llvm isn't accidentally used -MY_RUSTC="$(pwd)/build/bin/cg_clif $RUSTFLAGS -L crate=target/out --out-dir target/out -Cdebuginfo=2" +export CG_CLIF_DISPLAY_CG_TIME=1 +export CG_CLIF_DISABLE_INCR_CACHE=1 + +export HOST_TRIPLE=$(rustc -vV | grep host | cut -d: -f2 | tr -d " ") +export TARGET_TRIPLE=${TARGET_TRIPLE:-$HOST_TRIPLE} + +export RUN_WRAPPER='' + +case "$TARGET_TRIPLE" in + x86_64*) + export JIT_SUPPORTED=1 + ;; + *) + export JIT_SUPPORTED=0 + ;; +esac + +if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then + export JIT_SUPPORTED=0 + if [[ "$TARGET_TRIPLE" == "aarch64-unknown-linux-gnu" ]]; then + # We are cross-compiling for aarch64. Use the correct linker and run tests in qemu. + export RUSTFLAGS='-Clinker=aarch64-linux-gnu-gcc '$RUSTFLAGS + export RUN_WRAPPER='qemu-aarch64 -L /usr/aarch64-linux-gnu' + elif [[ "$TARGET_TRIPLE" == "x86_64-pc-windows-gnu" ]]; then + # We are cross-compiling for Windows. Run tests in wine. + export RUN_WRAPPER='wine' + else + echo "Unknown non-native platform" + fi +fi + +# FIXME fix `#[linkage = "extern_weak"]` without this +if [[ "$(uname)" == 'Darwin' ]]; then + export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup" +fi + +MY_RUSTC="$(pwd)/build/rustc-clif $RUSTFLAGS -L crate=target/out --out-dir target/out -Cdebuginfo=2" function no_sysroot_tests() { echo "[BUILD] mini_core" @@ -39,7 +72,7 @@ function base_sysroot_tests() { $MY_RUSTC example/issue-91827-extern-types.rs --crate-name issue_91827_extern_types --crate-type bin --target "$TARGET_TRIPLE" $RUN_WRAPPER ./target/out/issue_91827_extern_types - echo "[AOT] alloc_system" + echo "[BUILD] alloc_system" $MY_RUSTC example/alloc_system.rs --crate-type lib --target "$TARGET_TRIPLE" echo "[AOT] alloc_example" @@ -56,14 +89,14 @@ function base_sysroot_tests() { echo "[JIT] std_example (skipped)" fi - echo "[AOT] dst_field_align" - $MY_RUSTC example/dst-field-align.rs --crate-name dst_field_align --crate-type bin --target "$TARGET_TRIPLE" - $RUN_WRAPPER ./target/out/dst_field_align || (echo $?; false) - echo "[AOT] std_example" $MY_RUSTC example/std_example.rs --crate-type bin --target "$TARGET_TRIPLE" $RUN_WRAPPER ./target/out/std_example arg + echo "[AOT] dst_field_align" + $MY_RUSTC example/dst-field-align.rs --crate-name dst_field_align --crate-type bin --target "$TARGET_TRIPLE" + $RUN_WRAPPER ./target/out/dst_field_align + echo "[AOT] subslice-patterns-const-eval" $MY_RUSTC example/subslice-patterns-const-eval.rs --crate-type bin -Cpanic=abort --target "$TARGET_TRIPLE" $RUN_WRAPPER ./target/out/subslice-patterns-const-eval @@ -97,7 +130,7 @@ function extended_sysroot_tests() { if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then echo "[BENCH COMPILE] ebobby/simple-raytracer" hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "../build/cargo-clif clean" \ - "RUSTC=rustc RUSTFLAGS='' cargo build" \ + "RUSTFLAGS='' cargo build" \ "../build/cargo-clif build" echo "[BENCH RUN] ebobby/simple-raytracer" diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index ef56fb191b..ffa5d747b1 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -23,6 +23,7 @@ fn clif_sig_from_fn_abi<'tcx>( ) -> Signature { let call_conv = match fn_abi.conv { Conv::Rust | Conv::C => default_call_conv, + Conv::RustCold => CallConv::Cold, Conv::X86_64SysV => CallConv::SystemV, Conv::X86_64Win64 => CallConv::WindowsFastcall, Conv::ArmAapcs @@ -309,16 +310,17 @@ fn codegen_call_argument_operand<'tcx>( pub(crate) fn codegen_terminator_call<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - span: Span, + source_info: mir::SourceInfo, func: &Operand<'tcx>, args: &[Operand<'tcx>], - mir_dest: Option<(Place<'tcx>, BasicBlock)>, + destination: Place<'tcx>, + target: Option, ) { let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx)); let fn_sig = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); - let destination = mir_dest.map(|(place, bb)| (codegen_place(fx, place), bb)); + let ret_place = codegen_place(fx, destination); // Handle special calls like instrinsics and empty drop glue. let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() { @@ -333,19 +335,27 @@ pub(crate) fn codegen_terminator_call<'tcx>( &fx.tcx.symbol_name(instance).name, substs, args, - destination, + ret_place, + target, ); return; } match instance.def { InstanceDef::Intrinsic(_) => { - crate::intrinsics::codegen_intrinsic_call(fx, instance, args, destination, span); + crate::intrinsics::codegen_intrinsic_call( + fx, + instance, + args, + ret_place, + target, + source_info, + ); return; } InstanceDef::DropGlue(_, None) => { // empty drop glue - a nop. - let (_, dest) = destination.expect("Non terminating drop_in_place_real???"); + let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); fx.bcx.ins().jump(ret_block, &[]); return; @@ -371,7 +381,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( .unwrap_or(false); if is_cold { fx.bcx.set_cold_block(fx.bcx.current_block().unwrap()); - if let Some((_place, destination_block)) = destination { + if let Some(destination_block) = target { fx.bcx.set_cold_block(fx.get_block(destination_block)); } } @@ -402,7 +412,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // Pass the caller location for `#[track_caller]`. if instance.map(|inst| inst.def.requires_caller_location(fx.tcx)).unwrap_or(false) { - let caller_location = fx.get_caller_location(span); + let caller_location = fx.get_caller_location(source_info); args.push(CallArgument { value: caller_location, is_owned: false }); } @@ -453,7 +463,6 @@ pub(crate) fn codegen_terminator_call<'tcx>( } }; - let ret_place = destination.map(|(place, _)| place); self::returning::codegen_with_call_return_arg(fx, &fn_abi.ret, ret_place, |fx, return_ptr| { let call_args = return_ptr .into_iter() @@ -479,9 +488,10 @@ pub(crate) fn codegen_terminator_call<'tcx>( // FIXME find a cleaner way to support varargs if fn_sig.c_variadic { if !matches!(fn_sig.abi, Abi::C { .. }) { - fx.tcx - .sess - .span_fatal(span, &format!("Variadic call for non-C abi {:?}", fn_sig.abi)); + fx.tcx.sess.span_fatal( + source_info.span, + &format!("Variadic call for non-C abi {:?}", fn_sig.abi), + ); } let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); let abi_params = call_args @@ -490,9 +500,10 @@ pub(crate) fn codegen_terminator_call<'tcx>( let ty = fx.bcx.func.dfg.value_type(arg); if !ty.is_int() { // FIXME set %al to upperbound on float args once floats are supported - fx.tcx - .sess - .span_fatal(span, &format!("Non int ty {:?} for variadic call", ty)); + fx.tcx.sess.span_fatal( + source_info.span, + &format!("Non int ty {:?} for variadic call", ty), + ); } AbiParam::new(ty) }) @@ -503,7 +514,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( call_inst }); - if let Some((_, dest)) = destination { + if let Some(dest) = target { let ret_block = fx.get_block(dest); fx.bcx.ins().jump(ret_block, &[]); } else { @@ -513,7 +524,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( pub(crate) fn codegen_drop<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - span: Span, + source_info: mir::SourceInfo, drop_place: CPlace<'tcx>, ) { let ty = drop_place.layout().ty; @@ -560,7 +571,7 @@ pub(crate) fn codegen_drop<'tcx>( if drop_instance.def.requires_caller_location(fx.tcx) { // Pass the caller location for `#[track_caller]`. - let caller_location = fx.get_caller_location(span); + let caller_location = fx.get_caller_location(source_info); call_args.extend( adjust_arg_for_abi(fx, caller_location, &fn_abi.args[1], false).into_iter(), ); diff --git a/compiler/rustc_codegen_cranelift/src/abi/returning.rs b/compiler/rustc_codegen_cranelift/src/abi/returning.rs index c1bdba43e6..ff3bb2dfd0 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/returning.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/returning.rs @@ -56,23 +56,22 @@ pub(super) fn codegen_return_param<'tcx>( pub(super) fn codegen_with_call_return_arg<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, ret_arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, - ret_place: Option>, + ret_place: CPlace<'tcx>, f: impl FnOnce(&mut FunctionCx<'_, '_, 'tcx>, Option) -> Inst, ) { let (ret_temp_place, return_ptr) = match ret_arg_abi.mode { PassMode::Ignore => (None, None), - PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => match ret_place { - Some(ret_place) if matches!(ret_place.inner(), CPlaceInner::Addr(_, None)) => { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { + if matches!(ret_place.inner(), CPlaceInner::Addr(_, None)) { // This is an optimization to prevent unnecessary copies of the return value when // the return place is already a memory place as opposed to a register. // This match arm can be safely removed. (None, Some(ret_place.to_ptr().get_addr(fx))) - } - _ => { + } else { let place = CPlace::new_stack_slot(fx, ret_arg_abi.layout); (Some(place), Some(place.to_ptr().get_addr(fx))) } - }, + } PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") } @@ -84,39 +83,25 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( match ret_arg_abi.mode { PassMode::Ignore => {} PassMode::Direct(_) => { - if let Some(ret_place) = ret_place { - let ret_val = fx.bcx.inst_results(call_inst)[0]; - ret_place.write_cvalue(fx, CValue::by_val(ret_val, ret_arg_abi.layout)); - } + let ret_val = fx.bcx.inst_results(call_inst)[0]; + ret_place.write_cvalue(fx, CValue::by_val(ret_val, ret_arg_abi.layout)); } PassMode::Pair(_, _) => { - if let Some(ret_place) = ret_place { - let ret_val_a = fx.bcx.inst_results(call_inst)[0]; - let ret_val_b = fx.bcx.inst_results(call_inst)[1]; - ret_place.write_cvalue( - fx, - CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout), - ); - } + let ret_val_a = fx.bcx.inst_results(call_inst)[0]; + let ret_val_b = fx.bcx.inst_results(call_inst)[1]; + ret_place + .write_cvalue(fx, CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout)); } PassMode::Cast(cast) => { - if let Some(ret_place) = ret_place { - let results = fx - .bcx - .inst_results(call_inst) - .iter() - .copied() - .collect::>(); - let result = - super::pass_mode::from_casted_value(fx, &results, ret_place.layout(), cast); - ret_place.write_cvalue(fx, result); - } + let results = + fx.bcx.inst_results(call_inst).iter().copied().collect::>(); + let result = + super::pass_mode::from_casted_value(fx, &results, ret_place.layout(), cast); + ret_place.write_cvalue(fx, result); } PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { - if let (Some(ret_place), Some(ret_temp_place)) = (ret_place, ret_temp_place) { - // Both ret_place and ret_temp_place must be Some. If ret_place is None, this is - // a non-returning call. If ret_temp_place is None, it is not necessary to copy the - // return value. + if let Some(ret_temp_place) = ret_temp_place { + // If ret_temp_place is None, it is not necessary to copy the return value. let ret_temp_value = ret_temp_place.to_cvalue(fx); ret_place.write_cvalue(fx, ret_temp_value); } diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs index a099e8b3a6..0812f930b5 100644 --- a/compiler/rustc_codegen_cranelift/src/archive.rs +++ b/compiler/rustc_codegen_cranelift/src/archive.rs @@ -30,25 +30,7 @@ pub(crate) struct ArArchiveBuilder<'a> { } impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { - fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self { - let (src_archives, entries) = if let Some(input) = input { - let read_cache = ReadCache::new(File::open(input).unwrap()); - let archive = ArchiveFile::parse(&read_cache).unwrap(); - let mut entries = Vec::new(); - - for entry in archive.members() { - let entry = entry.unwrap(); - entries.push(( - entry.name().to_vec(), - ArchiveEntry::FromArchive { archive_index: 0, file_range: entry.file_range() }, - )); - } - - (vec![read_cache.into_inner()], entries) - } else { - (vec![], Vec::new()) - }; - + fn new(sess: &'a Session, output: &Path) -> Self { ArArchiveBuilder { sess, dst: output.to_path_buf(), @@ -56,24 +38,11 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { // FIXME fix builtin ranlib on macOS no_builtin_ranlib: sess.target.is_like_osx, - src_archives, - entries, + src_archives: vec![], + entries: vec![], } } - fn src_files(&mut self) -> Vec { - self.entries.iter().map(|(name, _)| String::from_utf8(name.clone()).unwrap()).collect() - } - - fn remove_file(&mut self, name: &str) { - let index = self - .entries - .iter() - .position(|(entry_name, _)| entry_name == name.as_bytes()) - .expect("Tried to remove file not existing in src archive"); - self.entries.remove(index); - } - fn add_file(&mut self, file: &Path) { self.entries.push(( file.file_name().unwrap().to_str().unwrap().to_string().into_bytes(), @@ -105,7 +74,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { Ok(()) } - fn build(mut self) { + fn build(mut self) -> bool { enum BuilderKind { Bsd(ar::Builder), Gnu(ar::GnuBuilder), @@ -204,6 +173,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { ) }; + let any_members = !entries.is_empty(); + // Add all files for (entry_name, data) in entries.into_iter() { let header = ar::Header::new(entry_name, data.len() as u64); @@ -229,6 +200,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { self.sess.fatal(&format!("Ranlib exited with code {:?}", status.code())); } } + + any_members } fn inject_dll_import_lib( diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 65346cb396..fbe830b2b1 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -325,7 +325,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { AssertKind::BoundsCheck { ref len, ref index } => { let len = codegen_operand(fx, len).load_scalar(fx); let index = codegen_operand(fx, index).load_scalar(fx); - let location = fx.get_caller_location(source_info.span).load_scalar(fx); + let location = fx.get_caller_location(source_info).load_scalar(fx); codegen_panic_inner( fx, @@ -336,7 +336,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { } _ => { let msg_str = msg.description(); - codegen_panic(fx, msg_str, source_info.span); + codegen_panic(fx, msg_str, source_info); } } } @@ -393,12 +393,20 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { func, args, destination, + target, fn_span, cleanup: _, from_hir_call: _, } => { fx.tcx.sess.time("codegen call", || { - crate::abi::codegen_terminator_call(fx, *fn_span, func, args, *destination) + crate::abi::codegen_terminator_call( + fx, + mir::SourceInfo { span: *fn_span, ..source_info }, + func, + args, + *destination, + *target, + ) }); } TerminatorKind::InlineAsm { @@ -450,7 +458,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { } TerminatorKind::Drop { place, target, unwind: _ } => { let drop_place = codegen_place(fx, *place); - crate::abi::codegen_drop(fx, source_info.span, drop_place); + crate::abi::codegen_drop(fx, source_info, drop_place); let target_block = fx.get_block(*target); fx.bcx.ins().jump(target_block, &[]); @@ -471,7 +479,7 @@ fn codegen_stmt<'tcx>( fx.set_debug_loc(stmt.source_info); - #[cfg(disabled)] + #[cfg(any())] // This is never true match &stmt.kind { StatementKind::StorageLive(..) | StatementKind::StorageDead(..) => {} // Those are not very useful _ => { @@ -599,7 +607,13 @@ fn codegen_stmt<'tcx>( let operand = codegen_operand(fx, operand); lval.write_cvalue(fx, operand.cast_pointer_to(to_layout)); } - Rvalue::Cast(CastKind::Misc, ref operand, to_ty) => { + Rvalue::Cast( + CastKind::Misc + | CastKind::PointerExposeAddress + | CastKind::PointerFromExposedAddress, + ref operand, + to_ty, + ) => { let operand = codegen_operand(fx, operand); let from_ty = operand.layout().ty; let to_ty = fx.monomorphize(to_ty); @@ -696,7 +710,7 @@ fn codegen_stmt<'tcx>( let times = fx .monomorphize(times) .eval(fx.tcx, ParamEnv::reveal_all()) - .val() + .kind() .try_to_bits(fx.tcx.data_layout.pointer_size) .unwrap(); if operand.layout().size.bytes() == 0 { @@ -898,14 +912,18 @@ pub(crate) fn codegen_operand<'tcx>( } } -pub(crate) fn codegen_panic<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, msg_str: &str, span: Span) { - let location = fx.get_caller_location(span).load_scalar(fx); +pub(crate) fn codegen_panic<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, + msg_str: &str, + source_info: mir::SourceInfo, +) { + let location = fx.get_caller_location(source_info).load_scalar(fx); let msg_ptr = fx.anonymous_str(msg_str); let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); let args = [msg_ptr, msg_len, location]; - codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, span); + codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, source_info.span); } pub(crate) fn codegen_panic_inner<'tcx>( diff --git a/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs b/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs deleted file mode 100644 index 5984ec8412..0000000000 --- a/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs +++ /dev/null @@ -1,94 +0,0 @@ -#![feature(rustc_private)] -#![warn(rust_2018_idioms)] -#![warn(unused_lifetimes)] -#![warn(unreachable_pub)] - -extern crate rustc_data_structures; -extern crate rustc_driver; -extern crate rustc_interface; -extern crate rustc_session; -extern crate rustc_target; - -use std::panic; - -use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; -use rustc_interface::interface; -use rustc_session::config::{ErrorOutputType, TrimmedDefPaths}; -use rustc_session::early_error; -use rustc_target::spec::PanicStrategy; - -// FIXME use std::lazy::SyncLazy once it stabilizes -use once_cell::sync::Lazy; - -const BUG_REPORT_URL: &str = "https://github.com/bjorn3/rustc_codegen_cranelift/issues/new"; - -static DEFAULT_HOOK: Lazy) + Sync + Send + 'static>> = - Lazy::new(|| { - let hook = panic::take_hook(); - panic::set_hook(Box::new(|info| { - // Invoke the default handler, which prints the actual panic message and optionally a backtrace - (*DEFAULT_HOOK)(info); - - // Separate the output with an empty line - eprintln!(); - - // Print the ICE message - rustc_driver::report_ice(info, BUG_REPORT_URL); - })); - hook - }); - -#[derive(Default)] -pub struct CraneliftPassesCallbacks { - time_passes: bool, -} - -impl rustc_driver::Callbacks for CraneliftPassesCallbacks { - fn config(&mut self, config: &mut interface::Config) { - // If a --prints=... option has been given, we don't print the "total" - // time because it will mess up the --prints output. See #64339. - self.time_passes = config.opts.prints.is_empty() - && (config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time); - - config.opts.cg.panic = Some(PanicStrategy::Abort); - config.opts.debugging_opts.panic_abort_tests = true; - config.opts.maybe_sysroot = Some(config.opts.maybe_sysroot.clone().unwrap_or_else(|| { - std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned() - })); - - config.opts.trimmed_def_paths = TrimmedDefPaths::GoodPath; - } -} - -fn main() { - let start_time = std::time::Instant::now(); - let start_rss = get_resident_set_size(); - rustc_driver::init_rustc_env_logger(); - let mut callbacks = CraneliftPassesCallbacks::default(); - Lazy::force(&DEFAULT_HOOK); // Install ice hook - let exit_code = rustc_driver::catch_with_exit_code(|| { - let args = std::env::args_os() - .enumerate() - .map(|(i, arg)| { - arg.into_string().unwrap_or_else(|arg| { - early_error( - ErrorOutputType::default(), - &format!("Argument {} is not valid Unicode: {:?}", i, arg), - ) - }) - }) - .collect::>(); - let mut run_compiler = rustc_driver::RunCompiler::new(&args, &mut callbacks); - run_compiler.set_make_codegen_backend(Some(Box::new(move |_| { - Box::new(rustc_codegen_cranelift::CraneliftCodegenBackend { config: None }) - }))); - run_compiler.run() - }); - - if callbacks.time_passes { - let end_rss = get_resident_set_size(); - print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss); - } - - std::process::exit(exit_code) -} diff --git a/compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs b/compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs deleted file mode 100644 index bde4d71b9a..0000000000 --- a/compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs +++ /dev/null @@ -1,93 +0,0 @@ -//! The only difference between this and cg_clif.rs is that this binary defaults to using cg_llvm -//! instead of cg_clif and requires `--clif` to use cg_clif and that this binary doesn't have JIT -//! support. -//! This is necessary as with Cargo `RUSTC` applies to both target crates and host crates. The host -//! crates must be built with cg_llvm as we are currently building a sysroot for cg_clif. -//! `RUSTFLAGS` however is only applied to target crates, so `--clif` would only be passed to the -//! target crates. - -#![feature(rustc_private)] -#![warn(rust_2018_idioms)] -#![warn(unused_lifetimes)] -#![warn(unreachable_pub)] - -extern crate rustc_driver; -extern crate rustc_interface; -extern crate rustc_session; -extern crate rustc_target; - -use std::path::PathBuf; - -use rustc_interface::interface; -use rustc_session::config::ErrorOutputType; -use rustc_session::early_error; -use rustc_target::spec::PanicStrategy; - -fn find_sysroot() -> String { - // Taken from https://github.com/Manishearth/rust-clippy/pull/911. - let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME")); - let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN")); - match (home, toolchain) { - (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain), - _ => option_env!("RUST_SYSROOT") - .expect("need to specify RUST_SYSROOT env var or use rustup or multirust") - .to_owned(), - } -} - -pub struct CraneliftPassesCallbacks { - use_clif: bool, -} - -impl rustc_driver::Callbacks for CraneliftPassesCallbacks { - fn config(&mut self, config: &mut interface::Config) { - if !self.use_clif { - config.opts.maybe_sysroot = Some(PathBuf::from(find_sysroot())); - return; - } - - config.opts.cg.panic = Some(PanicStrategy::Abort); - config.opts.debugging_opts.panic_abort_tests = true; - config.opts.maybe_sysroot = - Some(std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned()); - } -} - -fn main() { - rustc_driver::init_rustc_env_logger(); - rustc_driver::install_ice_hook(); - let exit_code = rustc_driver::catch_with_exit_code(|| { - let mut use_clif = false; - - let args = std::env::args_os() - .enumerate() - .map(|(i, arg)| { - arg.into_string().unwrap_or_else(|arg| { - early_error( - ErrorOutputType::default(), - &format!("Argument {} is not valid Unicode: {:?}", i, arg), - ) - }) - }) - .filter(|arg| { - if arg == "--clif" { - use_clif = true; - false - } else { - true - } - }) - .collect::>(); - - let mut callbacks = CraneliftPassesCallbacks { use_clif }; - - let mut run_compiler = rustc_driver::RunCompiler::new(&args, &mut callbacks); - if use_clif { - run_compiler.set_make_codegen_backend(Some(Box::new(move |_| { - Box::new(rustc_codegen_cranelift::CraneliftCodegenBackend { config: None }) - }))); - } - run_compiler.run() - }); - std::process::exit(exit_code) -} diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index ffa629ca16..f9dc1b5169 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -340,22 +340,46 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { self.bcx.set_srcloc(SourceLoc::new(index as u32)); } - pub(crate) fn get_caller_location(&mut self, span: Span) -> CValue<'tcx> { - if let Some(loc) = self.caller_location { - // `#[track_caller]` is used; return caller location instead of current location. - return loc; + // Note: must be kept in sync with get_caller_location from cg_ssa + pub(crate) fn get_caller_location(&mut self, mut source_info: mir::SourceInfo) -> CValue<'tcx> { + let span_to_caller_location = |fx: &mut FunctionCx<'_, '_, 'tcx>, span: Span| { + let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); + let caller = fx.tcx.sess.source_map().lookup_char_pos(topmost.lo()); + let const_loc = fx.tcx.const_caller_location(( + rustc_span::symbol::Symbol::intern( + &caller.file.name.prefer_remapped().to_string_lossy(), + ), + caller.line as u32, + caller.col_display as u32 + 1, + )); + crate::constant::codegen_const_value(fx, const_loc, fx.tcx.caller_location_ty()) + }; + + // Walk up the `SourceScope`s, in case some of them are from MIR inlining. + // If so, the starting `source_info.span` is in the innermost inlined + // function, and will be replaced with outer callsite spans as long + // as the inlined functions were `#[track_caller]`. + loop { + let scope_data = &self.mir.source_scopes[source_info.scope]; + + if let Some((callee, callsite_span)) = scope_data.inlined { + // Stop inside the most nested non-`#[track_caller]` function, + // before ever reaching its caller (which is irrelevant). + if !callee.def.requires_caller_location(self.tcx) { + return span_to_caller_location(self, source_info.span); + } + source_info.span = callsite_span; + } + + // Skip past all of the parents with `inlined: None`. + match scope_data.inlined_parent_scope { + Some(parent) => source_info.scope = parent, + None => break, + } } - let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); - let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo()); - let const_loc = self.tcx.const_caller_location(( - rustc_span::symbol::Symbol::intern( - &caller.file.name.prefer_remapped().to_string_lossy(), - ), - caller.line as u32, - caller.col_display as u32 + 1, - )); - crate::constant::codegen_const_value(self, const_loc, self.tcx.caller_location_ty()) + // No inlined `SourceScope`s, or all of them were `#[track_caller]`. + self.caller_location.unwrap_or_else(|| span_to_caller_location(self, source_info.span)) } pub(crate) fn anonymous_str(&mut self, msg: &str) -> Value { diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 57074f0021..ef72e6efb9 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -45,7 +45,7 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { ConstantKind::Ty(ct) => ct, ConstantKind::Val(..) => continue, }; - match const_.val() { + match const_.kind() { ConstKind::Value(_) => {} ConstKind::Unevaluated(unevaluated) => { if let Err(err) = @@ -126,8 +126,8 @@ pub(crate) fn codegen_constant<'tcx>( ConstantKind::Ty(ct) => ct, ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty), }; - let const_val = match const_.val() { - ConstKind::Value(const_val) => const_val, + let const_val = match const_.kind() { + ConstKind::Value(valtree) => fx.tcx.valtree_to_const_val((const_.ty(), valtree)), ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => { @@ -468,9 +468,10 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( ) -> Option> { match operand { Operand::Constant(const_) => match const_.literal { - ConstantKind::Ty(const_) => { - fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val().try_to_value() - } + ConstantKind::Ty(const_) => fx + .monomorphize(const_) + .eval_for_mir(fx.tcx, ParamEnv::reveal_all()) + .try_to_value(fx.tcx), ConstantKind::Val(val, _) => Some(val), }, // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored @@ -542,8 +543,8 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } => unreachable!(), TerminatorKind::InlineAsm { .. } => return None, - TerminatorKind::Call { destination: Some((call_place, _)), .. } - if call_place == place => + TerminatorKind::Call { destination, target: Some(_), .. } + if destination == place => { return None; } diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 5e1e1c81d2..05457ce15e 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -66,11 +66,7 @@ fn emit_module( let work_product = if backend_config.disable_incr_cache { None } else { - rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( - tcx.sess, - &name, - &Some(tmp_file.clone()), - ) + rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(tcx.sess, &name, &tmp_file) }; ModuleCodegenResult( @@ -84,21 +80,16 @@ fn reuse_workproduct_for_cgu( cgu: &CodegenUnit<'_>, work_products: &mut FxHashMap, ) -> CompiledModule { - let mut object = None; - let work_product = cgu.work_product(tcx); - if let Some(saved_file) = &work_product.saved_file { - let obj_out = - tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str())); - object = Some(obj_out.clone()); - let source_file = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, &saved_file); - if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) { - tcx.sess.err(&format!( - "unable to copy {} to {}: {}", - source_file.display(), - obj_out.display(), - err - )); - } + let work_product = cgu.previous_work_product(tcx); + let obj_out = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str())); + let source_file = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, &work_product.saved_file); + if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) { + tcx.sess.err(&format!( + "unable to copy {} to {}: {}", + source_file.display(), + obj_out.display(), + err + )); } work_products.insert(cgu.work_product_id(), work_product); @@ -106,7 +97,7 @@ fn reuse_workproduct_for_cgu( CompiledModule { name: cgu.name().to_string(), kind: ModuleKind::Regular, - object, + object: Some(obj_out), dwarf_object: None, bytecode: None, } diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 7f15bc75fd..a56a910005 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -13,7 +13,7 @@ use rustc_span::Symbol; use cranelift_jit::{JITBuilder, JITModule}; -// FIXME use std::lazy::SyncOnceCell once it stabilizes +// FIXME use std::sync::OnceLock once it stabilizes use once_cell::sync::OnceCell; use crate::{prelude::*, BackendConfig}; @@ -74,6 +74,7 @@ fn create_jit_module<'tcx>( jit_builder.hotswap(hotswap); crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); jit_builder.symbols(imported_symbols); + jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8); let mut jit_module = JITModule::new(jit_builder); let mut cx = crate::CodegenCx::new( @@ -210,8 +211,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { } } -#[no_mangle] -extern "C" fn __clif_jit_fn( +extern "C" fn clif_jit_fn( instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8, ) -> *const u8 { diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs index 0e4f7ee907..77ac46540a 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs @@ -10,10 +10,9 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( intrinsic: &str, _substs: SubstsRef<'tcx>, args: &[mir::Operand<'tcx>], - destination: Option<(CPlace<'tcx>, BasicBlock)>, + ret: CPlace<'tcx>, + target: Option, ) { - let ret = destination.unwrap().0; - intrinsic_match! { fx, intrinsic, args, _ => { @@ -126,7 +125,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( }; } - let dest = destination.expect("all llvm intrinsics used by stdlib should return").1; + let dest = target.expect("all llvm intrinsics used by stdlib should return"); let ret_block = fx.get_block(dest); fx.bcx.ins().jump(ret_block, &[]); } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index f7a83373e8..6937e658ed 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -58,6 +58,7 @@ pub(crate) use llvm::codegen_llvm_intrinsic_call; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::SubstsRef; use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_target::abi::InitKind; use crate::prelude::*; use cranelift_codegen::ir::AtomicRmwOp; @@ -217,35 +218,42 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, instance: Instance<'tcx>, args: &[mir::Operand<'tcx>], - destination: Option<(CPlace<'tcx>, BasicBlock)>, - span: Span, + destination: CPlace<'tcx>, + target: Option, + source_info: mir::SourceInfo, ) { let intrinsic = fx.tcx.item_name(instance.def_id()); let substs = instance.substs; - let ret = match destination { - Some((place, _)) => place, - None => { - // Insert non returning intrinsics here - match intrinsic { - sym::abort => { - fx.bcx.ins().trap(TrapCode::User(0)); - } - sym::transmute => { - crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", span); - } - _ => unimplemented!("unsupported instrinsic {}", intrinsic), + let target = if let Some(target) = target { + target + } else { + // Insert non returning intrinsics here + match intrinsic { + sym::abort => { + fx.bcx.ins().trap(TrapCode::User(0)); } - return; + sym::transmute => { + crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", source_info); + } + _ => unimplemented!("unsupported instrinsic {}", intrinsic), } + return; }; if intrinsic.as_str().starts_with("simd_") { - self::simd::codegen_simd_intrinsic_call(fx, intrinsic, substs, args, ret, span); - let ret_block = fx.get_block(destination.expect("SIMD intrinsics don't diverge").1); + self::simd::codegen_simd_intrinsic_call( + fx, + intrinsic, + substs, + args, + destination, + source_info.span, + ); + let ret_block = fx.get_block(target); fx.bcx.ins().jump(ret_block, &[]); - } else if codegen_float_intrinsic_call(fx, intrinsic, args, ret) { - let ret_block = fx.get_block(destination.expect("Float intrinsics don't diverge").1); + } else if codegen_float_intrinsic_call(fx, intrinsic, args, destination) { + let ret_block = fx.get_block(target); fx.bcx.ins().jump(ret_block, &[]); } else { codegen_regular_intrinsic_call( @@ -254,9 +262,9 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( intrinsic, substs, args, - ret, - span, destination, + Some(target), + source_info, ); } } @@ -339,15 +347,15 @@ fn codegen_regular_intrinsic_call<'tcx>( substs: SubstsRef<'tcx>, args: &[mir::Operand<'tcx>], ret: CPlace<'tcx>, - span: Span, - destination: Option<(CPlace<'tcx>, BasicBlock)>, + destination: Option, + source_info: mir::SourceInfo, ) { let usize_layout = fx.layout_of(fx.tcx.types.usize); intrinsic_match! { fx, intrinsic, args, _ => { - fx.tcx.sess.span_fatal(span, &format!("unsupported intrinsic {}", intrinsic)); + fx.tcx.sess.span_fatal(source_info.span, &format!("unsupported intrinsic {}", intrinsic)); }; assume, (c _a) {}; @@ -658,29 +666,39 @@ fn codegen_regular_intrinsic_call<'tcx>( crate::base::codegen_panic( fx, &format!("attempted to instantiate uninhabited type `{}`", layout.ty), - span, + source_info, ) }); return; } - if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true) { + if intrinsic == sym::assert_zero_valid + && !layout.might_permit_raw_init( + fx, + InitKind::Zero, + fx.tcx.sess.opts.debugging_opts.strict_init_checks) { + with_no_trimmed_paths!({ crate::base::codegen_panic( fx, &format!("attempted to zero-initialize type `{}`, which is invalid", layout.ty), - span, + source_info, ); }); return; } - if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false) { + if intrinsic == sym::assert_uninit_valid + && !layout.might_permit_raw_init( + fx, + InitKind::Uninit, + fx.tcx.sess.opts.debugging_opts.strict_init_checks) { + with_no_trimmed_paths!({ crate::base::codegen_panic( fx, &format!("attempted to leave type `{}` uninitialized, which is invalid", layout.ty), - span, + source_info, ) }); return; @@ -715,19 +733,19 @@ fn codegen_regular_intrinsic_call<'tcx>( ptr_offset_from | ptr_offset_from_unsigned, (v ptr, v base) { let ty = substs.type_at(0); - let isize_layout = fx.layout_of(fx.tcx.types.isize); let pointee_size: u64 = fx.layout_of(ty).size.bytes(); let diff_bytes = fx.bcx.ins().isub(ptr, base); // FIXME this can be an exact division. - let diff = if intrinsic == sym::ptr_offset_from_unsigned { + let val = if intrinsic == sym::ptr_offset_from_unsigned { + let usize_layout = fx.layout_of(fx.tcx.types.usize); // Because diff_bytes ULE isize::MAX, this would be fine as signed, // but unsigned is slightly easier to codegen, so might as well. - fx.bcx.ins().udiv_imm(diff_bytes, pointee_size as i64) + CValue::by_val(fx.bcx.ins().udiv_imm(diff_bytes, pointee_size as i64), usize_layout) } else { - fx.bcx.ins().sdiv_imm(diff_bytes, pointee_size as i64) + let isize_layout = fx.layout_of(fx.tcx.types.isize); + CValue::by_val(fx.bcx.ins().sdiv_imm(diff_bytes, pointee_size as i64), isize_layout) }; - let val = CValue::by_val(diff, isize_layout); ret.write_cvalue(fx, val); }; @@ -742,7 +760,7 @@ fn codegen_regular_intrinsic_call<'tcx>( }; caller_location, () { - let caller_location = fx.get_caller_location(span); + let caller_location = fx.get_caller_location(source_info); ret.write_cvalue(fx, caller_location); }; @@ -761,16 +779,16 @@ fn codegen_regular_intrinsic_call<'tcx>( if fx.tcx.is_compiler_builtins(LOCAL_CRATE) { // special case for compiler-builtins to avoid having to patch it crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported"); - let ret_block = fx.get_block(destination.unwrap().1); + let ret_block = fx.get_block(destination.unwrap()); fx.bcx.ins().jump(ret_block, &[]); return; } else { - fx.tcx.sess.span_fatal(span, "128bit atomics not yet supported"); + fx.tcx.sess.span_fatal(source_info.span, "128bit atomics not yet supported"); } } ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty); return; } } @@ -789,16 +807,16 @@ fn codegen_regular_intrinsic_call<'tcx>( if fx.tcx.is_compiler_builtins(LOCAL_CRATE) { // special case for compiler-builtins to avoid having to patch it crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported"); - let ret_block = fx.get_block(destination.unwrap().1); + let ret_block = fx.get_block(destination.unwrap()); fx.bcx.ins().jump(ret_block, &[]); return; } else { - fx.tcx.sess.span_fatal(span, "128bit atomics not yet supported"); + fx.tcx.sess.span_fatal(source_info.span, "128bit atomics not yet supported"); } } ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty); return; } } @@ -812,7 +830,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -830,7 +848,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -850,7 +868,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -868,7 +886,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -886,7 +904,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -904,7 +922,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -922,7 +940,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -940,7 +958,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -958,7 +976,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -976,7 +994,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -994,7 +1012,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -1012,7 +1030,7 @@ fn codegen_regular_intrinsic_call<'tcx>( match layout.ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { - report_atomic_type_validation_error(fx, intrinsic, span, layout.ty); + report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return; } } @@ -1130,6 +1148,6 @@ fn codegen_regular_intrinsic_call<'tcx>( }; } - let ret_block = fx.get_block(destination.unwrap().1); + let ret_block = fx.get_block(destination.unwrap()); fx.bcx.ins().jump(ret_block, &[]); } diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 8f80b02ae0..a68225de58 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -828,6 +828,7 @@ pub(crate) fn assert_assignable<'tcx>( } } } + (ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b), _ => { assert_eq!( from_ty, to_ty, diff --git a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml index 337837c40b..8ebdabe826 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml +++ b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - libgccjit_version: ["libgccjit.so", "libgccjit_without_int128.so"] + libgccjit_version: ["libgccjit.so", "libgccjit_without_int128.so", "libgccjit12.so"] steps: - uses: actions/checkout@v2 @@ -78,12 +78,21 @@ jobs: key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} - name: Build + if: matrix.libgccjit_version != 'libgccjit12.so' run: | ./prepare_build.sh ./build.sh cargo test ./clean_all.sh + - name: Build + if: matrix.libgccjit_version == 'libgccjit12.so' + run: | + ./prepare_build.sh + ./build.sh --no-default-features + cargo test --no-default-features + ./clean_all.sh + - name: Prepare dependencies run: | git config --global user.email "user@example.com" @@ -98,6 +107,7 @@ jobs: args: --release - name: Test + if: matrix.libgccjit_version != 'libgccjit12.so' run: | # Enable backtraces for easier debugging export RUST_BACKTRACE=1 @@ -107,3 +117,15 @@ jobs: export RUN_RUNS=2 ./test.sh --release + + - name: Test + if: matrix.libgccjit_version == 'libgccjit12.so' + run: | + # Enable backtraces for easier debugging + export RUST_BACKTRACE=1 + + # Reduce amount of benchmark runs as they are slow + export COMPILE_RUNS=2 + export RUN_RUNS=2 + + ./test.sh --release --no-default-features diff --git a/compiler/rustc_codegen_gcc/.rustfmt.toml b/compiler/rustc_codegen_gcc/.rustfmt.toml new file mode 100644 index 0000000000..c7ad93bafe --- /dev/null +++ b/compiler/rustc_codegen_gcc/.rustfmt.toml @@ -0,0 +1 @@ +disable_all_formatting = true diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock index a1d9f2f5e3..6df2102470 100644 --- a/compiler/rustc_codegen_gcc/Cargo.lock +++ b/compiler/rustc_codegen_gcc/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "gccjit" version = "1.0.0" -source = "git+https://github.com/antoyo/gccjit.rs#bdecdecfb8a02ec861a39a350f990faa33bd31c3" +source = "git+https://github.com/antoyo/gccjit.rs#bdb86fb5092895ff5589726b33250010c64d93f6" dependencies = [ "gccjit_sys", ] @@ -49,7 +49,7 @@ dependencies = [ [[package]] name = "gccjit_sys" version = "0.0.1" -source = "git+https://github.com/antoyo/gccjit.rs#bdecdecfb8a02ec861a39a350f990faa33bd31c3" +source = "git+https://github.com/antoyo/gccjit.rs#bdb86fb5092895ff5589726b33250010c64d93f6" dependencies = [ "libc 0.1.12", ] diff --git a/compiler/rustc_codegen_gcc/Cargo.toml b/compiler/rustc_codegen_gcc/Cargo.toml index 21f0bfbf69..211d19a8dc 100644 --- a/compiler/rustc_codegen_gcc/Cargo.toml +++ b/compiler/rustc_codegen_gcc/Cargo.toml @@ -9,9 +9,17 @@ license = "MIT OR Apache-2.0" crate-type = ["dylib"] [[test]] -name = "lang_tests" -path = "tests/lib.rs" +name = "lang_tests_debug" +path = "tests/lang_tests_debug.rs" harness = false +[[test]] +name = "lang_tests_release" +path = "tests/lang_tests_release.rs" +harness = false + +[features] +default = ["master"] +master = ["gccjit/master"] [dependencies] gccjit = { git = "https://github.com/antoyo/gccjit.rs" } diff --git a/compiler/rustc_codegen_gcc/build.sh b/compiler/rustc_codegen_gcc/build.sh index 230ab7b6d4..ba0d0d0494 100755 --- a/compiler/rustc_codegen_gcc/build.sh +++ b/compiler/rustc_codegen_gcc/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #set -x set -e @@ -6,6 +6,8 @@ set -e codegen_channel=debug sysroot_channel=debug +flags= + while [[ $# -gt 0 ]]; do case $1 in --release) @@ -16,6 +18,15 @@ while [[ $# -gt 0 ]]; do sysroot_channel=release shift ;; + --no-default-features) + flags="$flags --no-default-features" + shift + ;; + --features) + shift + flags="$flags --features $1" + shift + ;; *) echo "Unknown option $1" exit 1 @@ -33,21 +44,13 @@ fi export LD_LIBRARY_PATH="$GCC_PATH" export LIBRARY_PATH="$GCC_PATH" -features= - -if [[ "$1" == "--features" ]]; then - shift - features="--features $1" - shift -fi - if [[ "$codegen_channel" == "release" ]]; then export CHANNEL='release' - CARGO_INCREMENTAL=1 cargo rustc --release $features + CARGO_INCREMENTAL=1 cargo rustc --release $flags else echo $LD_LIBRARY_PATH export CHANNEL='debug' - cargo rustc $features + cargo rustc $flags fi source config.sh diff --git a/compiler/rustc_codegen_gcc/build_sysroot/build_sysroot.sh b/compiler/rustc_codegen_gcc/build_sysroot/build_sysroot.sh index a965ca971a..f293192a09 100755 --- a/compiler/rustc_codegen_gcc/build_sysroot/build_sysroot.sh +++ b/compiler/rustc_codegen_gcc/build_sysroot/build_sysroot.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Requires the CHANNEL env var to be set to `debug` or `release.` diff --git a/compiler/rustc_codegen_gcc/build_sysroot/prepare_sysroot_src.sh b/compiler/rustc_codegen_gcc/build_sysroot/prepare_sysroot_src.sh index 071e7ed1f8..56768bbf1d 100755 --- a/compiler/rustc_codegen_gcc/build_sysroot/prepare_sysroot_src.sh +++ b/compiler/rustc_codegen_gcc/build_sysroot/prepare_sysroot_src.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e cd $(dirname "$0") diff --git a/compiler/rustc_codegen_gcc/cargo.sh b/compiler/rustc_codegen_gcc/cargo.sh index 332f365ce0..16e49b2042 100755 --- a/compiler/rustc_codegen_gcc/cargo.sh +++ b/compiler/rustc_codegen_gcc/cargo.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if [ -z $CHANNEL ]; then export CHANNEL='debug' @@ -20,4 +20,4 @@ fi cmd=$1 shift -RUSTDOCFLAGS="$RUSTFLAGS" cargo +${TOOLCHAIN} $cmd --target $TARGET_TRIPLE $@ +RUSTDOCFLAGS="$RUSTFLAGS" cargo +${TOOLCHAIN} $cmd $@ diff --git a/compiler/rustc_codegen_gcc/clean_all.sh b/compiler/rustc_codegen_gcc/clean_all.sh index a77d1486fe..782bd3e505 100755 --- a/compiler/rustc_codegen_gcc/clean_all.sh +++ b/compiler/rustc_codegen_gcc/clean_all.sh @@ -1,5 +1,6 @@ -#!/bin/bash --verbose +#!/usr/bin/env bash set -e +set -v rm -rf target/ build_sysroot/{sysroot/,sysroot_src/,target/,Cargo.lock} perf.data{,.old} rm -rf regex/ simple-raytracer/ diff --git a/compiler/rustc_codegen_gcc/config.sh b/compiler/rustc_codegen_gcc/config.sh index a932c1c837..b25e215fb9 100644 --- a/compiler/rustc_codegen_gcc/config.sh +++ b/compiler/rustc_codegen_gcc/config.sh @@ -2,7 +2,7 @@ set -e export CARGO_INCREMENTAL=0 -if [ -f ./gcc_path ]; then +if [ -f ./gcc_path ]; then export GCC_PATH=$(cat gcc_path) else echo 'Please put the path to your custom build of libgccjit in the file `gcc_path`, see Readme.md for details' @@ -38,7 +38,7 @@ if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then fi fi -export RUSTFLAGS="$linker -Cpanic=abort -Csymbol-mangling-version=v0 -Cdebuginfo=2 -Clto=off -Zpanic-abort-tests -Zcodegen-backend=$(pwd)/target/${CHANNEL:-debug}/librustc_codegen_gcc.$dylib_ext --sysroot $(pwd)/build_sysroot/sysroot" +export RUSTFLAGS="$CG_RUSTFLAGS $linker -Cpanic=abort -Csymbol-mangling-version=v0 -Cdebuginfo=2 -Clto=off -Zpanic-abort-tests -Zcodegen-backend=$(pwd)/target/${CHANNEL:-debug}/librustc_codegen_gcc.$dylib_ext --sysroot $(pwd)/build_sysroot/sysroot" # FIXME(antoyo): remove once the atomic shim is gone if [[ `uname` == 'Darwin' ]]; then diff --git a/compiler/rustc_codegen_gcc/crate_patches/0002-rand-Disable-failing-test.patch b/compiler/rustc_codegen_gcc/crate_patches/0002-rand-Disable-failing-test.patch new file mode 100644 index 0000000000..449ca5f6e2 --- /dev/null +++ b/compiler/rustc_codegen_gcc/crate_patches/0002-rand-Disable-failing-test.patch @@ -0,0 +1,32 @@ +From a8fb97120d71252538b6b026695df40d02696bdb Mon Sep 17 00:00:00 2001 +From: bjorn3 +Date: Sat, 15 Aug 2020 20:04:38 +0200 +Subject: [PATCH] [rand] Disable failing test + +--- + src/distributions/uniform.rs | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/distributions/uniform.rs b/src/distributions/uniform.rs +index 480b859..c80bb6f 100644 +--- a/src/distributions/uniform.rs ++++ b/src/distributions/uniform.rs +@@ -1085,7 +1085,7 @@ mod tests { + _ => panic!("`UniformDurationMode` was not serialized/deserialized correctly") + } + } +- ++ + #[test] + #[cfg(feature = "serde1")] + fn test_uniform_serialization() { +@@ -1314,6 +1314,7 @@ mod tests { + not(target_arch = "wasm32"), + not(target_arch = "asmjs") + ))] ++ #[ignore] // FIXME + fn test_float_assertions() { + use super::SampleUniform; + use std::panic::catch_unwind; +-- +2.20.1 diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index a8435287d9..ddcbb0d9fc 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -514,7 +514,7 @@ pub mod intrinsics { pub fn copy(src: *const T, dst: *mut T, count: usize); pub fn transmute(e: T) -> U; pub fn ctlz_nonzero(x: T) -> T; - pub fn needs_drop() -> bool; + pub fn needs_drop() -> bool; pub fn bitreverse(x: T) -> T; pub fn bswap(x: T) -> T; pub fn write_bytes(dst: *mut T, val: u8, count: usize); diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs index 69d591565a..14fd9eeffa 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs @@ -47,6 +47,11 @@ struct NoisyDrop { inner: NoisyDropInner, } +struct NoisyDropUnsized { + inner: NoisyDropInner, + text: str, +} + struct NoisyDropInner; impl Drop for NoisyDrop { @@ -184,7 +189,9 @@ fn main() { assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8); assert!(!intrinsics::needs_drop::()); + assert!(!intrinsics::needs_drop::<[u8]>()); assert!(intrinsics::needs_drop::()); + assert!(intrinsics::needs_drop::()); Unique { pointer: 0 as *const &str, diff --git a/compiler/rustc_codegen_gcc/example/std_example.rs b/compiler/rustc_codegen_gcc/example/std_example.rs index eba0eb8289..31069058ae 100644 --- a/compiler/rustc_codegen_gcc/example/std_example.rs +++ b/compiler/rustc_codegen_gcc/example/std_example.rs @@ -93,9 +93,10 @@ fn main() { println!("{:?}", std::intrinsics::caller_location()); - /*unsafe { + #[cfg(feature="master")] + unsafe { test_simd(); - }*/ + } Box::pin(move |mut _task_context| { yield (); @@ -104,7 +105,8 @@ fn main() { println!("End"); } -/*#[target_feature(enable = "sse2")] +#[cfg(feature="master")] +#[target_feature(enable = "sse2")] unsafe fn test_simd() { let x = _mm_setzero_si128(); let y = _mm_set1_epi16(7); @@ -112,7 +114,7 @@ unsafe fn test_simd() { let cmp_eq = _mm_cmpeq_epi8(y, y); let cmp_lt = _mm_cmplt_epi8(y, y); - /*assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]); + assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]); assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_eq), [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff]); assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]); @@ -124,14 +126,15 @@ unsafe fn test_simd() { test_mm_cvtepi8_epi16(); test_mm_cvtsi128_si64(); - // FIXME(#666) implement `#[rustc_arg_required_const(..)]` support - //test_mm_extract_epi8(); + test_mm_extract_epi8(); + test_mm_insert_epi16(); let mask1 = _mm_movemask_epi8(dbg!(_mm_setr_epi8(255u8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); - assert_eq!(mask1, 1);*/ -}*/ + assert_eq!(mask1, 1); +} -/*#[target_feature(enable = "sse2")] +#[cfg(feature="master")] +#[target_feature(enable = "sse2")] unsafe fn test_mm_slli_si128() { #[rustfmt::skip] let a = _mm_setr_epi8( @@ -155,22 +158,10 @@ unsafe fn test_mm_slli_si128() { ); let r = _mm_slli_si128(a, 16); assert_eq_m128i(r, _mm_set1_epi8(0)); - - #[rustfmt::skip] - let a = _mm_setr_epi8( - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - ); - let r = _mm_slli_si128(a, -1); - assert_eq_m128i(_mm_set1_epi8(0), r); - - #[rustfmt::skip] - let a = _mm_setr_epi8( - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - ); - let r = _mm_slli_si128(a, -0x80000000); - assert_eq_m128i(r, _mm_set1_epi8(0)); } + +#[cfg(feature="master")] #[target_feature(enable = "sse2")] unsafe fn test_mm_movemask_epi8() { #[rustfmt::skip] @@ -184,6 +175,7 @@ unsafe fn test_mm_movemask_epi8() { assert_eq!(r, 0b10100100_00100101); } +#[cfg(feature="master")] #[target_feature(enable = "avx2")] unsafe fn test_mm256_movemask_epi8() { let a = _mm256_set1_epi8(-1); @@ -192,6 +184,7 @@ unsafe fn test_mm256_movemask_epi8() { assert_eq!(r, e); } +#[cfg(feature="master")] #[target_feature(enable = "sse2")] unsafe fn test_mm_add_epi8() { let a = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -207,6 +200,7 @@ unsafe fn test_mm_add_epi8() { assert_eq_m128i(r, e); } +#[cfg(feature="master")] #[target_feature(enable = "sse2")] unsafe fn test_mm_add_pd() { let a = _mm_setr_pd(1.0, 2.0); @@ -215,12 +209,14 @@ unsafe fn test_mm_add_pd() { assert_eq_m128d(r, _mm_setr_pd(6.0, 12.0)); } +#[cfg(feature="master")] fn assert_eq_m128i(x: std::arch::x86_64::__m128i, y: std::arch::x86_64::__m128i) { unsafe { assert_eq!(std::mem::transmute::<_, [u8; 16]>(x), std::mem::transmute::<_, [u8; 16]>(y)); } } +#[cfg(feature="master")] #[target_feature(enable = "sse2")] pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) { if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 { @@ -228,12 +224,14 @@ pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) { } } +#[cfg(feature="master")] #[target_feature(enable = "sse2")] unsafe fn test_mm_cvtsi128_si64() { let r = _mm_cvtsi128_si64(std::mem::transmute::<[i64; 2], _>([5, 0])); assert_eq!(r, 5); } +#[cfg(feature="master")] #[target_feature(enable = "sse4.1")] unsafe fn test_mm_cvtepi8_epi16() { let a = _mm_set1_epi8(10); @@ -246,6 +244,7 @@ unsafe fn test_mm_cvtepi8_epi16() { assert_eq_m128i(r, e); } +#[cfg(feature="master")] #[target_feature(enable = "sse4.1")] unsafe fn test_mm_extract_epi8() { #[rustfmt::skip] @@ -254,10 +253,19 @@ unsafe fn test_mm_extract_epi8() { 8, 9, 10, 11, 12, 13, 14, 15 ); let r1 = _mm_extract_epi8(a, 0); - let r2 = _mm_extract_epi8(a, 19); + let r2 = _mm_extract_epi8(a, 3); assert_eq!(r1, 0xFF); assert_eq!(r2, 3); -}*/ +} + +#[cfg(all(feature="master", target_arch = "x86_64"))] +#[target_feature(enable = "sse2")] +unsafe fn test_mm_insert_epi16() { + let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); + let r = _mm_insert_epi16(a, 9, 0); + let e = _mm_setr_epi16(9, 1, 2, 3, 4, 5, 6, 7); + assert_eq_m128i(r, e); +} #[derive(PartialEq)] enum LoopState { diff --git a/compiler/rustc_codegen_gcc/patches/0024-core-Disable-portable-simd-test.patch b/compiler/rustc_codegen_gcc/patches/0024-core-Disable-portable-simd-test.patch index 03900ba101..d5fa1cec06 100644 --- a/compiler/rustc_codegen_gcc/patches/0024-core-Disable-portable-simd-test.patch +++ b/compiler/rustc_codegen_gcc/patches/0024-core-Disable-portable-simd-test.patch @@ -7,167 +7,6 @@ Subject: [PATCH] [core] Disable portable-simd test library/core/tests/lib.rs | 1 - 1 file changed, 1 deletion(-) -diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs -index aa1ad93..95fbf55 100644 ---- a/library/core/src/lib.rs -+++ b/library/core/src/lib.rs -@@ -398,23 +398,4 @@ pub mod arch { - } - } - --// Pull in the `core_simd` crate directly into libcore. The contents of --// `core_simd` are in a different repository: rust-lang/portable-simd. --// --// `core_simd` depends on libcore, but the contents of this module are --// set up in such a way that directly pulling it here works such that the --// crate uses this crate as its libcore. --#[path = "../../portable-simd/crates/core_simd/src/mod.rs"] --#[allow(missing_debug_implementations, dead_code, unsafe_op_in_unsafe_fn, unused_unsafe)] --#[allow(rustdoc::bare_urls)] --#[unstable(feature = "portable_simd", issue = "86656")] --mod core_simd; -- --#[doc = include_str!("../../portable-simd/crates/core_simd/src/core_simd_docs.md")] --#[unstable(feature = "portable_simd", issue = "86656")] --pub mod simd { -- #[unstable(feature = "portable_simd", issue = "86656")] -- pub use crate::core_simd::simd::*; --} -- - include!("primitive_docs.rs"); -diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs -index cd38c3a..ad632dc 100644 ---- a/library/core/src/slice/mod.rs -+++ b/library/core/src/slice/mod.rs -@@ -17,6 +17,5 @@ use crate::ptr; - use crate::result::Result; - use crate::result::Result::{Err, Ok}; --use crate::simd::{self, Simd}; - use crate::slice; - - #[unstable( -@@ -3475,121 +3474,6 @@ impl [T] { - } - } - -- /// Split a slice into a prefix, a middle of aligned SIMD types, and a suffix. -- /// -- /// This is a safe wrapper around [`slice::align_to`], so has the same weak -- /// postconditions as that method. You're only assured that -- /// `self.len() == prefix.len() + middle.len() * LANES + suffix.len()`. -- /// -- /// Notably, all of the following are possible: -- /// - `prefix.len() >= LANES`. -- /// - `middle.is_empty()` despite `self.len() >= 3 * LANES`. -- /// - `suffix.len() >= LANES`. -- /// -- /// That said, this is a safe method, so if you're only writing safe code, -- /// then this can at most cause incorrect logic, not unsoundness. -- /// -- /// # Panics -- /// -- /// This will panic if the size of the SIMD type is different from -- /// `LANES` times that of the scalar. -- /// -- /// At the time of writing, the trait restrictions on `Simd` keeps -- /// that from ever happening, as only power-of-two numbers of lanes are -- /// supported. It's possible that, in the future, those restrictions might -- /// be lifted in a way that would make it possible to see panics from this -- /// method for something like `LANES == 3`. -- /// -- /// # Examples -- /// -- /// ``` -- /// #![feature(portable_simd)] -- /// -- /// let short = &[1, 2, 3]; -- /// let (prefix, middle, suffix) = short.as_simd::<4>(); -- /// assert_eq!(middle, []); // Not enough elements for anything in the middle -- /// -- /// // They might be split in any possible way between prefix and suffix -- /// let it = prefix.iter().chain(suffix).copied(); -- /// assert_eq!(it.collect::>(), vec![1, 2, 3]); -- /// -- /// fn basic_simd_sum(x: &[f32]) -> f32 { -- /// use std::ops::Add; -- /// use std::simd::f32x4; -- /// let (prefix, middle, suffix) = x.as_simd(); -- /// let sums = f32x4::from_array([ -- /// prefix.iter().copied().sum(), -- /// 0.0, -- /// 0.0, -- /// suffix.iter().copied().sum(), -- /// ]); -- /// let sums = middle.iter().copied().fold(sums, f32x4::add); -- /// sums.reduce_sum() -- /// } -- /// -- /// let numbers: Vec = (1..101).map(|x| x as _).collect(); -- /// assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0); -- /// ``` -- #[unstable(feature = "portable_simd", issue = "86656")] -- pub fn as_simd(&self) -> (&[T], &[Simd], &[T]) -- where -- Simd: AsRef<[T; LANES]>, -- T: simd::SimdElement, -- simd::LaneCount: simd::SupportedLaneCount, -- { -- // These are expected to always match, as vector types are laid out like -- // arrays per , but we -- // might as well double-check since it'll optimize away anyhow. -- assert_eq!(mem::size_of::>(), mem::size_of::<[T; LANES]>()); -- -- // SAFETY: The simd types have the same layout as arrays, just with -- // potentially-higher alignment, so the de-facto transmutes are sound. -- unsafe { self.align_to() } -- } -- -- /// Split a slice into a prefix, a middle of aligned SIMD types, and a suffix. -- /// -- /// This is a safe wrapper around [`slice::align_to_mut`], so has the same weak -- /// postconditions as that method. You're only assured that -- /// `self.len() == prefix.len() + middle.len() * LANES + suffix.len()`. -- /// -- /// Notably, all of the following are possible: -- /// - `prefix.len() >= LANES`. -- /// - `middle.is_empty()` despite `self.len() >= 3 * LANES`. -- /// - `suffix.len() >= LANES`. -- /// -- /// That said, this is a safe method, so if you're only writing safe code, -- /// then this can at most cause incorrect logic, not unsoundness. -- /// -- /// This is the mutable version of [`slice::as_simd`]; see that for examples. -- /// -- /// # Panics -- /// -- /// This will panic if the size of the SIMD type is different from -- /// `LANES` times that of the scalar. -- /// -- /// At the time of writing, the trait restrictions on `Simd` keeps -- /// that from ever happening, as only power-of-two numbers of lanes are -- /// supported. It's possible that, in the future, those restrictions might -- /// be lifted in a way that would make it possible to see panics from this -- /// method for something like `LANES == 3`. -- #[unstable(feature = "portable_simd", issue = "86656")] -- pub fn as_simd_mut(&mut self) -> (&mut [T], &mut [Simd], &mut [T]) -- where -- Simd: AsMut<[T; LANES]>, -- T: simd::SimdElement, -- simd::LaneCount: simd::SupportedLaneCount, -- { -- // These are expected to always match, as vector types are laid out like -- // arrays per , but we -- // might as well double-check since it'll optimize away anyhow. -- assert_eq!(mem::size_of::>(), mem::size_of::<[T; LANES]>()); -- -- // SAFETY: The simd types have the same layout as arrays, just with -- // potentially-higher alignment, so the de-facto transmutes are sound. -- unsafe { self.align_to_mut() } -- } -- - /// Checks if the elements of this slice are sorted. - /// - /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 06c7be0..359e2e7 100644 --- a/library/core/tests/lib.rs @@ -188,41 +27,3 @@ index 06c7be0..359e2e7 100644 mod slice; mod str; mod str_lossy; -diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs -index 5dc586d..b6fc48f 100644 ---- a/library/std/src/lib.rs -+++ b/library/std/src/lib.rs -@@ -312,6 +312,5 @@ - #![feature(panic_can_unwind)] - #![feature(panic_unwind)] - #![feature(platform_intrinsics)] --#![feature(portable_simd)] - #![feature(prelude_import)] - #![feature(ptr_as_uninit)] -@@ -508,23 +508,6 @@ pub mod time; - #[unstable(feature = "once_cell", issue = "74465")] - pub mod lazy; - --// Pull in `std_float` crate into libstd. The contents of --// `std_float` are in a different repository: rust-lang/portable-simd. --#[path = "../../portable-simd/crates/std_float/src/lib.rs"] --#[allow(missing_debug_implementations, dead_code, unsafe_op_in_unsafe_fn, unused_unsafe)] --#[allow(rustdoc::bare_urls)] --#[unstable(feature = "portable_simd", issue = "86656")] --mod std_float; -- --#[doc = include_str!("../../portable-simd/crates/core_simd/src/core_simd_docs.md")] --#[unstable(feature = "portable_simd", issue = "86656")] --pub mod simd { -- #[doc(inline)] -- pub use crate::std_float::StdFloat; -- #[doc(inline)] -- pub use core::simd::*; --} -- - #[stable(feature = "futures_api", since = "1.36.0")] - pub mod task { - //! Types and Traits for working with asynchronous tasks. --- -2.26.2.7.g19db9cfb68 - diff --git a/compiler/rustc_codegen_gcc/prepare.sh b/compiler/rustc_codegen_gcc/prepare.sh index 503fa29b36..e98f24c6e1 100755 --- a/compiler/rustc_codegen_gcc/prepare.sh +++ b/compiler/rustc_codegen_gcc/prepare.sh @@ -1,10 +1,18 @@ -#!/bin/bash --verbose +#!/usr/bin/env bash set -e +set -v source prepare_build.sh cargo install hyperfine || echo "Skipping hyperfine install" +git clone https://github.com/rust-random/rand.git || echo "rust-random/rand has already been cloned" +pushd rand +git checkout -- . +git checkout 0f933f9c7176e53b2a3c7952ded484e1783f0bf1 +git am ../crate_patches/*-rand-*.patch +popd + git clone https://github.com/rust-lang/regex.git || echo "rust-lang/regex has already been cloned" pushd regex git checkout -- . diff --git a/compiler/rustc_codegen_gcc/prepare_build.sh b/compiler/rustc_codegen_gcc/prepare_build.sh index 3896775a0b..8194360da4 100755 --- a/compiler/rustc_codegen_gcc/prepare_build.sh +++ b/compiler/rustc_codegen_gcc/prepare_build.sh @@ -1,4 +1,5 @@ -#!/bin/bash --verbose +#!/usr/bin/env bash set -e +set -v ./build_sysroot/prepare_sysroot_src.sh diff --git a/compiler/rustc_codegen_gcc/rust-toolchain b/compiler/rustc_codegen_gcc/rust-toolchain index db14ea2beb..b20aeb979a 100644 --- a/compiler/rustc_codegen_gcc/rust-toolchain +++ b/compiler/rustc_codegen_gcc/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2022-03-26" +channel = "nightly-2022-06-06" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/compiler/rustc_codegen_gcc/rustc_patches/compile_test.patch b/compiler/rustc_codegen_gcc/rustc_patches/compile_test.patch new file mode 100644 index 0000000000..59143eac37 --- /dev/null +++ b/compiler/rustc_codegen_gcc/rustc_patches/compile_test.patch @@ -0,0 +1,14 @@ +diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs +index 887d27fd6dca4..2c2239f2b83d1 100644 +--- a/src/tools/compiletest/src/header.rs ++++ b/src/tools/compiletest/src/header.rs +@@ -806,8 +806,8 @@ pub fn make_test_description( + cfg: Option<&str>, + ) -> test::TestDesc { + let mut ignore = false; + #[cfg(not(bootstrap))] +- let ignore_message: Option = None; ++ let ignore_message: Option<&str> = None; + let mut should_fail = false; + + let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some(); diff --git a/compiler/rustc_codegen_gcc/rustup.sh b/compiler/rustc_codegen_gcc/rustup.sh index 11d39a122f..041079bc9c 100755 --- a/compiler/rustc_codegen_gcc/rustup.sh +++ b/compiler/rustc_codegen_gcc/rustup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs index fac532f3e9..411ec27139 100644 --- a/compiler/rustc_codegen_gcc/src/archive.rs +++ b/compiler/rustc_codegen_gcc/src/archive.rs @@ -32,7 +32,7 @@ pub struct ArArchiveBuilder<'a> { } impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { - fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self { + fn new(sess: &'a Session, output: &Path) -> Self { let config = ArchiveConfig { sess, dst: output.to_path_buf(), @@ -41,48 +41,13 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { use_gnu_style_archive: sess.target.options.archive_format == "gnu", }; - let (src_archives, entries) = if let Some(input) = input { - let mut archive = ar::Archive::new(File::open(input).unwrap()); - let mut entries = Vec::new(); - - let mut i = 0; - while let Some(entry) = archive.next_entry() { - let entry = entry.unwrap(); - entries.push(( - String::from_utf8(entry.header().identifier().to_vec()).unwrap(), - ArchiveEntry::FromArchive { - archive_index: 0, - entry_index: i, - }, - )); - i += 1; - } - - (vec![(input.to_owned(), archive)], entries) - } else { - (vec![], Vec::new()) - }; - ArArchiveBuilder { config, - src_archives, - entries, + src_archives: vec![], + entries: vec![], } } - fn src_files(&mut self) -> Vec { - self.entries.iter().map(|(name, _)| name.clone()).collect() - } - - fn remove_file(&mut self, name: &str) { - let index = self - .entries - .iter() - .position(|(entry_name, _)| entry_name == name) - .expect("Tried to remove file not existing in src archive"); - self.entries.remove(index); - } - fn add_file(&mut self, file: &Path) { self.entries.push(( file.file_name().unwrap().to_str().unwrap().to_string(), @@ -113,7 +78,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { Ok(()) } - fn build(mut self) { + fn build(mut self) -> bool { use std::process::Command; fn add_file_using_ar(archive: &Path, file: &Path) { @@ -146,6 +111,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { BuilderKind::Bsd(ar::Builder::new(File::create(&self.config.dst).unwrap())) }; + let any_members = !self.entries.is_empty(); + // Add all files for (entry_name, entry) in self.entries.into_iter() { match entry { @@ -206,6 +173,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { if !status.success() { self.config.sess.fatal(&format!("Ranlib exited with code {:?}", status.code())); } + + any_members } fn inject_dll_import_lib(&mut self, _lib_name: &str, _dll_imports: &[DllImport], _tmpdir: &MaybeTempDir) { diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 2e8cd934eb..52fd66af06 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -13,6 +13,7 @@ use std::borrow::Cow; use crate::builder::Builder; use crate::context::CodegenCx; use crate::type_of::LayoutGccExt; +use crate::callee::get_fn; // Rust asm! and GCC Extended Asm semantics differ substantially. @@ -116,7 +117,6 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let asm_arch = self.tcx.sess.asm_arch.unwrap(); let is_x86 = matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64); let att_dialect = is_x86 && options.contains(InlineAsmOptions::ATT_SYNTAX); - let intel_dialect = is_x86 && !options.contains(InlineAsmOptions::ATT_SYNTAX); // GCC index of an output operand equals its position in the array let mut outputs = vec![]; @@ -348,9 +348,24 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // processed in the previous pass } - InlineAsmOperandRef::Const { .. } - | InlineAsmOperandRef::SymFn { .. } - | InlineAsmOperandRef::SymStatic { .. } => { + InlineAsmOperandRef::SymFn { instance } => { + inputs.push(AsmInOperand { + constraint: "X".into(), + rust_idx, + val: self.cx.rvalue_as_function(get_fn(self.cx, instance)) + .get_address(None), + }); + } + + InlineAsmOperandRef::SymStatic { def_id } => { + inputs.push(AsmInOperand { + constraint: "X".into(), + rust_idx, + val: self.cx.get_static(def_id).get_address(None), + }); + } + + InlineAsmOperandRef::Const { .. } => { // processed in the previous pass } } @@ -359,7 +374,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // 3. Build the template string let mut template_str = String::with_capacity(estimate_template_length(template, constants_len, att_dialect)); - if !intel_dialect { + if att_dialect { template_str.push_str(ATT_SYNTAX_INS); } @@ -444,7 +459,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } } - if !intel_dialect { + if att_dialect { template_str.push_str(INTEL_SYNTAX_INS); } @@ -588,11 +603,11 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg) | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x", InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v", - InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => unimplemented!(), + InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "Yk", InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => unimplemented!(), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => unimplemented!(), InlineAsmRegClass::X86( - X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg, + X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg | X86InlineAsmRegClass::tmm_reg, ) => unreachable!("clobber-only"), InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("GCC backend does not support SPIR-V") @@ -656,6 +671,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg) => unimplemented!(), InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(), InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => cx.type_i16(), + InlineAsmRegClass::X86(X86InlineAsmRegClass::tmm_reg) => unimplemented!(), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(), InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") @@ -671,8 +687,8 @@ impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let asm_arch = self.tcx.sess.asm_arch.unwrap(); // Default to Intel syntax on x86 - let intel_syntax = matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64) - && !options.contains(InlineAsmOptions::ATT_SYNTAX); + let att_dialect = matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64) + && options.contains(InlineAsmOptions::ATT_SYNTAX); // Build the template string let mut template_str = String::new(); @@ -722,11 +738,11 @@ impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } let template_str = - if intel_syntax { - format!("{}\n\t.intel_syntax noprefix", template_str) + if att_dialect { + format!(".att_syntax\n\t{}\n\t.intel_syntax noprefix", template_str) } else { - format!(".att_syntax\n\t{}\n\t.intel_syntax noprefix", template_str) + template_str }; // NOTE: seems like gcc will put the asm in the wrong section, so set it to .text manually. let template_str = format!(".pushsection .text\n{}\n.popsection", template_str); @@ -787,7 +803,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option }, InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None, InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => None, - InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => { + InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg | X86InlineAsmRegClass::tmm_reg) => { unreachable!("clobber-only") } InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => unimplemented!(), diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index f5aca35cdc..e4ecbd46f0 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -78,9 +78,19 @@ pub fn compile_codegen_unit<'tcx>(tcx: TyCtxt<'tcx>, cgu_name: Symbol, supports_ let context = Context::default(); // TODO(antoyo): only set on x86 platforms. context.add_command_line_option("-masm=intel"); + // TODO(antoyo): only add the following cli argument if the feature is supported. + context.add_command_line_option("-msse2"); + context.add_command_line_option("-mavx2"); + context.add_command_line_option("-msha"); + context.add_command_line_option("-mpclmul"); + // FIXME(antoyo): the following causes an illegal instruction on vmovdqu64 in std_example on my CPU. + // Only add if the CPU supports it. + //context.add_command_line_option("-mavx512f"); for arg in &tcx.sess.opts.cg.llvm_args { context.add_command_line_option(arg); } + // NOTE: This is needed to compile the file src/intrinsic/archs.rs during a bootstrap of rustc. + context.add_command_line_option("-fno-var-tracking-assignments"); // NOTE: an optimization (https://github.com/rust-lang/rustc_codegen_gcc/issues/53). context.add_command_line_option("-fno-semantic-interposition"); // NOTE: Rust relies on LLVM not doing TBAA (https://github.com/rust-lang/unsafe-code-guidelines/issues/292). diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 41f88f119e..fa490fe3f2 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -3,11 +3,11 @@ use std::cell::Cell; use std::convert::TryFrom; use std::ops::Deref; -use gccjit::FunctionType; use gccjit::{ BinaryOp, Block, ComparisonOp, + Context, Function, LValue, RValue, @@ -48,6 +48,7 @@ use rustc_target::spec::{HasTargetSpec, Target}; use crate::common::{SignType, TypeReflection, type_is_pointer}; use crate::context::CodegenCx; +use crate::intrinsic::llvm; use crate::type_of::LayoutGccExt; // TODO(antoyo) @@ -61,24 +62,6 @@ enum ExtremumOperation { Min, } -trait EnumClone { - fn clone(&self) -> Self; -} - -impl EnumClone for AtomicOrdering { - fn clone(&self) -> Self { - match *self { - AtomicOrdering::NotAtomic => AtomicOrdering::NotAtomic, - AtomicOrdering::Unordered => AtomicOrdering::Unordered, - AtomicOrdering::Monotonic => AtomicOrdering::Monotonic, - AtomicOrdering::Acquire => AtomicOrdering::Acquire, - AtomicOrdering::Release => AtomicOrdering::Release, - AtomicOrdering::AcquireRelease => AtomicOrdering::AcquireRelease, - AtomicOrdering::SequentiallyConsistent => AtomicOrdering::SequentiallyConsistent, - } - } -} - pub struct Builder<'a: 'gcc, 'gcc, 'tcx> { pub cx: &'a CodegenCx<'gcc, 'tcx>, pub block: Block<'gcc>, @@ -103,9 +86,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { match order { // TODO(antoyo): does this make sense? AtomicOrdering::AcquireRelease | AtomicOrdering::Release => AtomicOrdering::Acquire, - _ => order.clone(), + _ => order, }; - let previous_value = self.atomic_load(dst.get_type(), dst, load_ordering.clone(), Size::from_bytes(size)); + let previous_value = self.atomic_load(dst.get_type(), dst, load_ordering, Size::from_bytes(size)); let previous_var = func.new_local(None, previous_value.get_type(), "previous_value"); let return_value = func.new_local(None, previous_value.get_type(), "return_value"); self.llbb().add_assignment(None, previous_var, previous_value); @@ -217,17 +200,28 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { return Cow::Borrowed(args); } + let func_name = format!("{:?}", func_ptr); + let casted_args: Vec<_> = param_types .into_iter() .zip(args.iter()) .enumerate() .map(|(index, (expected_ty, &actual_val))| { + if llvm::ignore_arg_cast(&func_name, index, args.len()) { + return actual_val; + } + let actual_ty = actual_val.get_type(); if expected_ty != actual_ty { - if on_stack_param_indices.contains(&index) { + if !actual_ty.is_vector() && !expected_ty.is_vector() && actual_ty.is_integral() && expected_ty.is_integral() && actual_ty.get_size() != expected_ty.get_size() { + self.context.new_cast(None, actual_val, expected_ty) + } + else if on_stack_param_indices.contains(&index) { actual_val.dereference(None).to_rvalue() } else { + assert!(!((actual_ty.is_vector() && !expected_ty.is_vector()) || (!actual_ty.is_vector() && expected_ty.is_vector())), "{:?} ({}) -> {:?} ({}), index: {:?}[{}]", actual_ty, actual_ty.is_vector(), expected_ty, expected_ty.is_vector(), func_ptr, index); + // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. self.bitcast(actual_val, expected_ty) } } @@ -286,22 +280,20 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // gccjit requires to use the result of functions, even when it's not used. // That's why we assign the result to a local or call add_eval(). let gcc_func = func_ptr.get_type().dyncast_function_ptr_type().expect("function ptr"); - let mut return_type = gcc_func.get_return_type(); + let return_type = gcc_func.get_return_type(); let void_type = self.context.new_type::<()>(); let current_func = self.block.get_function(); - // FIXME(antoyo): As a temporary workaround for unsupported LLVM intrinsics. - if gcc_func.get_param_count() == 0 && format!("{:?}", func_ptr) == "__builtin_ia32_pmovmskb128" { - return_type = self.int_type; - } - if return_type != void_type { unsafe { RETURN_VALUE_COUNT += 1 }; let result = current_func.new_local(None, return_type, &format!("ptrReturnValue{}", unsafe { RETURN_VALUE_COUNT })); + let func_name = format!("{:?}", func_ptr); + let args = llvm::adjust_intrinsic_arguments(&self, gcc_func, args, &func_name); self.block.add_assignment(None, result, self.cx.context.new_call_through_ptr(None, func_ptr, &args)); result.to_rvalue() } else { + #[cfg(not(feature="master"))] if gcc_func.get_param_count() == 0 { // FIXME(antoyo): As a temporary workaround for unsupported LLVM intrinsics. self.block.add_eval(None, self.cx.context.new_call_through_ptr(None, func_ptr, &[])); @@ -309,6 +301,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { else { self.block.add_eval(None, self.cx.context.new_call_through_ptr(None, func_ptr, &args)); } + #[cfg(feature="master")] + self.block.add_eval(None, self.cx.context.new_call_through_ptr(None, func_ptr, &args)); // Return dummy value when not having return value. let result = current_func.new_local(None, self.isize_type, "dummyValueThatShouldNeverBeUsed"); self.block.add_assignment(None, result, self.context.new_rvalue_from_long(self.isize_type, 0)); @@ -498,8 +492,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn exactudiv(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - // TODO(antoyo): convert the arguments to unsigned? // TODO(antoyo): poison if not exact. + let a_type = a.get_type().to_unsigned(self); + let a = self.gcc_int_cast(a, a_type); + let b_type = b.get_type().to_unsigned(self); + let b = self.gcc_int_cast(b, b_type); a / b } @@ -529,12 +526,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn frem(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - if a.get_type() == self.cx.float_type { + if a.get_type().is_compatible_with(self.cx.float_type) { let fmodf = self.context.get_builtin_function("fmodf"); // FIXME(antoyo): this seems to produce the wrong result. return self.context.new_call(None, fmodf, &[a, b]); } - assert_eq!(a.get_type(), self.cx.double_type); + assert_eq!(a.get_type().unqualified(), self.cx.double_type); let fmod = self.context.get_builtin_function("fmod"); return self.context.new_call(None, fmod, &[a, b]); @@ -650,18 +647,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { unimplemented!(); } - fn load(&mut self, _ty: Type<'gcc>, ptr: RValue<'gcc>, _align: Align) -> RValue<'gcc> { - // TODO(antoyo): use ty. + fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, _align: Align) -> RValue<'gcc> { let block = self.llbb(); let function = block.get_function(); // NOTE: instead of returning the dereference here, we have to assign it to a variable in // the current basic block. Otherwise, it could be used in another basic block, causing a // dereference after a drop, for instance. - // TODO(antoyo): handle align. + // TODO(antoyo): handle align of the load instruction. + let ptr = self.context.new_cast(None, ptr, pointee_ty.make_pointer()); let deref = ptr.dereference(None).to_rvalue(); - let value_type = deref.get_type(); unsafe { RETURN_VALUE_COUNT += 1 }; - let loaded_value = function.new_local(None, value_type, &format!("loadedValue{}", unsafe { RETURN_VALUE_COUNT })); + let loaded_value = function.new_local(None, pointee_ty, &format!("loadedValue{}", unsafe { RETURN_VALUE_COUNT })); block.add_assignment(None, loaded_value, deref); loaded_value.to_rvalue() } @@ -713,7 +709,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { OperandValue::Ref(place.llval, Some(llextra), place.align) } else if place.layout.is_gcc_immediate() { - let load = self.load(place.llval.get_type(), place.llval, place.align); + let load = self.load( + place.layout.gcc_type(self, false), + place.llval, + place.align, + ); if let abi::Abi::Scalar(ref scalar) = place.layout.abi { scalar_load_metadata(self, load, scalar); } @@ -725,7 +725,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let mut load = |i, scalar: &abi::Scalar, align| { let llptr = self.struct_gep(pair_type, place.llval, i as u64); - let load = self.load(llptr.get_type(), llptr, align); + let llty = place.layout.scalar_pair_element_gcc_type(self, i, false); + let load = self.load(llty, llptr, align); scalar_load_metadata(self, load, scalar); if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load } }; @@ -797,9 +798,16 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.store_with_flags(val, ptr, align, MemFlags::empty()) } - fn store_with_flags(&mut self, val: RValue<'gcc>, ptr: RValue<'gcc>, _align: Align, _flags: MemFlags) -> RValue<'gcc> { + fn store_with_flags(&mut self, val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align, _flags: MemFlags) -> RValue<'gcc> { let ptr = self.check_store(val, ptr); - self.llbb().add_assignment(None, ptr.dereference(None), val); + let destination = ptr.dereference(None); + // NOTE: libgccjit does not support specifying the alignment on the assignment, so we cast + // to type so it gets the proper alignment. + let destination_type = destination.to_rvalue().get_type().unqualified(); + let aligned_type = destination_type.get_aligned(align.bytes()).make_pointer(); + let aligned_destination = self.cx.context.new_bitcast(None, ptr, aligned_type); + let aligned_destination = aligned_destination.dereference(None); + self.llbb().add_assignment(None, aligned_destination, val); // TODO(antoyo): handle align and flags. // NOTE: dummy value here since it's never used. FIXME(antoyo): API should not return a value here? self.cx.context.new_rvalue_zero(self.type_i32()) @@ -971,7 +979,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn memmove(&mut self, dst: RValue<'gcc>, dst_align: Align, src: RValue<'gcc>, src_align: Align, size: RValue<'gcc>, flags: MemFlags) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memmove. - let val = self.load(src.get_type(), src, src_align); + let val = self.load(src.get_type().get_pointee().expect("get_pointee"), src, src_align); let ptr = self.pointercast(dst, self.type_ptr_to(self.val_ty(val))); self.store_with_flags(val, ptr, dst_align, flags); return; @@ -1287,16 +1295,183 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { + #[cfg(feature="master")] pub fn shuffle_vector(&mut self, v1: RValue<'gcc>, v2: RValue<'gcc>, mask: RValue<'gcc>) -> RValue<'gcc> { - let return_type = v1.get_type(); - let params = [ - self.context.new_parameter(None, return_type, "v1"), - self.context.new_parameter(None, return_type, "v2"), - self.context.new_parameter(None, mask.get_type(), "mask"), - ]; - let shuffle = self.context.new_function(None, FunctionType::Extern, return_type, ¶ms, "_mm_shuffle_epi8", false); - self.context.new_call(None, shuffle, &[v1, v2, mask]) + let struct_type = mask.get_type().is_struct().expect("mask of struct type"); + + // TODO(antoyo): use a recursive unqualified() here. + let vector_type = v1.get_type().unqualified().dyncast_vector().expect("vector type"); + let element_type = vector_type.get_element_type(); + let vec_num_units = vector_type.get_num_units(); + + let mask_num_units = struct_type.get_field_count(); + let mut vector_elements = vec![]; + let mask_element_type = + if element_type.is_integral() { + element_type + } + else { + #[cfg(feature="master")] + { + self.cx.type_ix(element_type.get_size() as u64 * 8) + } + #[cfg(not(feature="master"))] + self.int_type + }; + for i in 0..mask_num_units { + let field = struct_type.get_field(i as i32); + vector_elements.push(self.context.new_cast(None, mask.access_field(None, field).to_rvalue(), mask_element_type)); + } + + // NOTE: the mask needs to be the same length as the input vectors, so add the missing + // elements in the mask if needed. + for _ in mask_num_units..vec_num_units { + vector_elements.push(self.context.new_rvalue_zero(mask_element_type)); + } + + let array_type = self.context.new_array_type(None, element_type, vec_num_units as i32); + let result_type = self.context.new_vector_type(element_type, mask_num_units as u64); + let (v1, v2) = + if vec_num_units < mask_num_units { + // NOTE: the mask needs to be the same length as the input vectors, so join the 2 + // vectors and create a dummy second vector. + // TODO(antoyo): switch to using new_vector_access. + let array = self.context.new_bitcast(None, v1, array_type); + let mut elements = vec![]; + for i in 0..vec_num_units { + elements.push(self.context.new_array_access(None, array, self.context.new_rvalue_from_int(self.int_type, i as i32)).to_rvalue()); + } + // TODO(antoyo): switch to using new_vector_access. + let array = self.context.new_bitcast(None, v2, array_type); + for i in 0..(mask_num_units - vec_num_units) { + elements.push(self.context.new_array_access(None, array, self.context.new_rvalue_from_int(self.int_type, i as i32)).to_rvalue()); + } + let v1 = self.context.new_rvalue_from_vector(None, result_type, &elements); + let zero = self.context.new_rvalue_zero(element_type); + let v2 = self.context.new_rvalue_from_vector(None, result_type, &vec![zero; mask_num_units]); + (v1, v2) + } + else { + (v1, v2) + }; + + let new_mask_num_units = std::cmp::max(mask_num_units, vec_num_units); + let mask_type = self.context.new_vector_type(mask_element_type, new_mask_num_units as u64); + let mask = self.context.new_rvalue_from_vector(None, mask_type, &vector_elements); + let result = self.context.new_rvalue_vector_perm(None, v1, v2, mask); + + if vec_num_units != mask_num_units { + // NOTE: if padding was added, only select the number of elements of the masks to + // remove that padding in the result. + let mut elements = vec![]; + // TODO(antoyo): switch to using new_vector_access. + let array = self.context.new_bitcast(None, result, array_type); + for i in 0..mask_num_units { + elements.push(self.context.new_array_access(None, array, self.context.new_rvalue_from_int(self.int_type, i as i32)).to_rvalue()); + } + self.context.new_rvalue_from_vector(None, result_type, &elements) + } + else { + result + } + } + + #[cfg(not(feature="master"))] + pub fn shuffle_vector(&mut self, _v1: RValue<'gcc>, _v2: RValue<'gcc>, _mask: RValue<'gcc>) -> RValue<'gcc> { + unimplemented!(); + } + + #[cfg(feature="master")] + pub fn vector_reduce(&mut self, src: RValue<'gcc>, op: F) -> RValue<'gcc> + where F: Fn(RValue<'gcc>, RValue<'gcc>, &'gcc Context<'gcc>) -> RValue<'gcc> + { + let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type"); + let element_count = vector_type.get_num_units(); + let mut vector_elements = vec![]; + for i in 0..element_count { + vector_elements.push(i); + } + let mask_type = self.context.new_vector_type(self.int_type, element_count as u64); + let mut shift = 1; + let mut res = src; + while shift < element_count { + let vector_elements: Vec<_> = + vector_elements.iter() + .map(|i| self.context.new_rvalue_from_int(self.int_type, ((i + shift) % element_count) as i32)) + .collect(); + let mask = self.context.new_rvalue_from_vector(None, mask_type, &vector_elements); + let shifted = self.context.new_rvalue_vector_perm(None, res, res, mask); + shift *= 2; + res = op(res, shifted, &self.context); + } + self.context.new_vector_access(None, res, self.context.new_rvalue_zero(self.int_type)) + .to_rvalue() + } + + #[cfg(not(feature="master"))] + pub fn vector_reduce(&mut self, src: RValue<'gcc>, op: F) -> RValue<'gcc> + where F: Fn(RValue<'gcc>, RValue<'gcc>, &'gcc Context<'gcc>) -> RValue<'gcc> + { + unimplemented!(); } + + pub fn vector_reduce_op(&mut self, src: RValue<'gcc>, op: BinaryOp) -> RValue<'gcc> { + self.vector_reduce(src, |a, b, context| context.new_binary_op(None, op, a.get_type(), a, b)) + } + + pub fn vector_reduce_fadd_fast(&mut self, _acc: RValue<'gcc>, _src: RValue<'gcc>) -> RValue<'gcc> { + unimplemented!(); + } + + pub fn vector_reduce_fmul_fast(&mut self, _acc: RValue<'gcc>, _src: RValue<'gcc>) -> RValue<'gcc> { + unimplemented!(); + } + + // Inspired by Hacker's Delight min implementation. + pub fn vector_reduce_min(&mut self, src: RValue<'gcc>) -> RValue<'gcc> { + self.vector_reduce(src, |a, b, context| { + let differences_or_zeros = difference_or_zero(a, b, context); + context.new_binary_op(None, BinaryOp::Minus, a.get_type(), a, differences_or_zeros) + }) + } + + // Inspired by Hacker's Delight max implementation. + pub fn vector_reduce_max(&mut self, src: RValue<'gcc>) -> RValue<'gcc> { + self.vector_reduce(src, |a, b, context| { + let differences_or_zeros = difference_or_zero(a, b, context); + context.new_binary_op(None, BinaryOp::Plus, b.get_type(), b, differences_or_zeros) + }) + } + + pub fn vector_select(&mut self, cond: RValue<'gcc>, then_val: RValue<'gcc>, else_val: RValue<'gcc>) -> RValue<'gcc> { + // cond is a vector of integers, not of bools. + let cond_type = cond.get_type(); + let vector_type = cond_type.unqualified().dyncast_vector().expect("vector type"); + let num_units = vector_type.get_num_units(); + let element_type = vector_type.get_element_type(); + let zeros = vec![self.context.new_rvalue_zero(element_type); num_units]; + let zeros = self.context.new_rvalue_from_vector(None, cond_type, &zeros); + + let masks = self.context.new_comparison(None, ComparisonOp::NotEquals, cond, zeros); + let then_vals = masks & then_val; + + let ones = vec![self.context.new_rvalue_one(element_type); num_units]; + let ones = self.context.new_rvalue_from_vector(None, cond_type, &ones); + let inverted_masks = masks + ones; + // NOTE: sometimes, the type of else_val can be different than the type of then_val in + // libgccjit (vector of int vs vector of int32_t), but they should be the same for the AND + // operation to work. + let else_val = self.context.new_bitcast(None, else_val, then_val.get_type()); + let else_vals = inverted_masks & else_val; + + then_vals | else_vals + } +} + +fn difference_or_zero<'gcc>(a: RValue<'gcc>, b: RValue<'gcc>, context: &'gcc Context<'gcc>) -> RValue<'gcc> { + let difference = a - b; + let masks = context.new_comparison(None, ComparisonOp::GreaterThanEquals, b, a); + difference & masks } impl<'a, 'gcc, 'tcx> StaticBuilderMethods for Builder<'a, 'gcc, 'tcx> { @@ -1384,9 +1559,8 @@ impl ToGccOrdering for AtomicOrdering { let ordering = match self { - AtomicOrdering::NotAtomic => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same. AtomicOrdering::Unordered => __ATOMIC_RELAXED, - AtomicOrdering::Monotonic => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same. + AtomicOrdering::Relaxed => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same. AtomicOrdering::Acquire => __ATOMIC_ACQUIRE, AtomicOrdering::Release => __ATOMIC_RELEASE, AtomicOrdering::AcquireRelease => __ATOMIC_ACQ_REL, diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index b056b6d473..ce341406ea 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -121,8 +121,8 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { unimplemented!(); } - fn const_real(&self, _t: Type<'gcc>, _val: f64) -> RValue<'gcc> { - unimplemented!(); + fn const_real(&self, typ: Type<'gcc>, val: f64) -> RValue<'gcc> { + self.context.new_rvalue_from_double(typ, val) } fn const_str(&self, s: Symbol) -> (RValue<'gcc>, RValue<'gcc>) { @@ -279,6 +279,21 @@ impl<'gcc, 'tcx> SignType<'gcc, 'tcx> for Type<'gcc> { else if self.is_u128(cx) { cx.i128_type } + else if self.is_uchar(cx) { + cx.char_type + } + else if self.is_ushort(cx) { + cx.short_type + } + else if self.is_uint(cx) { + cx.int_type + } + else if self.is_ulong(cx) { + cx.long_type + } + else if self.is_ulonglong(cx) { + cx.longlong_type + } else { self.clone() } @@ -300,6 +315,21 @@ impl<'gcc, 'tcx> SignType<'gcc, 'tcx> for Type<'gcc> { else if self.is_i128(cx) { cx.u128_type } + else if self.is_char(cx) { + cx.uchar_type + } + else if self.is_short(cx) { + cx.ushort_type + } + else if self.is_int(cx) { + cx.uint_type + } + else if self.is_long(cx) { + cx.ulong_type + } + else if self.is_longlong(cx) { + cx.ulonglong_type + } else { self.clone() } @@ -312,6 +342,11 @@ pub trait TypeReflection<'gcc, 'tcx> { fn is_uint(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; fn is_ulong(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; fn is_ulonglong(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; + fn is_char(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; + fn is_short(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; + fn is_int(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; + fn is_long(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; + fn is_longlong(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; fn is_i8(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; fn is_u8(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; @@ -326,15 +361,17 @@ pub trait TypeReflection<'gcc, 'tcx> { fn is_f32(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; fn is_f64(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; + + fn is_vector(&self) -> bool; } impl<'gcc, 'tcx> TypeReflection<'gcc, 'tcx> for Type<'gcc> { fn is_uchar(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { - self.unqualified() == cx.u8_type + self.unqualified() == cx.uchar_type } fn is_ushort(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { - self.unqualified() == cx.u16_type + self.unqualified() == cx.ushort_type } fn is_uint(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { @@ -349,6 +386,26 @@ impl<'gcc, 'tcx> TypeReflection<'gcc, 'tcx> for Type<'gcc> { self.unqualified() == cx.ulonglong_type } + fn is_char(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { + self.unqualified() == cx.char_type + } + + fn is_short(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { + self.unqualified() == cx.short_type + } + + fn is_int(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { + self.unqualified() == cx.int_type + } + + fn is_long(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { + self.unqualified() == cx.long_type + } + + fn is_longlong(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { + self.unqualified() == cx.longlong_type + } + fn is_i8(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { self.unqualified() == cx.i8_type } @@ -396,4 +453,21 @@ impl<'gcc, 'tcx> TypeReflection<'gcc, 'tcx> for Type<'gcc> { fn is_f64(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool { self.unqualified() == cx.context.new_type::() } + + fn is_vector(&self) -> bool { + let mut typ = self.clone(); + loop { + if typ.dyncast_vector().is_some() { + return true; + } + + let old_type = typ; + typ = typ.unqualified(); + if old_type == typ { + break; + } + } + + false + } } diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 3dc456f1aa..c0b8d21818 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -25,7 +25,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } } - self.context.new_bitcast(None, value, typ) + // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some + // SIMD builtins require a constant value. + self.bitcast_if_needed(value, typ) } } @@ -45,7 +47,10 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { } } let global_value = self.static_addr_of_mut(cv, align, kind); - // TODO(antoyo): set global constant. + #[cfg(feature = "master")] + self.global_lvalues.borrow().get(&global_value) + .expect("`static_addr_of_mut` did not add the global to `self.global_lvalues`") + .global_set_readonly(); self.const_globals.borrow_mut().insert(cv, global_value); global_value } @@ -79,20 +84,15 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { // TODO(antoyo): set alignment. - let value = - if value.get_type() != gcc_type { - self.context.new_bitcast(None, value, gcc_type) - } - else { - value - }; + let value = self.bitcast_if_needed(value, gcc_type); global.global_set_initializer_rvalue(value); // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. if !is_mutable { if self.type_is_freeze(ty) { - // TODO(antoyo): set global constant. + #[cfg(feature = "master")] + global.global_set_readonly(); } } @@ -171,8 +171,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { Some(kind) if !self.tcx.sess.fewer_names() => { let name = self.generate_local_symbol_name(kind); // TODO(antoyo): check if it's okay that no link_section is set. - // TODO(antoyo): set alignment here as well. - let global = self.declare_private_global(&name[..], self.val_ty(cv)); + + let typ = self.val_ty(cv).get_aligned(align.bytes()); + let global = self.declare_private_global(&name[..], typ); global } _ => { diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index edbe7122bd..44f36cfa4c 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -35,6 +35,7 @@ pub struct CodegenCx<'gcc, 'tcx> { pub normal_function_addresses: RefCell>>, pub functions: RefCell>>, + pub intrinsics: RefCell>>, pub tls_model: gccjit::TlsModel, @@ -53,10 +54,15 @@ pub struct CodegenCx<'gcc, 'tcx> { pub u128_type: Type<'gcc>, pub usize_type: Type<'gcc>, + pub char_type: Type<'gcc>, + pub uchar_type: Type<'gcc>, + pub short_type: Type<'gcc>, + pub ushort_type: Type<'gcc>, pub int_type: Type<'gcc>, pub uint_type: Type<'gcc>, pub long_type: Type<'gcc>, pub ulong_type: Type<'gcc>, + pub longlong_type: Type<'gcc>, pub ulonglong_type: Type<'gcc>, pub sizet_type: Type<'gcc>, @@ -145,10 +151,15 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let float_type = context.new_type::(); let double_type = context.new_type::(); + let char_type = context.new_c_type(CType::Char); + let uchar_type = context.new_c_type(CType::UChar); + let short_type = context.new_c_type(CType::Short); + let ushort_type = context.new_c_type(CType::UShort); let int_type = context.new_c_type(CType::Int); let uint_type = context.new_c_type(CType::UInt); let long_type = context.new_c_type(CType::Long); let ulong_type = context.new_c_type(CType::ULong); + let longlong_type = context.new_c_type(CType::LongLong); let ulonglong_type = context.new_c_type(CType::ULongLong); let sizet_type = context.new_c_type(CType::SizeT); @@ -184,6 +195,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { current_func: RefCell::new(None), normal_function_addresses: Default::default(), functions: RefCell::new(functions), + intrinsics: RefCell::new(FxHashMap::default()), tls_model, @@ -200,10 +212,15 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { u32_type, u64_type, u128_type, + char_type, + uchar_type, + short_type, + ushort_type, int_type, uint_type, long_type, ulong_type, + longlong_type, ulonglong_type, sizet_type, @@ -269,16 +286,25 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } pub fn is_native_int_type_or_bool(&self, typ: Type<'gcc>) -> bool { - self.is_native_int_type(typ) || typ == self.bool_type + self.is_native_int_type(typ) || typ.is_compatible_with(self.bool_type) } pub fn is_int_type_or_bool(&self, typ: Type<'gcc>) -> bool { - self.is_native_int_type(typ) || self.is_non_native_int_type(typ) || typ == self.bool_type + self.is_native_int_type(typ) || self.is_non_native_int_type(typ) || typ.is_compatible_with(self.bool_type) } pub fn sess(&self) -> &Session { &self.tcx.sess } + + pub fn bitcast_if_needed(&self, value: RValue<'gcc>, expected_type: Type<'gcc>) -> RValue<'gcc> { + if value.get_type() != expected_type { + self.context.new_bitcast(None, value, expected_type) + } + else { + value + } + } } impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> { @@ -306,8 +332,16 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> { - let func = get_fn(self, instance); - let func = self.rvalue_as_function(func); + let func_name = self.tcx.symbol_name(instance).name; + + let func = + if self.intrinsics.borrow().contains_key(func_name) { + self.intrinsics.borrow()[func_name].clone() + } + else { + let func = get_fn(self, instance); + self.rvalue_as_function(func) + }; let ptr = func.get_address(None); // TODO(antoyo): don't do this twice: i.e. in declare_fn and here. diff --git a/compiler/rustc_codegen_gcc/src/declare.rs b/compiler/rustc_codegen_gcc/src/declare.rs index 4301737691..a619e2f771 100644 --- a/compiler/rustc_codegen_gcc/src/declare.rs +++ b/compiler/rustc_codegen_gcc/src/declare.rs @@ -11,7 +11,7 @@ use crate::intrinsic::llvm; impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn get_or_insert_global(&self, name: &str, ty: Type<'gcc>, is_tls: bool, link_section: Option) -> LValue<'gcc> { if self.globals.borrow().contains_key(name) { - let typ = self.globals.borrow().get(name).expect("global").get_type(); + let typ = self.globals.borrow()[name].get_type(); let global = self.context.new_global(None, GlobalKind::Imported, typ, name); if is_tls { global.set_tls_model(self.tls_model); @@ -103,11 +103,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { /// update the declaration and return existing Value instead. fn declare_raw_fn<'gcc>(cx: &CodegenCx<'gcc, '_>, name: &str, _callconv: () /*llvm::CallConv*/, return_type: Type<'gcc>, param_types: &[Type<'gcc>], variadic: bool) -> Function<'gcc> { if name.starts_with("llvm.") { - return llvm::intrinsic(name, cx); + let intrinsic = llvm::intrinsic(name, cx); + cx.intrinsics.borrow_mut().insert(name.to_string(), intrinsic); + return intrinsic; } let func = if cx.functions.borrow().contains_key(name) { - *cx.functions.borrow().get(name).expect("function") + cx.functions.borrow()[name] } else { let params: Vec<_> = param_types.into_iter().enumerate() diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs index c3ed71ff73..0c5dab0046 100644 --- a/compiler/rustc_codegen_gcc/src/int.rs +++ b/compiler/rustc_codegen_gcc/src/int.rs @@ -153,8 +153,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let a_type = a.get_type(); let b_type = b.get_type(); if self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type) { - if a.get_type() != b.get_type() { - b = self.context.new_cast(None, b, a.get_type()); + if a_type != b_type { + if a_type.is_vector() { + // Vector types need to be bitcast. + // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. + b = self.context.new_bitcast(None, b, a.get_type()); + } + else { + b = self.context.new_cast(None, b, a.get_type()); + } } self.context.new_binary_op(None, operation, a_type, a, b) } @@ -593,7 +600,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let b_type = b.get_type(); let a_native = self.is_native_int_type_or_bool(a_type); let b_native = self.is_native_int_type_or_bool(b_type); - if a_native && b_native { + if a_type.is_vector() && b_type.is_vector() { + self.context.new_binary_op(None, operation, a_type, a, b) + } + else if a_native && b_native { if a_type != b_type { b = self.context.new_cast(None, b, a_type); } @@ -639,6 +649,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { else { // Since u128 and i128 are the only types that can be unsupported, we know the type of // value and the destination type have the same size, so a bitcast is fine. + + // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. self.context.new_bitcast(None, value, dest_typ) } } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs b/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs new file mode 100644 index 0000000000..fb6c38fa07 --- /dev/null +++ b/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs @@ -0,0 +1,5722 @@ +// File generated by `rustc_codegen_gcc/tools/generate_intrinsics.py` +// DO NOT EDIT IT! +match name { + // AMDGPU + "llvm.AMDGPU.div.fixup.f32" => "__builtin_amdgpu_div_fixup", + "llvm.AMDGPU.div.fixup.f64" => "__builtin_amdgpu_div_fixup", + "llvm.AMDGPU.div.fixup.v2f64" => "__builtin_amdgpu_div_fixup", + "llvm.AMDGPU.div.fixup.v4f32" => "__builtin_amdgpu_div_fixup", + "llvm.AMDGPU.div.fmas.f32" => "__builtin_amdgpu_div_fmas", + "llvm.AMDGPU.div.fmas.f64" => "__builtin_amdgpu_div_fmas", + "llvm.AMDGPU.div.fmas.v2f64" => "__builtin_amdgpu_div_fmas", + "llvm.AMDGPU.div.fmas.v4f32" => "__builtin_amdgpu_div_fmas", + "llvm.AMDGPU.ldexp.f32" => "__builtin_amdgpu_ldexp", + "llvm.AMDGPU.ldexp.f64" => "__builtin_amdgpu_ldexp", + "llvm.AMDGPU.ldexp.v2f64" => "__builtin_amdgpu_ldexp", + "llvm.AMDGPU.ldexp.v4f32" => "__builtin_amdgpu_ldexp", + "llvm.AMDGPU.rcp.f32" => "__builtin_amdgpu_rcp", + "llvm.AMDGPU.rcp.f64" => "__builtin_amdgpu_rcp", + "llvm.AMDGPU.rcp.v2f64" => "__builtin_amdgpu_rcp", + "llvm.AMDGPU.rcp.v4f32" => "__builtin_amdgpu_rcp", + "llvm.AMDGPU.rsq.clamped.f32" => "__builtin_amdgpu_rsq_clamped", + "llvm.AMDGPU.rsq.clamped.f64" => "__builtin_amdgpu_rsq_clamped", + "llvm.AMDGPU.rsq.clamped.v2f64" => "__builtin_amdgpu_rsq_clamped", + "llvm.AMDGPU.rsq.clamped.v4f32" => "__builtin_amdgpu_rsq_clamped", + "llvm.AMDGPU.rsq.f32" => "__builtin_amdgpu_rsq", + "llvm.AMDGPU.rsq.f64" => "__builtin_amdgpu_rsq", + "llvm.AMDGPU.rsq.v2f64" => "__builtin_amdgpu_rsq", + "llvm.AMDGPU.rsq.v4f32" => "__builtin_amdgpu_rsq", + "llvm.AMDGPU.trig.preop.f32" => "__builtin_amdgpu_trig_preop", + "llvm.AMDGPU.trig.preop.f64" => "__builtin_amdgpu_trig_preop", + "llvm.AMDGPU.trig.preop.v2f64" => "__builtin_amdgpu_trig_preop", + "llvm.AMDGPU.trig.preop.v4f32" => "__builtin_amdgpu_trig_preop", + // aarch64 + "llvm.aarch64.dmb" => "__builtin_arm_dmb", + "llvm.aarch64.dsb" => "__builtin_arm_dsb", + "llvm.aarch64.isb" => "__builtin_arm_isb", + "llvm.aarch64.sve.aesd" => "__builtin_sve_svaesd_u8", + "llvm.aarch64.sve.aese" => "__builtin_sve_svaese_u8", + "llvm.aarch64.sve.aesimc" => "__builtin_sve_svaesimc_u8", + "llvm.aarch64.sve.aesmc" => "__builtin_sve_svaesmc_u8", + "llvm.aarch64.sve.rax1" => "__builtin_sve_svrax1_u64", + "llvm.aarch64.sve.rdffr" => "__builtin_sve_svrdffr", + "llvm.aarch64.sve.rdffr.z" => "__builtin_sve_svrdffr_z", + "llvm.aarch64.sve.setffr" => "__builtin_sve_svsetffr", + "llvm.aarch64.sve.sm4e" => "__builtin_sve_svsm4e_u32", + "llvm.aarch64.sve.sm4ekey" => "__builtin_sve_svsm4ekey_u32", + "llvm.aarch64.sve.wrffr" => "__builtin_sve_svwrffr", + "llvm.aarch64.tcancel" => "__builtin_arm_tcancel", + "llvm.aarch64.tcommit" => "__builtin_arm_tcommit", + "llvm.aarch64.tstart" => "__builtin_arm_tstart", + "llvm.aarch64.ttest" => "__builtin_arm_ttest", + // amdgcn + "llvm.amdgcn.alignbyte" => "__builtin_amdgcn_alignbyte", + "llvm.amdgcn.buffer.wbinvl1" => "__builtin_amdgcn_buffer_wbinvl1", + "llvm.amdgcn.buffer.wbinvl1.sc" => "__builtin_amdgcn_buffer_wbinvl1_sc", + "llvm.amdgcn.buffer.wbinvl1.vol" => "__builtin_amdgcn_buffer_wbinvl1_vol", + "llvm.amdgcn.cubeid" => "__builtin_amdgcn_cubeid", + "llvm.amdgcn.cubema" => "__builtin_amdgcn_cubema", + "llvm.amdgcn.cubesc" => "__builtin_amdgcn_cubesc", + "llvm.amdgcn.cubetc" => "__builtin_amdgcn_cubetc", + "llvm.amdgcn.cvt.pk.i16" => "__builtin_amdgcn_cvt_pk_i16", + "llvm.amdgcn.cvt.pk.u16" => "__builtin_amdgcn_cvt_pk_u16", + "llvm.amdgcn.cvt.pk.u8.f32" => "__builtin_amdgcn_cvt_pk_u8_f32", + "llvm.amdgcn.cvt.pknorm.i16" => "__builtin_amdgcn_cvt_pknorm_i16", + "llvm.amdgcn.cvt.pknorm.u16" => "__builtin_amdgcn_cvt_pknorm_u16", + "llvm.amdgcn.cvt.pkrtz" => "__builtin_amdgcn_cvt_pkrtz", + "llvm.amdgcn.dispatch.id" => "__builtin_amdgcn_dispatch_id", + "llvm.amdgcn.ds.bpermute" => "__builtin_amdgcn_ds_bpermute", + "llvm.amdgcn.ds.fadd.v2bf16" => "__builtin_amdgcn_ds_atomic_fadd_v2bf16", + "llvm.amdgcn.ds.gws.barrier" => "__builtin_amdgcn_ds_gws_barrier", + "llvm.amdgcn.ds.gws.init" => "__builtin_amdgcn_ds_gws_init", + "llvm.amdgcn.ds.gws.sema.br" => "__builtin_amdgcn_ds_gws_sema_br", + "llvm.amdgcn.ds.gws.sema.p" => "__builtin_amdgcn_ds_gws_sema_p", + "llvm.amdgcn.ds.gws.sema.release.all" => "__builtin_amdgcn_ds_gws_sema_release_all", + "llvm.amdgcn.ds.gws.sema.v" => "__builtin_amdgcn_ds_gws_sema_v", + "llvm.amdgcn.ds.permute" => "__builtin_amdgcn_ds_permute", + "llvm.amdgcn.ds.swizzle" => "__builtin_amdgcn_ds_swizzle", + "llvm.amdgcn.endpgm" => "__builtin_amdgcn_endpgm", + "llvm.amdgcn.fdot2" => "__builtin_amdgcn_fdot2", + "llvm.amdgcn.fmed3" => "__builtin_amdgcn_fmed3", + "llvm.amdgcn.fmul.legacy" => "__builtin_amdgcn_fmul_legacy", + "llvm.amdgcn.groupstaticsize" => "__builtin_amdgcn_groupstaticsize", + "llvm.amdgcn.implicit.buffer.ptr" => "__builtin_amdgcn_implicit_buffer_ptr", + "llvm.amdgcn.implicitarg.ptr" => "__builtin_amdgcn_implicitarg_ptr", + "llvm.amdgcn.interp.mov" => "__builtin_amdgcn_interp_mov", + "llvm.amdgcn.interp.p1" => "__builtin_amdgcn_interp_p1", + "llvm.amdgcn.interp.p1.f16" => "__builtin_amdgcn_interp_p1_f16", + "llvm.amdgcn.interp.p2" => "__builtin_amdgcn_interp_p2", + "llvm.amdgcn.interp.p2.f16" => "__builtin_amdgcn_interp_p2_f16", + "llvm.amdgcn.is.private" => "__builtin_amdgcn_is_private", + "llvm.amdgcn.is.shared" => "__builtin_amdgcn_is_shared", + "llvm.amdgcn.kernarg.segment.ptr" => "__builtin_amdgcn_kernarg_segment_ptr", + "llvm.amdgcn.lerp" => "__builtin_amdgcn_lerp", + "llvm.amdgcn.mbcnt.hi" => "__builtin_amdgcn_mbcnt_hi", + "llvm.amdgcn.mbcnt.lo" => "__builtin_amdgcn_mbcnt_lo", + "llvm.amdgcn.mqsad.pk.u16.u8" => "__builtin_amdgcn_mqsad_pk_u16_u8", + "llvm.amdgcn.mqsad.u32.u8" => "__builtin_amdgcn_mqsad_u32_u8", + "llvm.amdgcn.msad.u8" => "__builtin_amdgcn_msad_u8", + "llvm.amdgcn.perm" => "__builtin_amdgcn_perm", + "llvm.amdgcn.permlane16" => "__builtin_amdgcn_permlane16", + "llvm.amdgcn.permlanex16" => "__builtin_amdgcn_permlanex16", + "llvm.amdgcn.qsad.pk.u16.u8" => "__builtin_amdgcn_qsad_pk_u16_u8", + "llvm.amdgcn.queue.ptr" => "__builtin_amdgcn_queue_ptr", + "llvm.amdgcn.rcp.legacy" => "__builtin_amdgcn_rcp_legacy", + "llvm.amdgcn.readfirstlane" => "__builtin_amdgcn_readfirstlane", + "llvm.amdgcn.readlane" => "__builtin_amdgcn_readlane", + "llvm.amdgcn.rsq.legacy" => "__builtin_amdgcn_rsq_legacy", + "llvm.amdgcn.s.barrier" => "__builtin_amdgcn_s_barrier", + "llvm.amdgcn.s.dcache.inv" => "__builtin_amdgcn_s_dcache_inv", + "llvm.amdgcn.s.dcache.inv.vol" => "__builtin_amdgcn_s_dcache_inv_vol", + "llvm.amdgcn.s.dcache.wb" => "__builtin_amdgcn_s_dcache_wb", + "llvm.amdgcn.s.dcache.wb.vol" => "__builtin_amdgcn_s_dcache_wb_vol", + "llvm.amdgcn.s.decperflevel" => "__builtin_amdgcn_s_decperflevel", + "llvm.amdgcn.s.get.waveid.in.workgroup" => "__builtin_amdgcn_s_get_waveid_in_workgroup", + "llvm.amdgcn.s.getpc" => "__builtin_amdgcn_s_getpc", + "llvm.amdgcn.s.getreg" => "__builtin_amdgcn_s_getreg", + "llvm.amdgcn.s.incperflevel" => "__builtin_amdgcn_s_incperflevel", + "llvm.amdgcn.s.memrealtime" => "__builtin_amdgcn_s_memrealtime", + "llvm.amdgcn.s.memtime" => "__builtin_amdgcn_s_memtime", + "llvm.amdgcn.s.sendmsg" => "__builtin_amdgcn_s_sendmsg", + "llvm.amdgcn.s.sendmsghalt" => "__builtin_amdgcn_s_sendmsghalt", + "llvm.amdgcn.s.setprio" => "__builtin_amdgcn_s_setprio", + "llvm.amdgcn.s.setreg" => "__builtin_amdgcn_s_setreg", + "llvm.amdgcn.s.sleep" => "__builtin_amdgcn_s_sleep", + "llvm.amdgcn.s.waitcnt" => "__builtin_amdgcn_s_waitcnt", + "llvm.amdgcn.sad.hi.u8" => "__builtin_amdgcn_sad_hi_u8", + "llvm.amdgcn.sad.u16" => "__builtin_amdgcn_sad_u16", + "llvm.amdgcn.sad.u8" => "__builtin_amdgcn_sad_u8", + "llvm.amdgcn.sched.barrier" => "__builtin_amdgcn_sched_barrier", + "llvm.amdgcn.sdot2" => "__builtin_amdgcn_sdot2", + "llvm.amdgcn.sdot4" => "__builtin_amdgcn_sdot4", + "llvm.amdgcn.sdot8" => "__builtin_amdgcn_sdot8", + "llvm.amdgcn.udot2" => "__builtin_amdgcn_udot2", + "llvm.amdgcn.udot4" => "__builtin_amdgcn_udot4", + "llvm.amdgcn.udot8" => "__builtin_amdgcn_udot8", + "llvm.amdgcn.wave.barrier" => "__builtin_amdgcn_wave_barrier", + "llvm.amdgcn.wavefrontsize" => "__builtin_amdgcn_wavefrontsize", + "llvm.amdgcn.writelane" => "__builtin_amdgcn_writelane", + // arm + "llvm.arm.cdp" => "__builtin_arm_cdp", + "llvm.arm.cdp2" => "__builtin_arm_cdp2", + "llvm.arm.cmse.tt" => "__builtin_arm_cmse_TT", + "llvm.arm.cmse.tta" => "__builtin_arm_cmse_TTA", + "llvm.arm.cmse.ttat" => "__builtin_arm_cmse_TTAT", + "llvm.arm.cmse.ttt" => "__builtin_arm_cmse_TTT", + "llvm.arm.dmb" => "__builtin_arm_dmb", + "llvm.arm.dsb" => "__builtin_arm_dsb", + "llvm.arm.get.fpscr" => "__builtin_arm_get_fpscr", + "llvm.arm.isb" => "__builtin_arm_isb", + "llvm.arm.ldc" => "__builtin_arm_ldc", + "llvm.arm.ldc2" => "__builtin_arm_ldc2", + "llvm.arm.ldc2l" => "__builtin_arm_ldc2l", + "llvm.arm.ldcl" => "__builtin_arm_ldcl", + "llvm.arm.mcr" => "__builtin_arm_mcr", + "llvm.arm.mcr2" => "__builtin_arm_mcr2", + "llvm.arm.mcrr" => "__builtin_arm_mcrr", + "llvm.arm.mcrr2" => "__builtin_arm_mcrr2", + "llvm.arm.mrc" => "__builtin_arm_mrc", + "llvm.arm.mrc2" => "__builtin_arm_mrc2", + "llvm.arm.qadd" => "__builtin_arm_qadd", + "llvm.arm.qadd16" => "__builtin_arm_qadd16", + "llvm.arm.qadd8" => "__builtin_arm_qadd8", + "llvm.arm.qasx" => "__builtin_arm_qasx", + "llvm.arm.qsax" => "__builtin_arm_qsax", + "llvm.arm.qsub" => "__builtin_arm_qsub", + "llvm.arm.qsub16" => "__builtin_arm_qsub16", + "llvm.arm.qsub8" => "__builtin_arm_qsub8", + "llvm.arm.sadd16" => "__builtin_arm_sadd16", + "llvm.arm.sadd8" => "__builtin_arm_sadd8", + "llvm.arm.sasx" => "__builtin_arm_sasx", + "llvm.arm.sel" => "__builtin_arm_sel", + "llvm.arm.set.fpscr" => "__builtin_arm_set_fpscr", + "llvm.arm.shadd16" => "__builtin_arm_shadd16", + "llvm.arm.shadd8" => "__builtin_arm_shadd8", + "llvm.arm.shasx" => "__builtin_arm_shasx", + "llvm.arm.shsax" => "__builtin_arm_shsax", + "llvm.arm.shsub16" => "__builtin_arm_shsub16", + "llvm.arm.shsub8" => "__builtin_arm_shsub8", + "llvm.arm.smlabb" => "__builtin_arm_smlabb", + "llvm.arm.smlabt" => "__builtin_arm_smlabt", + "llvm.arm.smlad" => "__builtin_arm_smlad", + "llvm.arm.smladx" => "__builtin_arm_smladx", + "llvm.arm.smlald" => "__builtin_arm_smlald", + "llvm.arm.smlaldx" => "__builtin_arm_smlaldx", + "llvm.arm.smlatb" => "__builtin_arm_smlatb", + "llvm.arm.smlatt" => "__builtin_arm_smlatt", + "llvm.arm.smlawb" => "__builtin_arm_smlawb", + "llvm.arm.smlawt" => "__builtin_arm_smlawt", + "llvm.arm.smlsd" => "__builtin_arm_smlsd", + "llvm.arm.smlsdx" => "__builtin_arm_smlsdx", + "llvm.arm.smlsld" => "__builtin_arm_smlsld", + "llvm.arm.smlsldx" => "__builtin_arm_smlsldx", + "llvm.arm.smuad" => "__builtin_arm_smuad", + "llvm.arm.smuadx" => "__builtin_arm_smuadx", + "llvm.arm.smulbb" => "__builtin_arm_smulbb", + "llvm.arm.smulbt" => "__builtin_arm_smulbt", + "llvm.arm.smultb" => "__builtin_arm_smultb", + "llvm.arm.smultt" => "__builtin_arm_smultt", + "llvm.arm.smulwb" => "__builtin_arm_smulwb", + "llvm.arm.smulwt" => "__builtin_arm_smulwt", + "llvm.arm.smusd" => "__builtin_arm_smusd", + "llvm.arm.smusdx" => "__builtin_arm_smusdx", + "llvm.arm.ssat" => "__builtin_arm_ssat", + "llvm.arm.ssat16" => "__builtin_arm_ssat16", + "llvm.arm.ssax" => "__builtin_arm_ssax", + "llvm.arm.ssub16" => "__builtin_arm_ssub16", + "llvm.arm.ssub8" => "__builtin_arm_ssub8", + "llvm.arm.stc" => "__builtin_arm_stc", + "llvm.arm.stc2" => "__builtin_arm_stc2", + "llvm.arm.stc2l" => "__builtin_arm_stc2l", + "llvm.arm.stcl" => "__builtin_arm_stcl", + "llvm.arm.sxtab16" => "__builtin_arm_sxtab16", + "llvm.arm.sxtb16" => "__builtin_arm_sxtb16", + "llvm.arm.thread.pointer" => "__builtin_thread_pointer", + "llvm.arm.uadd16" => "__builtin_arm_uadd16", + "llvm.arm.uadd8" => "__builtin_arm_uadd8", + "llvm.arm.uasx" => "__builtin_arm_uasx", + "llvm.arm.uhadd16" => "__builtin_arm_uhadd16", + "llvm.arm.uhadd8" => "__builtin_arm_uhadd8", + "llvm.arm.uhasx" => "__builtin_arm_uhasx", + "llvm.arm.uhsax" => "__builtin_arm_uhsax", + "llvm.arm.uhsub16" => "__builtin_arm_uhsub16", + "llvm.arm.uhsub8" => "__builtin_arm_uhsub8", + "llvm.arm.uqadd16" => "__builtin_arm_uqadd16", + "llvm.arm.uqadd8" => "__builtin_arm_uqadd8", + "llvm.arm.uqasx" => "__builtin_arm_uqasx", + "llvm.arm.uqsax" => "__builtin_arm_uqsax", + "llvm.arm.uqsub16" => "__builtin_arm_uqsub16", + "llvm.arm.uqsub8" => "__builtin_arm_uqsub8", + "llvm.arm.usad8" => "__builtin_arm_usad8", + "llvm.arm.usada8" => "__builtin_arm_usada8", + "llvm.arm.usat" => "__builtin_arm_usat", + "llvm.arm.usat16" => "__builtin_arm_usat16", + "llvm.arm.usax" => "__builtin_arm_usax", + "llvm.arm.usub16" => "__builtin_arm_usub16", + "llvm.arm.usub8" => "__builtin_arm_usub8", + "llvm.arm.uxtab16" => "__builtin_arm_uxtab16", + "llvm.arm.uxtb16" => "__builtin_arm_uxtb16", + // bpf + "llvm.bpf.btf.type.id" => "__builtin_bpf_btf_type_id", + "llvm.bpf.compare" => "__builtin_bpf_compare", + "llvm.bpf.load.byte" => "__builtin_bpf_load_byte", + "llvm.bpf.load.half" => "__builtin_bpf_load_half", + "llvm.bpf.load.word" => "__builtin_bpf_load_word", + "llvm.bpf.passthrough" => "__builtin_bpf_passthrough", + "llvm.bpf.preserve.enum.value" => "__builtin_bpf_preserve_enum_value", + "llvm.bpf.preserve.field.info" => "__builtin_bpf_preserve_field_info", + "llvm.bpf.preserve.type.info" => "__builtin_bpf_preserve_type_info", + "llvm.bpf.pseudo" => "__builtin_bpf_pseudo", + // cuda + "llvm.cuda.syncthreads" => "__syncthreads", + // hexagon + "llvm.hexagon.A2.abs" => "__builtin_HEXAGON_A2_abs", + "llvm.hexagon.A2.absp" => "__builtin_HEXAGON_A2_absp", + "llvm.hexagon.A2.abssat" => "__builtin_HEXAGON_A2_abssat", + "llvm.hexagon.A2.add" => "__builtin_HEXAGON_A2_add", + "llvm.hexagon.A2.addh.h16.hh" => "__builtin_HEXAGON_A2_addh_h16_hh", + "llvm.hexagon.A2.addh.h16.hl" => "__builtin_HEXAGON_A2_addh_h16_hl", + "llvm.hexagon.A2.addh.h16.lh" => "__builtin_HEXAGON_A2_addh_h16_lh", + "llvm.hexagon.A2.addh.h16.ll" => "__builtin_HEXAGON_A2_addh_h16_ll", + "llvm.hexagon.A2.addh.h16.sat.hh" => "__builtin_HEXAGON_A2_addh_h16_sat_hh", + "llvm.hexagon.A2.addh.h16.sat.hl" => "__builtin_HEXAGON_A2_addh_h16_sat_hl", + "llvm.hexagon.A2.addh.h16.sat.lh" => "__builtin_HEXAGON_A2_addh_h16_sat_lh", + "llvm.hexagon.A2.addh.h16.sat.ll" => "__builtin_HEXAGON_A2_addh_h16_sat_ll", + "llvm.hexagon.A2.addh.l16.hl" => "__builtin_HEXAGON_A2_addh_l16_hl", + "llvm.hexagon.A2.addh.l16.ll" => "__builtin_HEXAGON_A2_addh_l16_ll", + "llvm.hexagon.A2.addh.l16.sat.hl" => "__builtin_HEXAGON_A2_addh_l16_sat_hl", + "llvm.hexagon.A2.addh.l16.sat.ll" => "__builtin_HEXAGON_A2_addh_l16_sat_ll", + "llvm.hexagon.A2.addi" => "__builtin_HEXAGON_A2_addi", + "llvm.hexagon.A2.addp" => "__builtin_HEXAGON_A2_addp", + "llvm.hexagon.A2.addpsat" => "__builtin_HEXAGON_A2_addpsat", + "llvm.hexagon.A2.addsat" => "__builtin_HEXAGON_A2_addsat", + "llvm.hexagon.A2.addsp" => "__builtin_HEXAGON_A2_addsp", + "llvm.hexagon.A2.and" => "__builtin_HEXAGON_A2_and", + "llvm.hexagon.A2.andir" => "__builtin_HEXAGON_A2_andir", + "llvm.hexagon.A2.andp" => "__builtin_HEXAGON_A2_andp", + "llvm.hexagon.A2.aslh" => "__builtin_HEXAGON_A2_aslh", + "llvm.hexagon.A2.asrh" => "__builtin_HEXAGON_A2_asrh", + "llvm.hexagon.A2.combine.hh" => "__builtin_HEXAGON_A2_combine_hh", + "llvm.hexagon.A2.combine.hl" => "__builtin_HEXAGON_A2_combine_hl", + "llvm.hexagon.A2.combine.lh" => "__builtin_HEXAGON_A2_combine_lh", + "llvm.hexagon.A2.combine.ll" => "__builtin_HEXAGON_A2_combine_ll", + "llvm.hexagon.A2.combineii" => "__builtin_HEXAGON_A2_combineii", + "llvm.hexagon.A2.combinew" => "__builtin_HEXAGON_A2_combinew", + "llvm.hexagon.A2.max" => "__builtin_HEXAGON_A2_max", + "llvm.hexagon.A2.maxp" => "__builtin_HEXAGON_A2_maxp", + "llvm.hexagon.A2.maxu" => "__builtin_HEXAGON_A2_maxu", + "llvm.hexagon.A2.maxup" => "__builtin_HEXAGON_A2_maxup", + "llvm.hexagon.A2.min" => "__builtin_HEXAGON_A2_min", + "llvm.hexagon.A2.minp" => "__builtin_HEXAGON_A2_minp", + "llvm.hexagon.A2.minu" => "__builtin_HEXAGON_A2_minu", + "llvm.hexagon.A2.minup" => "__builtin_HEXAGON_A2_minup", + "llvm.hexagon.A2.neg" => "__builtin_HEXAGON_A2_neg", + "llvm.hexagon.A2.negp" => "__builtin_HEXAGON_A2_negp", + "llvm.hexagon.A2.negsat" => "__builtin_HEXAGON_A2_negsat", + "llvm.hexagon.A2.not" => "__builtin_HEXAGON_A2_not", + "llvm.hexagon.A2.notp" => "__builtin_HEXAGON_A2_notp", + "llvm.hexagon.A2.or" => "__builtin_HEXAGON_A2_or", + "llvm.hexagon.A2.orir" => "__builtin_HEXAGON_A2_orir", + "llvm.hexagon.A2.orp" => "__builtin_HEXAGON_A2_orp", + "llvm.hexagon.A2.roundsat" => "__builtin_HEXAGON_A2_roundsat", + "llvm.hexagon.A2.sat" => "__builtin_HEXAGON_A2_sat", + "llvm.hexagon.A2.satb" => "__builtin_HEXAGON_A2_satb", + "llvm.hexagon.A2.sath" => "__builtin_HEXAGON_A2_sath", + "llvm.hexagon.A2.satub" => "__builtin_HEXAGON_A2_satub", + "llvm.hexagon.A2.satuh" => "__builtin_HEXAGON_A2_satuh", + "llvm.hexagon.A2.sub" => "__builtin_HEXAGON_A2_sub", + "llvm.hexagon.A2.subh.h16.hh" => "__builtin_HEXAGON_A2_subh_h16_hh", + "llvm.hexagon.A2.subh.h16.hl" => "__builtin_HEXAGON_A2_subh_h16_hl", + "llvm.hexagon.A2.subh.h16.lh" => "__builtin_HEXAGON_A2_subh_h16_lh", + "llvm.hexagon.A2.subh.h16.ll" => "__builtin_HEXAGON_A2_subh_h16_ll", + "llvm.hexagon.A2.subh.h16.sat.hh" => "__builtin_HEXAGON_A2_subh_h16_sat_hh", + "llvm.hexagon.A2.subh.h16.sat.hl" => "__builtin_HEXAGON_A2_subh_h16_sat_hl", + "llvm.hexagon.A2.subh.h16.sat.lh" => "__builtin_HEXAGON_A2_subh_h16_sat_lh", + "llvm.hexagon.A2.subh.h16.sat.ll" => "__builtin_HEXAGON_A2_subh_h16_sat_ll", + "llvm.hexagon.A2.subh.l16.hl" => "__builtin_HEXAGON_A2_subh_l16_hl", + "llvm.hexagon.A2.subh.l16.ll" => "__builtin_HEXAGON_A2_subh_l16_ll", + "llvm.hexagon.A2.subh.l16.sat.hl" => "__builtin_HEXAGON_A2_subh_l16_sat_hl", + "llvm.hexagon.A2.subh.l16.sat.ll" => "__builtin_HEXAGON_A2_subh_l16_sat_ll", + "llvm.hexagon.A2.subp" => "__builtin_HEXAGON_A2_subp", + "llvm.hexagon.A2.subri" => "__builtin_HEXAGON_A2_subri", + "llvm.hexagon.A2.subsat" => "__builtin_HEXAGON_A2_subsat", + "llvm.hexagon.A2.svaddh" => "__builtin_HEXAGON_A2_svaddh", + "llvm.hexagon.A2.svaddhs" => "__builtin_HEXAGON_A2_svaddhs", + "llvm.hexagon.A2.svadduhs" => "__builtin_HEXAGON_A2_svadduhs", + "llvm.hexagon.A2.svavgh" => "__builtin_HEXAGON_A2_svavgh", + "llvm.hexagon.A2.svavghs" => "__builtin_HEXAGON_A2_svavghs", + "llvm.hexagon.A2.svnavgh" => "__builtin_HEXAGON_A2_svnavgh", + "llvm.hexagon.A2.svsubh" => "__builtin_HEXAGON_A2_svsubh", + "llvm.hexagon.A2.svsubhs" => "__builtin_HEXAGON_A2_svsubhs", + "llvm.hexagon.A2.svsubuhs" => "__builtin_HEXAGON_A2_svsubuhs", + "llvm.hexagon.A2.swiz" => "__builtin_HEXAGON_A2_swiz", + "llvm.hexagon.A2.sxtb" => "__builtin_HEXAGON_A2_sxtb", + "llvm.hexagon.A2.sxth" => "__builtin_HEXAGON_A2_sxth", + "llvm.hexagon.A2.sxtw" => "__builtin_HEXAGON_A2_sxtw", + "llvm.hexagon.A2.tfr" => "__builtin_HEXAGON_A2_tfr", + "llvm.hexagon.A2.tfrih" => "__builtin_HEXAGON_A2_tfrih", + "llvm.hexagon.A2.tfril" => "__builtin_HEXAGON_A2_tfril", + "llvm.hexagon.A2.tfrp" => "__builtin_HEXAGON_A2_tfrp", + "llvm.hexagon.A2.tfrpi" => "__builtin_HEXAGON_A2_tfrpi", + "llvm.hexagon.A2.tfrsi" => "__builtin_HEXAGON_A2_tfrsi", + "llvm.hexagon.A2.vabsh" => "__builtin_HEXAGON_A2_vabsh", + "llvm.hexagon.A2.vabshsat" => "__builtin_HEXAGON_A2_vabshsat", + "llvm.hexagon.A2.vabsw" => "__builtin_HEXAGON_A2_vabsw", + "llvm.hexagon.A2.vabswsat" => "__builtin_HEXAGON_A2_vabswsat", + "llvm.hexagon.A2.vaddb.map" => "__builtin_HEXAGON_A2_vaddb_map", + "llvm.hexagon.A2.vaddh" => "__builtin_HEXAGON_A2_vaddh", + "llvm.hexagon.A2.vaddhs" => "__builtin_HEXAGON_A2_vaddhs", + "llvm.hexagon.A2.vaddub" => "__builtin_HEXAGON_A2_vaddub", + "llvm.hexagon.A2.vaddubs" => "__builtin_HEXAGON_A2_vaddubs", + "llvm.hexagon.A2.vadduhs" => "__builtin_HEXAGON_A2_vadduhs", + "llvm.hexagon.A2.vaddw" => "__builtin_HEXAGON_A2_vaddw", + "llvm.hexagon.A2.vaddws" => "__builtin_HEXAGON_A2_vaddws", + "llvm.hexagon.A2.vavgh" => "__builtin_HEXAGON_A2_vavgh", + "llvm.hexagon.A2.vavghcr" => "__builtin_HEXAGON_A2_vavghcr", + "llvm.hexagon.A2.vavghr" => "__builtin_HEXAGON_A2_vavghr", + "llvm.hexagon.A2.vavgub" => "__builtin_HEXAGON_A2_vavgub", + "llvm.hexagon.A2.vavgubr" => "__builtin_HEXAGON_A2_vavgubr", + "llvm.hexagon.A2.vavguh" => "__builtin_HEXAGON_A2_vavguh", + "llvm.hexagon.A2.vavguhr" => "__builtin_HEXAGON_A2_vavguhr", + "llvm.hexagon.A2.vavguw" => "__builtin_HEXAGON_A2_vavguw", + "llvm.hexagon.A2.vavguwr" => "__builtin_HEXAGON_A2_vavguwr", + "llvm.hexagon.A2.vavgw" => "__builtin_HEXAGON_A2_vavgw", + "llvm.hexagon.A2.vavgwcr" => "__builtin_HEXAGON_A2_vavgwcr", + "llvm.hexagon.A2.vavgwr" => "__builtin_HEXAGON_A2_vavgwr", + "llvm.hexagon.A2.vcmpbeq" => "__builtin_HEXAGON_A2_vcmpbeq", + "llvm.hexagon.A2.vcmpbgtu" => "__builtin_HEXAGON_A2_vcmpbgtu", + "llvm.hexagon.A2.vcmpheq" => "__builtin_HEXAGON_A2_vcmpheq", + "llvm.hexagon.A2.vcmphgt" => "__builtin_HEXAGON_A2_vcmphgt", + "llvm.hexagon.A2.vcmphgtu" => "__builtin_HEXAGON_A2_vcmphgtu", + "llvm.hexagon.A2.vcmpweq" => "__builtin_HEXAGON_A2_vcmpweq", + "llvm.hexagon.A2.vcmpwgt" => "__builtin_HEXAGON_A2_vcmpwgt", + "llvm.hexagon.A2.vcmpwgtu" => "__builtin_HEXAGON_A2_vcmpwgtu", + "llvm.hexagon.A2.vconj" => "__builtin_HEXAGON_A2_vconj", + "llvm.hexagon.A2.vmaxb" => "__builtin_HEXAGON_A2_vmaxb", + "llvm.hexagon.A2.vmaxh" => "__builtin_HEXAGON_A2_vmaxh", + "llvm.hexagon.A2.vmaxub" => "__builtin_HEXAGON_A2_vmaxub", + "llvm.hexagon.A2.vmaxuh" => "__builtin_HEXAGON_A2_vmaxuh", + "llvm.hexagon.A2.vmaxuw" => "__builtin_HEXAGON_A2_vmaxuw", + "llvm.hexagon.A2.vmaxw" => "__builtin_HEXAGON_A2_vmaxw", + "llvm.hexagon.A2.vminb" => "__builtin_HEXAGON_A2_vminb", + "llvm.hexagon.A2.vminh" => "__builtin_HEXAGON_A2_vminh", + "llvm.hexagon.A2.vminub" => "__builtin_HEXAGON_A2_vminub", + "llvm.hexagon.A2.vminuh" => "__builtin_HEXAGON_A2_vminuh", + "llvm.hexagon.A2.vminuw" => "__builtin_HEXAGON_A2_vminuw", + "llvm.hexagon.A2.vminw" => "__builtin_HEXAGON_A2_vminw", + "llvm.hexagon.A2.vnavgh" => "__builtin_HEXAGON_A2_vnavgh", + "llvm.hexagon.A2.vnavghcr" => "__builtin_HEXAGON_A2_vnavghcr", + "llvm.hexagon.A2.vnavghr" => "__builtin_HEXAGON_A2_vnavghr", + "llvm.hexagon.A2.vnavgw" => "__builtin_HEXAGON_A2_vnavgw", + "llvm.hexagon.A2.vnavgwcr" => "__builtin_HEXAGON_A2_vnavgwcr", + "llvm.hexagon.A2.vnavgwr" => "__builtin_HEXAGON_A2_vnavgwr", + "llvm.hexagon.A2.vraddub" => "__builtin_HEXAGON_A2_vraddub", + "llvm.hexagon.A2.vraddub.acc" => "__builtin_HEXAGON_A2_vraddub_acc", + "llvm.hexagon.A2.vrsadub" => "__builtin_HEXAGON_A2_vrsadub", + "llvm.hexagon.A2.vrsadub.acc" => "__builtin_HEXAGON_A2_vrsadub_acc", + "llvm.hexagon.A2.vsubb.map" => "__builtin_HEXAGON_A2_vsubb_map", + "llvm.hexagon.A2.vsubh" => "__builtin_HEXAGON_A2_vsubh", + "llvm.hexagon.A2.vsubhs" => "__builtin_HEXAGON_A2_vsubhs", + "llvm.hexagon.A2.vsubub" => "__builtin_HEXAGON_A2_vsubub", + "llvm.hexagon.A2.vsububs" => "__builtin_HEXAGON_A2_vsububs", + "llvm.hexagon.A2.vsubuhs" => "__builtin_HEXAGON_A2_vsubuhs", + "llvm.hexagon.A2.vsubw" => "__builtin_HEXAGON_A2_vsubw", + "llvm.hexagon.A2.vsubws" => "__builtin_HEXAGON_A2_vsubws", + "llvm.hexagon.A2.xor" => "__builtin_HEXAGON_A2_xor", + "llvm.hexagon.A2.xorp" => "__builtin_HEXAGON_A2_xorp", + "llvm.hexagon.A2.zxtb" => "__builtin_HEXAGON_A2_zxtb", + "llvm.hexagon.A2.zxth" => "__builtin_HEXAGON_A2_zxth", + "llvm.hexagon.A4.andn" => "__builtin_HEXAGON_A4_andn", + "llvm.hexagon.A4.andnp" => "__builtin_HEXAGON_A4_andnp", + "llvm.hexagon.A4.bitsplit" => "__builtin_HEXAGON_A4_bitsplit", + "llvm.hexagon.A4.bitspliti" => "__builtin_HEXAGON_A4_bitspliti", + "llvm.hexagon.A4.boundscheck" => "__builtin_HEXAGON_A4_boundscheck", + "llvm.hexagon.A4.cmpbeq" => "__builtin_HEXAGON_A4_cmpbeq", + "llvm.hexagon.A4.cmpbeqi" => "__builtin_HEXAGON_A4_cmpbeqi", + "llvm.hexagon.A4.cmpbgt" => "__builtin_HEXAGON_A4_cmpbgt", + "llvm.hexagon.A4.cmpbgti" => "__builtin_HEXAGON_A4_cmpbgti", + "llvm.hexagon.A4.cmpbgtu" => "__builtin_HEXAGON_A4_cmpbgtu", + "llvm.hexagon.A4.cmpbgtui" => "__builtin_HEXAGON_A4_cmpbgtui", + "llvm.hexagon.A4.cmpheq" => "__builtin_HEXAGON_A4_cmpheq", + "llvm.hexagon.A4.cmpheqi" => "__builtin_HEXAGON_A4_cmpheqi", + "llvm.hexagon.A4.cmphgt" => "__builtin_HEXAGON_A4_cmphgt", + "llvm.hexagon.A4.cmphgti" => "__builtin_HEXAGON_A4_cmphgti", + "llvm.hexagon.A4.cmphgtu" => "__builtin_HEXAGON_A4_cmphgtu", + "llvm.hexagon.A4.cmphgtui" => "__builtin_HEXAGON_A4_cmphgtui", + "llvm.hexagon.A4.combineir" => "__builtin_HEXAGON_A4_combineir", + "llvm.hexagon.A4.combineri" => "__builtin_HEXAGON_A4_combineri", + "llvm.hexagon.A4.cround.ri" => "__builtin_HEXAGON_A4_cround_ri", + "llvm.hexagon.A4.cround.rr" => "__builtin_HEXAGON_A4_cround_rr", + "llvm.hexagon.A4.modwrapu" => "__builtin_HEXAGON_A4_modwrapu", + "llvm.hexagon.A4.orn" => "__builtin_HEXAGON_A4_orn", + "llvm.hexagon.A4.ornp" => "__builtin_HEXAGON_A4_ornp", + "llvm.hexagon.A4.rcmpeq" => "__builtin_HEXAGON_A4_rcmpeq", + "llvm.hexagon.A4.rcmpeqi" => "__builtin_HEXAGON_A4_rcmpeqi", + "llvm.hexagon.A4.rcmpneq" => "__builtin_HEXAGON_A4_rcmpneq", + "llvm.hexagon.A4.rcmpneqi" => "__builtin_HEXAGON_A4_rcmpneqi", + "llvm.hexagon.A4.round.ri" => "__builtin_HEXAGON_A4_round_ri", + "llvm.hexagon.A4.round.ri.sat" => "__builtin_HEXAGON_A4_round_ri_sat", + "llvm.hexagon.A4.round.rr" => "__builtin_HEXAGON_A4_round_rr", + "llvm.hexagon.A4.round.rr.sat" => "__builtin_HEXAGON_A4_round_rr_sat", + "llvm.hexagon.A4.tlbmatch" => "__builtin_HEXAGON_A4_tlbmatch", + "llvm.hexagon.A4.vcmpbeq.any" => "__builtin_HEXAGON_A4_vcmpbeq_any", + "llvm.hexagon.A4.vcmpbeqi" => "__builtin_HEXAGON_A4_vcmpbeqi", + "llvm.hexagon.A4.vcmpbgt" => "__builtin_HEXAGON_A4_vcmpbgt", + "llvm.hexagon.A4.vcmpbgti" => "__builtin_HEXAGON_A4_vcmpbgti", + "llvm.hexagon.A4.vcmpbgtui" => "__builtin_HEXAGON_A4_vcmpbgtui", + "llvm.hexagon.A4.vcmpheqi" => "__builtin_HEXAGON_A4_vcmpheqi", + "llvm.hexagon.A4.vcmphgti" => "__builtin_HEXAGON_A4_vcmphgti", + "llvm.hexagon.A4.vcmphgtui" => "__builtin_HEXAGON_A4_vcmphgtui", + "llvm.hexagon.A4.vcmpweqi" => "__builtin_HEXAGON_A4_vcmpweqi", + "llvm.hexagon.A4.vcmpwgti" => "__builtin_HEXAGON_A4_vcmpwgti", + "llvm.hexagon.A4.vcmpwgtui" => "__builtin_HEXAGON_A4_vcmpwgtui", + "llvm.hexagon.A4.vrmaxh" => "__builtin_HEXAGON_A4_vrmaxh", + "llvm.hexagon.A4.vrmaxuh" => "__builtin_HEXAGON_A4_vrmaxuh", + "llvm.hexagon.A4.vrmaxuw" => "__builtin_HEXAGON_A4_vrmaxuw", + "llvm.hexagon.A4.vrmaxw" => "__builtin_HEXAGON_A4_vrmaxw", + "llvm.hexagon.A4.vrminh" => "__builtin_HEXAGON_A4_vrminh", + "llvm.hexagon.A4.vrminuh" => "__builtin_HEXAGON_A4_vrminuh", + "llvm.hexagon.A4.vrminuw" => "__builtin_HEXAGON_A4_vrminuw", + "llvm.hexagon.A4.vrminw" => "__builtin_HEXAGON_A4_vrminw", + "llvm.hexagon.A5.vaddhubs" => "__builtin_HEXAGON_A5_vaddhubs", + "llvm.hexagon.C2.all8" => "__builtin_HEXAGON_C2_all8", + "llvm.hexagon.C2.and" => "__builtin_HEXAGON_C2_and", + "llvm.hexagon.C2.andn" => "__builtin_HEXAGON_C2_andn", + "llvm.hexagon.C2.any8" => "__builtin_HEXAGON_C2_any8", + "llvm.hexagon.C2.bitsclr" => "__builtin_HEXAGON_C2_bitsclr", + "llvm.hexagon.C2.bitsclri" => "__builtin_HEXAGON_C2_bitsclri", + "llvm.hexagon.C2.bitsset" => "__builtin_HEXAGON_C2_bitsset", + "llvm.hexagon.C2.cmpeq" => "__builtin_HEXAGON_C2_cmpeq", + "llvm.hexagon.C2.cmpeqi" => "__builtin_HEXAGON_C2_cmpeqi", + "llvm.hexagon.C2.cmpeqp" => "__builtin_HEXAGON_C2_cmpeqp", + "llvm.hexagon.C2.cmpgei" => "__builtin_HEXAGON_C2_cmpgei", + "llvm.hexagon.C2.cmpgeui" => "__builtin_HEXAGON_C2_cmpgeui", + "llvm.hexagon.C2.cmpgt" => "__builtin_HEXAGON_C2_cmpgt", + "llvm.hexagon.C2.cmpgti" => "__builtin_HEXAGON_C2_cmpgti", + "llvm.hexagon.C2.cmpgtp" => "__builtin_HEXAGON_C2_cmpgtp", + "llvm.hexagon.C2.cmpgtu" => "__builtin_HEXAGON_C2_cmpgtu", + "llvm.hexagon.C2.cmpgtui" => "__builtin_HEXAGON_C2_cmpgtui", + "llvm.hexagon.C2.cmpgtup" => "__builtin_HEXAGON_C2_cmpgtup", + "llvm.hexagon.C2.cmplt" => "__builtin_HEXAGON_C2_cmplt", + "llvm.hexagon.C2.cmpltu" => "__builtin_HEXAGON_C2_cmpltu", + "llvm.hexagon.C2.mask" => "__builtin_HEXAGON_C2_mask", + "llvm.hexagon.C2.mux" => "__builtin_HEXAGON_C2_mux", + "llvm.hexagon.C2.muxii" => "__builtin_HEXAGON_C2_muxii", + "llvm.hexagon.C2.muxir" => "__builtin_HEXAGON_C2_muxir", + "llvm.hexagon.C2.muxri" => "__builtin_HEXAGON_C2_muxri", + "llvm.hexagon.C2.not" => "__builtin_HEXAGON_C2_not", + "llvm.hexagon.C2.or" => "__builtin_HEXAGON_C2_or", + "llvm.hexagon.C2.orn" => "__builtin_HEXAGON_C2_orn", + "llvm.hexagon.C2.pxfer.map" => "__builtin_HEXAGON_C2_pxfer_map", + "llvm.hexagon.C2.tfrpr" => "__builtin_HEXAGON_C2_tfrpr", + "llvm.hexagon.C2.tfrrp" => "__builtin_HEXAGON_C2_tfrrp", + "llvm.hexagon.C2.vitpack" => "__builtin_HEXAGON_C2_vitpack", + "llvm.hexagon.C2.vmux" => "__builtin_HEXAGON_C2_vmux", + "llvm.hexagon.C2.xor" => "__builtin_HEXAGON_C2_xor", + "llvm.hexagon.C4.and.and" => "__builtin_HEXAGON_C4_and_and", + "llvm.hexagon.C4.and.andn" => "__builtin_HEXAGON_C4_and_andn", + "llvm.hexagon.C4.and.or" => "__builtin_HEXAGON_C4_and_or", + "llvm.hexagon.C4.and.orn" => "__builtin_HEXAGON_C4_and_orn", + "llvm.hexagon.C4.cmplte" => "__builtin_HEXAGON_C4_cmplte", + "llvm.hexagon.C4.cmpltei" => "__builtin_HEXAGON_C4_cmpltei", + "llvm.hexagon.C4.cmplteu" => "__builtin_HEXAGON_C4_cmplteu", + "llvm.hexagon.C4.cmplteui" => "__builtin_HEXAGON_C4_cmplteui", + "llvm.hexagon.C4.cmpneq" => "__builtin_HEXAGON_C4_cmpneq", + "llvm.hexagon.C4.cmpneqi" => "__builtin_HEXAGON_C4_cmpneqi", + "llvm.hexagon.C4.fastcorner9" => "__builtin_HEXAGON_C4_fastcorner9", + "llvm.hexagon.C4.fastcorner9.not" => "__builtin_HEXAGON_C4_fastcorner9_not", + "llvm.hexagon.C4.nbitsclr" => "__builtin_HEXAGON_C4_nbitsclr", + "llvm.hexagon.C4.nbitsclri" => "__builtin_HEXAGON_C4_nbitsclri", + "llvm.hexagon.C4.nbitsset" => "__builtin_HEXAGON_C4_nbitsset", + "llvm.hexagon.C4.or.and" => "__builtin_HEXAGON_C4_or_and", + "llvm.hexagon.C4.or.andn" => "__builtin_HEXAGON_C4_or_andn", + "llvm.hexagon.C4.or.or" => "__builtin_HEXAGON_C4_or_or", + "llvm.hexagon.C4.or.orn" => "__builtin_HEXAGON_C4_or_orn", + "llvm.hexagon.F2.conv.d2df" => "__builtin_HEXAGON_F2_conv_d2df", + "llvm.hexagon.F2.conv.d2sf" => "__builtin_HEXAGON_F2_conv_d2sf", + "llvm.hexagon.F2.conv.df2d" => "__builtin_HEXAGON_F2_conv_df2d", + "llvm.hexagon.F2.conv.df2d.chop" => "__builtin_HEXAGON_F2_conv_df2d_chop", + "llvm.hexagon.F2.conv.df2sf" => "__builtin_HEXAGON_F2_conv_df2sf", + "llvm.hexagon.F2.conv.df2ud" => "__builtin_HEXAGON_F2_conv_df2ud", + "llvm.hexagon.F2.conv.df2ud.chop" => "__builtin_HEXAGON_F2_conv_df2ud_chop", + "llvm.hexagon.F2.conv.df2uw" => "__builtin_HEXAGON_F2_conv_df2uw", + "llvm.hexagon.F2.conv.df2uw.chop" => "__builtin_HEXAGON_F2_conv_df2uw_chop", + "llvm.hexagon.F2.conv.df2w" => "__builtin_HEXAGON_F2_conv_df2w", + "llvm.hexagon.F2.conv.df2w.chop" => "__builtin_HEXAGON_F2_conv_df2w_chop", + "llvm.hexagon.F2.conv.sf2d" => "__builtin_HEXAGON_F2_conv_sf2d", + "llvm.hexagon.F2.conv.sf2d.chop" => "__builtin_HEXAGON_F2_conv_sf2d_chop", + "llvm.hexagon.F2.conv.sf2df" => "__builtin_HEXAGON_F2_conv_sf2df", + "llvm.hexagon.F2.conv.sf2ud" => "__builtin_HEXAGON_F2_conv_sf2ud", + "llvm.hexagon.F2.conv.sf2ud.chop" => "__builtin_HEXAGON_F2_conv_sf2ud_chop", + "llvm.hexagon.F2.conv.sf2uw" => "__builtin_HEXAGON_F2_conv_sf2uw", + "llvm.hexagon.F2.conv.sf2uw.chop" => "__builtin_HEXAGON_F2_conv_sf2uw_chop", + "llvm.hexagon.F2.conv.sf2w" => "__builtin_HEXAGON_F2_conv_sf2w", + "llvm.hexagon.F2.conv.sf2w.chop" => "__builtin_HEXAGON_F2_conv_sf2w_chop", + "llvm.hexagon.F2.conv.ud2df" => "__builtin_HEXAGON_F2_conv_ud2df", + "llvm.hexagon.F2.conv.ud2sf" => "__builtin_HEXAGON_F2_conv_ud2sf", + "llvm.hexagon.F2.conv.uw2df" => "__builtin_HEXAGON_F2_conv_uw2df", + "llvm.hexagon.F2.conv.uw2sf" => "__builtin_HEXAGON_F2_conv_uw2sf", + "llvm.hexagon.F2.conv.w2df" => "__builtin_HEXAGON_F2_conv_w2df", + "llvm.hexagon.F2.conv.w2sf" => "__builtin_HEXAGON_F2_conv_w2sf", + "llvm.hexagon.F2.dfadd" => "__builtin_HEXAGON_F2_dfadd", + "llvm.hexagon.F2.dfclass" => "__builtin_HEXAGON_F2_dfclass", + "llvm.hexagon.F2.dfcmpeq" => "__builtin_HEXAGON_F2_dfcmpeq", + "llvm.hexagon.F2.dfcmpge" => "__builtin_HEXAGON_F2_dfcmpge", + "llvm.hexagon.F2.dfcmpgt" => "__builtin_HEXAGON_F2_dfcmpgt", + "llvm.hexagon.F2.dfcmpuo" => "__builtin_HEXAGON_F2_dfcmpuo", + "llvm.hexagon.F2.dffixupd" => "__builtin_HEXAGON_F2_dffixupd", + "llvm.hexagon.F2.dffixupn" => "__builtin_HEXAGON_F2_dffixupn", + "llvm.hexagon.F2.dffixupr" => "__builtin_HEXAGON_F2_dffixupr", + "llvm.hexagon.F2.dffma" => "__builtin_HEXAGON_F2_dffma", + "llvm.hexagon.F2.dffma.lib" => "__builtin_HEXAGON_F2_dffma_lib", + "llvm.hexagon.F2.dffma.sc" => "__builtin_HEXAGON_F2_dffma_sc", + "llvm.hexagon.F2.dffms" => "__builtin_HEXAGON_F2_dffms", + "llvm.hexagon.F2.dffms.lib" => "__builtin_HEXAGON_F2_dffms_lib", + "llvm.hexagon.F2.dfimm.n" => "__builtin_HEXAGON_F2_dfimm_n", + "llvm.hexagon.F2.dfimm.p" => "__builtin_HEXAGON_F2_dfimm_p", + "llvm.hexagon.F2.dfmax" => "__builtin_HEXAGON_F2_dfmax", + "llvm.hexagon.F2.dfmin" => "__builtin_HEXAGON_F2_dfmin", + "llvm.hexagon.F2.dfmpy" => "__builtin_HEXAGON_F2_dfmpy", + "llvm.hexagon.F2.dfsub" => "__builtin_HEXAGON_F2_dfsub", + "llvm.hexagon.F2.sfadd" => "__builtin_HEXAGON_F2_sfadd", + "llvm.hexagon.F2.sfclass" => "__builtin_HEXAGON_F2_sfclass", + "llvm.hexagon.F2.sfcmpeq" => "__builtin_HEXAGON_F2_sfcmpeq", + "llvm.hexagon.F2.sfcmpge" => "__builtin_HEXAGON_F2_sfcmpge", + "llvm.hexagon.F2.sfcmpgt" => "__builtin_HEXAGON_F2_sfcmpgt", + "llvm.hexagon.F2.sfcmpuo" => "__builtin_HEXAGON_F2_sfcmpuo", + "llvm.hexagon.F2.sffixupd" => "__builtin_HEXAGON_F2_sffixupd", + "llvm.hexagon.F2.sffixupn" => "__builtin_HEXAGON_F2_sffixupn", + "llvm.hexagon.F2.sffixupr" => "__builtin_HEXAGON_F2_sffixupr", + "llvm.hexagon.F2.sffma" => "__builtin_HEXAGON_F2_sffma", + "llvm.hexagon.F2.sffma.lib" => "__builtin_HEXAGON_F2_sffma_lib", + "llvm.hexagon.F2.sffma.sc" => "__builtin_HEXAGON_F2_sffma_sc", + "llvm.hexagon.F2.sffms" => "__builtin_HEXAGON_F2_sffms", + "llvm.hexagon.F2.sffms.lib" => "__builtin_HEXAGON_F2_sffms_lib", + "llvm.hexagon.F2.sfimm.n" => "__builtin_HEXAGON_F2_sfimm_n", + "llvm.hexagon.F2.sfimm.p" => "__builtin_HEXAGON_F2_sfimm_p", + "llvm.hexagon.F2.sfmax" => "__builtin_HEXAGON_F2_sfmax", + "llvm.hexagon.F2.sfmin" => "__builtin_HEXAGON_F2_sfmin", + "llvm.hexagon.F2.sfmpy" => "__builtin_HEXAGON_F2_sfmpy", + "llvm.hexagon.F2.sfsub" => "__builtin_HEXAGON_F2_sfsub", + "llvm.hexagon.M2.acci" => "__builtin_HEXAGON_M2_acci", + "llvm.hexagon.M2.accii" => "__builtin_HEXAGON_M2_accii", + "llvm.hexagon.M2.cmaci.s0" => "__builtin_HEXAGON_M2_cmaci_s0", + "llvm.hexagon.M2.cmacr.s0" => "__builtin_HEXAGON_M2_cmacr_s0", + "llvm.hexagon.M2.cmacs.s0" => "__builtin_HEXAGON_M2_cmacs_s0", + "llvm.hexagon.M2.cmacs.s1" => "__builtin_HEXAGON_M2_cmacs_s1", + "llvm.hexagon.M2.cmacsc.s0" => "__builtin_HEXAGON_M2_cmacsc_s0", + "llvm.hexagon.M2.cmacsc.s1" => "__builtin_HEXAGON_M2_cmacsc_s1", + "llvm.hexagon.M2.cmpyi.s0" => "__builtin_HEXAGON_M2_cmpyi_s0", + "llvm.hexagon.M2.cmpyr.s0" => "__builtin_HEXAGON_M2_cmpyr_s0", + "llvm.hexagon.M2.cmpyrs.s0" => "__builtin_HEXAGON_M2_cmpyrs_s0", + "llvm.hexagon.M2.cmpyrs.s1" => "__builtin_HEXAGON_M2_cmpyrs_s1", + "llvm.hexagon.M2.cmpyrsc.s0" => "__builtin_HEXAGON_M2_cmpyrsc_s0", + "llvm.hexagon.M2.cmpyrsc.s1" => "__builtin_HEXAGON_M2_cmpyrsc_s1", + "llvm.hexagon.M2.cmpys.s0" => "__builtin_HEXAGON_M2_cmpys_s0", + "llvm.hexagon.M2.cmpys.s1" => "__builtin_HEXAGON_M2_cmpys_s1", + "llvm.hexagon.M2.cmpysc.s0" => "__builtin_HEXAGON_M2_cmpysc_s0", + "llvm.hexagon.M2.cmpysc.s1" => "__builtin_HEXAGON_M2_cmpysc_s1", + "llvm.hexagon.M2.cnacs.s0" => "__builtin_HEXAGON_M2_cnacs_s0", + "llvm.hexagon.M2.cnacs.s1" => "__builtin_HEXAGON_M2_cnacs_s1", + "llvm.hexagon.M2.cnacsc.s0" => "__builtin_HEXAGON_M2_cnacsc_s0", + "llvm.hexagon.M2.cnacsc.s1" => "__builtin_HEXAGON_M2_cnacsc_s1", + "llvm.hexagon.M2.dpmpyss.acc.s0" => "__builtin_HEXAGON_M2_dpmpyss_acc_s0", + "llvm.hexagon.M2.dpmpyss.nac.s0" => "__builtin_HEXAGON_M2_dpmpyss_nac_s0", + "llvm.hexagon.M2.dpmpyss.rnd.s0" => "__builtin_HEXAGON_M2_dpmpyss_rnd_s0", + "llvm.hexagon.M2.dpmpyss.s0" => "__builtin_HEXAGON_M2_dpmpyss_s0", + "llvm.hexagon.M2.dpmpyuu.acc.s0" => "__builtin_HEXAGON_M2_dpmpyuu_acc_s0", + "llvm.hexagon.M2.dpmpyuu.nac.s0" => "__builtin_HEXAGON_M2_dpmpyuu_nac_s0", + "llvm.hexagon.M2.dpmpyuu.s0" => "__builtin_HEXAGON_M2_dpmpyuu_s0", + "llvm.hexagon.M2.hmmpyh.rs1" => "__builtin_HEXAGON_M2_hmmpyh_rs1", + "llvm.hexagon.M2.hmmpyh.s1" => "__builtin_HEXAGON_M2_hmmpyh_s1", + "llvm.hexagon.M2.hmmpyl.rs1" => "__builtin_HEXAGON_M2_hmmpyl_rs1", + "llvm.hexagon.M2.hmmpyl.s1" => "__builtin_HEXAGON_M2_hmmpyl_s1", + "llvm.hexagon.M2.maci" => "__builtin_HEXAGON_M2_maci", + "llvm.hexagon.M2.macsin" => "__builtin_HEXAGON_M2_macsin", + "llvm.hexagon.M2.macsip" => "__builtin_HEXAGON_M2_macsip", + "llvm.hexagon.M2.mmachs.rs0" => "__builtin_HEXAGON_M2_mmachs_rs0", + "llvm.hexagon.M2.mmachs.rs1" => "__builtin_HEXAGON_M2_mmachs_rs1", + "llvm.hexagon.M2.mmachs.s0" => "__builtin_HEXAGON_M2_mmachs_s0", + "llvm.hexagon.M2.mmachs.s1" => "__builtin_HEXAGON_M2_mmachs_s1", + "llvm.hexagon.M2.mmacls.rs0" => "__builtin_HEXAGON_M2_mmacls_rs0", + "llvm.hexagon.M2.mmacls.rs1" => "__builtin_HEXAGON_M2_mmacls_rs1", + "llvm.hexagon.M2.mmacls.s0" => "__builtin_HEXAGON_M2_mmacls_s0", + "llvm.hexagon.M2.mmacls.s1" => "__builtin_HEXAGON_M2_mmacls_s1", + "llvm.hexagon.M2.mmacuhs.rs0" => "__builtin_HEXAGON_M2_mmacuhs_rs0", + "llvm.hexagon.M2.mmacuhs.rs1" => "__builtin_HEXAGON_M2_mmacuhs_rs1", + "llvm.hexagon.M2.mmacuhs.s0" => "__builtin_HEXAGON_M2_mmacuhs_s0", + "llvm.hexagon.M2.mmacuhs.s1" => "__builtin_HEXAGON_M2_mmacuhs_s1", + "llvm.hexagon.M2.mmaculs.rs0" => "__builtin_HEXAGON_M2_mmaculs_rs0", + "llvm.hexagon.M2.mmaculs.rs1" => "__builtin_HEXAGON_M2_mmaculs_rs1", + "llvm.hexagon.M2.mmaculs.s0" => "__builtin_HEXAGON_M2_mmaculs_s0", + "llvm.hexagon.M2.mmaculs.s1" => "__builtin_HEXAGON_M2_mmaculs_s1", + "llvm.hexagon.M2.mmpyh.rs0" => "__builtin_HEXAGON_M2_mmpyh_rs0", + "llvm.hexagon.M2.mmpyh.rs1" => "__builtin_HEXAGON_M2_mmpyh_rs1", + "llvm.hexagon.M2.mmpyh.s0" => "__builtin_HEXAGON_M2_mmpyh_s0", + "llvm.hexagon.M2.mmpyh.s1" => "__builtin_HEXAGON_M2_mmpyh_s1", + "llvm.hexagon.M2.mmpyl.rs0" => "__builtin_HEXAGON_M2_mmpyl_rs0", + "llvm.hexagon.M2.mmpyl.rs1" => "__builtin_HEXAGON_M2_mmpyl_rs1", + "llvm.hexagon.M2.mmpyl.s0" => "__builtin_HEXAGON_M2_mmpyl_s0", + "llvm.hexagon.M2.mmpyl.s1" => "__builtin_HEXAGON_M2_mmpyl_s1", + "llvm.hexagon.M2.mmpyuh.rs0" => "__builtin_HEXAGON_M2_mmpyuh_rs0", + "llvm.hexagon.M2.mmpyuh.rs1" => "__builtin_HEXAGON_M2_mmpyuh_rs1", + "llvm.hexagon.M2.mmpyuh.s0" => "__builtin_HEXAGON_M2_mmpyuh_s0", + "llvm.hexagon.M2.mmpyuh.s1" => "__builtin_HEXAGON_M2_mmpyuh_s1", + "llvm.hexagon.M2.mmpyul.rs0" => "__builtin_HEXAGON_M2_mmpyul_rs0", + "llvm.hexagon.M2.mmpyul.rs1" => "__builtin_HEXAGON_M2_mmpyul_rs1", + "llvm.hexagon.M2.mmpyul.s0" => "__builtin_HEXAGON_M2_mmpyul_s0", + "llvm.hexagon.M2.mmpyul.s1" => "__builtin_HEXAGON_M2_mmpyul_s1", + "llvm.hexagon.M2.mpy.acc.hh.s0" => "__builtin_HEXAGON_M2_mpy_acc_hh_s0", + "llvm.hexagon.M2.mpy.acc.hh.s1" => "__builtin_HEXAGON_M2_mpy_acc_hh_s1", + "llvm.hexagon.M2.mpy.acc.hl.s0" => "__builtin_HEXAGON_M2_mpy_acc_hl_s0", + "llvm.hexagon.M2.mpy.acc.hl.s1" => "__builtin_HEXAGON_M2_mpy_acc_hl_s1", + "llvm.hexagon.M2.mpy.acc.lh.s0" => "__builtin_HEXAGON_M2_mpy_acc_lh_s0", + "llvm.hexagon.M2.mpy.acc.lh.s1" => "__builtin_HEXAGON_M2_mpy_acc_lh_s1", + "llvm.hexagon.M2.mpy.acc.ll.s0" => "__builtin_HEXAGON_M2_mpy_acc_ll_s0", + "llvm.hexagon.M2.mpy.acc.ll.s1" => "__builtin_HEXAGON_M2_mpy_acc_ll_s1", + "llvm.hexagon.M2.mpy.acc.sat.hh.s0" => "__builtin_HEXAGON_M2_mpy_acc_sat_hh_s0", + "llvm.hexagon.M2.mpy.acc.sat.hh.s1" => "__builtin_HEXAGON_M2_mpy_acc_sat_hh_s1", + "llvm.hexagon.M2.mpy.acc.sat.hl.s0" => "__builtin_HEXAGON_M2_mpy_acc_sat_hl_s0", + "llvm.hexagon.M2.mpy.acc.sat.hl.s1" => "__builtin_HEXAGON_M2_mpy_acc_sat_hl_s1", + "llvm.hexagon.M2.mpy.acc.sat.lh.s0" => "__builtin_HEXAGON_M2_mpy_acc_sat_lh_s0", + "llvm.hexagon.M2.mpy.acc.sat.lh.s1" => "__builtin_HEXAGON_M2_mpy_acc_sat_lh_s1", + "llvm.hexagon.M2.mpy.acc.sat.ll.s0" => "__builtin_HEXAGON_M2_mpy_acc_sat_ll_s0", + "llvm.hexagon.M2.mpy.acc.sat.ll.s1" => "__builtin_HEXAGON_M2_mpy_acc_sat_ll_s1", + "llvm.hexagon.M2.mpy.hh.s0" => "__builtin_HEXAGON_M2_mpy_hh_s0", + "llvm.hexagon.M2.mpy.hh.s1" => "__builtin_HEXAGON_M2_mpy_hh_s1", + "llvm.hexagon.M2.mpy.hl.s0" => "__builtin_HEXAGON_M2_mpy_hl_s0", + "llvm.hexagon.M2.mpy.hl.s1" => "__builtin_HEXAGON_M2_mpy_hl_s1", + "llvm.hexagon.M2.mpy.lh.s0" => "__builtin_HEXAGON_M2_mpy_lh_s0", + "llvm.hexagon.M2.mpy.lh.s1" => "__builtin_HEXAGON_M2_mpy_lh_s1", + "llvm.hexagon.M2.mpy.ll.s0" => "__builtin_HEXAGON_M2_mpy_ll_s0", + "llvm.hexagon.M2.mpy.ll.s1" => "__builtin_HEXAGON_M2_mpy_ll_s1", + "llvm.hexagon.M2.mpy.nac.hh.s0" => "__builtin_HEXAGON_M2_mpy_nac_hh_s0", + "llvm.hexagon.M2.mpy.nac.hh.s1" => "__builtin_HEXAGON_M2_mpy_nac_hh_s1", + "llvm.hexagon.M2.mpy.nac.hl.s0" => "__builtin_HEXAGON_M2_mpy_nac_hl_s0", + "llvm.hexagon.M2.mpy.nac.hl.s1" => "__builtin_HEXAGON_M2_mpy_nac_hl_s1", + "llvm.hexagon.M2.mpy.nac.lh.s0" => "__builtin_HEXAGON_M2_mpy_nac_lh_s0", + "llvm.hexagon.M2.mpy.nac.lh.s1" => "__builtin_HEXAGON_M2_mpy_nac_lh_s1", + "llvm.hexagon.M2.mpy.nac.ll.s0" => "__builtin_HEXAGON_M2_mpy_nac_ll_s0", + "llvm.hexagon.M2.mpy.nac.ll.s1" => "__builtin_HEXAGON_M2_mpy_nac_ll_s1", + "llvm.hexagon.M2.mpy.nac.sat.hh.s0" => "__builtin_HEXAGON_M2_mpy_nac_sat_hh_s0", + "llvm.hexagon.M2.mpy.nac.sat.hh.s1" => "__builtin_HEXAGON_M2_mpy_nac_sat_hh_s1", + "llvm.hexagon.M2.mpy.nac.sat.hl.s0" => "__builtin_HEXAGON_M2_mpy_nac_sat_hl_s0", + "llvm.hexagon.M2.mpy.nac.sat.hl.s1" => "__builtin_HEXAGON_M2_mpy_nac_sat_hl_s1", + "llvm.hexagon.M2.mpy.nac.sat.lh.s0" => "__builtin_HEXAGON_M2_mpy_nac_sat_lh_s0", + "llvm.hexagon.M2.mpy.nac.sat.lh.s1" => "__builtin_HEXAGON_M2_mpy_nac_sat_lh_s1", + "llvm.hexagon.M2.mpy.nac.sat.ll.s0" => "__builtin_HEXAGON_M2_mpy_nac_sat_ll_s0", + "llvm.hexagon.M2.mpy.nac.sat.ll.s1" => "__builtin_HEXAGON_M2_mpy_nac_sat_ll_s1", + "llvm.hexagon.M2.mpy.rnd.hh.s0" => "__builtin_HEXAGON_M2_mpy_rnd_hh_s0", + "llvm.hexagon.M2.mpy.rnd.hh.s1" => "__builtin_HEXAGON_M2_mpy_rnd_hh_s1", + "llvm.hexagon.M2.mpy.rnd.hl.s0" => "__builtin_HEXAGON_M2_mpy_rnd_hl_s0", + "llvm.hexagon.M2.mpy.rnd.hl.s1" => "__builtin_HEXAGON_M2_mpy_rnd_hl_s1", + "llvm.hexagon.M2.mpy.rnd.lh.s0" => "__builtin_HEXAGON_M2_mpy_rnd_lh_s0", + "llvm.hexagon.M2.mpy.rnd.lh.s1" => "__builtin_HEXAGON_M2_mpy_rnd_lh_s1", + "llvm.hexagon.M2.mpy.rnd.ll.s0" => "__builtin_HEXAGON_M2_mpy_rnd_ll_s0", + "llvm.hexagon.M2.mpy.rnd.ll.s1" => "__builtin_HEXAGON_M2_mpy_rnd_ll_s1", + "llvm.hexagon.M2.mpy.sat.hh.s0" => "__builtin_HEXAGON_M2_mpy_sat_hh_s0", + "llvm.hexagon.M2.mpy.sat.hh.s1" => "__builtin_HEXAGON_M2_mpy_sat_hh_s1", + "llvm.hexagon.M2.mpy.sat.hl.s0" => "__builtin_HEXAGON_M2_mpy_sat_hl_s0", + "llvm.hexagon.M2.mpy.sat.hl.s1" => "__builtin_HEXAGON_M2_mpy_sat_hl_s1", + "llvm.hexagon.M2.mpy.sat.lh.s0" => "__builtin_HEXAGON_M2_mpy_sat_lh_s0", + "llvm.hexagon.M2.mpy.sat.lh.s1" => "__builtin_HEXAGON_M2_mpy_sat_lh_s1", + "llvm.hexagon.M2.mpy.sat.ll.s0" => "__builtin_HEXAGON_M2_mpy_sat_ll_s0", + "llvm.hexagon.M2.mpy.sat.ll.s1" => "__builtin_HEXAGON_M2_mpy_sat_ll_s1", + "llvm.hexagon.M2.mpy.sat.rnd.hh.s0" => "__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0", + "llvm.hexagon.M2.mpy.sat.rnd.hh.s1" => "__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1", + "llvm.hexagon.M2.mpy.sat.rnd.hl.s0" => "__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0", + "llvm.hexagon.M2.mpy.sat.rnd.hl.s1" => "__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1", + "llvm.hexagon.M2.mpy.sat.rnd.lh.s0" => "__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0", + "llvm.hexagon.M2.mpy.sat.rnd.lh.s1" => "__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1", + "llvm.hexagon.M2.mpy.sat.rnd.ll.s0" => "__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0", + "llvm.hexagon.M2.mpy.sat.rnd.ll.s1" => "__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1", + "llvm.hexagon.M2.mpy.up" => "__builtin_HEXAGON_M2_mpy_up", + "llvm.hexagon.M2.mpy.up.s1" => "__builtin_HEXAGON_M2_mpy_up_s1", + "llvm.hexagon.M2.mpy.up.s1.sat" => "__builtin_HEXAGON_M2_mpy_up_s1_sat", + "llvm.hexagon.M2.mpyd.acc.hh.s0" => "__builtin_HEXAGON_M2_mpyd_acc_hh_s0", + "llvm.hexagon.M2.mpyd.acc.hh.s1" => "__builtin_HEXAGON_M2_mpyd_acc_hh_s1", + "llvm.hexagon.M2.mpyd.acc.hl.s0" => "__builtin_HEXAGON_M2_mpyd_acc_hl_s0", + "llvm.hexagon.M2.mpyd.acc.hl.s1" => "__builtin_HEXAGON_M2_mpyd_acc_hl_s1", + "llvm.hexagon.M2.mpyd.acc.lh.s0" => "__builtin_HEXAGON_M2_mpyd_acc_lh_s0", + "llvm.hexagon.M2.mpyd.acc.lh.s1" => "__builtin_HEXAGON_M2_mpyd_acc_lh_s1", + "llvm.hexagon.M2.mpyd.acc.ll.s0" => "__builtin_HEXAGON_M2_mpyd_acc_ll_s0", + "llvm.hexagon.M2.mpyd.acc.ll.s1" => "__builtin_HEXAGON_M2_mpyd_acc_ll_s1", + "llvm.hexagon.M2.mpyd.hh.s0" => "__builtin_HEXAGON_M2_mpyd_hh_s0", + "llvm.hexagon.M2.mpyd.hh.s1" => "__builtin_HEXAGON_M2_mpyd_hh_s1", + "llvm.hexagon.M2.mpyd.hl.s0" => "__builtin_HEXAGON_M2_mpyd_hl_s0", + "llvm.hexagon.M2.mpyd.hl.s1" => "__builtin_HEXAGON_M2_mpyd_hl_s1", + "llvm.hexagon.M2.mpyd.lh.s0" => "__builtin_HEXAGON_M2_mpyd_lh_s0", + "llvm.hexagon.M2.mpyd.lh.s1" => "__builtin_HEXAGON_M2_mpyd_lh_s1", + "llvm.hexagon.M2.mpyd.ll.s0" => "__builtin_HEXAGON_M2_mpyd_ll_s0", + "llvm.hexagon.M2.mpyd.ll.s1" => "__builtin_HEXAGON_M2_mpyd_ll_s1", + "llvm.hexagon.M2.mpyd.nac.hh.s0" => "__builtin_HEXAGON_M2_mpyd_nac_hh_s0", + "llvm.hexagon.M2.mpyd.nac.hh.s1" => "__builtin_HEXAGON_M2_mpyd_nac_hh_s1", + "llvm.hexagon.M2.mpyd.nac.hl.s0" => "__builtin_HEXAGON_M2_mpyd_nac_hl_s0", + "llvm.hexagon.M2.mpyd.nac.hl.s1" => "__builtin_HEXAGON_M2_mpyd_nac_hl_s1", + "llvm.hexagon.M2.mpyd.nac.lh.s0" => "__builtin_HEXAGON_M2_mpyd_nac_lh_s0", + "llvm.hexagon.M2.mpyd.nac.lh.s1" => "__builtin_HEXAGON_M2_mpyd_nac_lh_s1", + "llvm.hexagon.M2.mpyd.nac.ll.s0" => "__builtin_HEXAGON_M2_mpyd_nac_ll_s0", + "llvm.hexagon.M2.mpyd.nac.ll.s1" => "__builtin_HEXAGON_M2_mpyd_nac_ll_s1", + "llvm.hexagon.M2.mpyd.rnd.hh.s0" => "__builtin_HEXAGON_M2_mpyd_rnd_hh_s0", + "llvm.hexagon.M2.mpyd.rnd.hh.s1" => "__builtin_HEXAGON_M2_mpyd_rnd_hh_s1", + "llvm.hexagon.M2.mpyd.rnd.hl.s0" => "__builtin_HEXAGON_M2_mpyd_rnd_hl_s0", + "llvm.hexagon.M2.mpyd.rnd.hl.s1" => "__builtin_HEXAGON_M2_mpyd_rnd_hl_s1", + "llvm.hexagon.M2.mpyd.rnd.lh.s0" => "__builtin_HEXAGON_M2_mpyd_rnd_lh_s0", + "llvm.hexagon.M2.mpyd.rnd.lh.s1" => "__builtin_HEXAGON_M2_mpyd_rnd_lh_s1", + "llvm.hexagon.M2.mpyd.rnd.ll.s0" => "__builtin_HEXAGON_M2_mpyd_rnd_ll_s0", + "llvm.hexagon.M2.mpyd.rnd.ll.s1" => "__builtin_HEXAGON_M2_mpyd_rnd_ll_s1", + "llvm.hexagon.M2.mpyi" => "__builtin_HEXAGON_M2_mpyi", + "llvm.hexagon.M2.mpysmi" => "__builtin_HEXAGON_M2_mpysmi", + "llvm.hexagon.M2.mpysu.up" => "__builtin_HEXAGON_M2_mpysu_up", + "llvm.hexagon.M2.mpyu.acc.hh.s0" => "__builtin_HEXAGON_M2_mpyu_acc_hh_s0", + "llvm.hexagon.M2.mpyu.acc.hh.s1" => "__builtin_HEXAGON_M2_mpyu_acc_hh_s1", + "llvm.hexagon.M2.mpyu.acc.hl.s0" => "__builtin_HEXAGON_M2_mpyu_acc_hl_s0", + "llvm.hexagon.M2.mpyu.acc.hl.s1" => "__builtin_HEXAGON_M2_mpyu_acc_hl_s1", + "llvm.hexagon.M2.mpyu.acc.lh.s0" => "__builtin_HEXAGON_M2_mpyu_acc_lh_s0", + "llvm.hexagon.M2.mpyu.acc.lh.s1" => "__builtin_HEXAGON_M2_mpyu_acc_lh_s1", + "llvm.hexagon.M2.mpyu.acc.ll.s0" => "__builtin_HEXAGON_M2_mpyu_acc_ll_s0", + "llvm.hexagon.M2.mpyu.acc.ll.s1" => "__builtin_HEXAGON_M2_mpyu_acc_ll_s1", + "llvm.hexagon.M2.mpyu.hh.s0" => "__builtin_HEXAGON_M2_mpyu_hh_s0", + "llvm.hexagon.M2.mpyu.hh.s1" => "__builtin_HEXAGON_M2_mpyu_hh_s1", + "llvm.hexagon.M2.mpyu.hl.s0" => "__builtin_HEXAGON_M2_mpyu_hl_s0", + "llvm.hexagon.M2.mpyu.hl.s1" => "__builtin_HEXAGON_M2_mpyu_hl_s1", + "llvm.hexagon.M2.mpyu.lh.s0" => "__builtin_HEXAGON_M2_mpyu_lh_s0", + "llvm.hexagon.M2.mpyu.lh.s1" => "__builtin_HEXAGON_M2_mpyu_lh_s1", + "llvm.hexagon.M2.mpyu.ll.s0" => "__builtin_HEXAGON_M2_mpyu_ll_s0", + "llvm.hexagon.M2.mpyu.ll.s1" => "__builtin_HEXAGON_M2_mpyu_ll_s1", + "llvm.hexagon.M2.mpyu.nac.hh.s0" => "__builtin_HEXAGON_M2_mpyu_nac_hh_s0", + "llvm.hexagon.M2.mpyu.nac.hh.s1" => "__builtin_HEXAGON_M2_mpyu_nac_hh_s1", + "llvm.hexagon.M2.mpyu.nac.hl.s0" => "__builtin_HEXAGON_M2_mpyu_nac_hl_s0", + "llvm.hexagon.M2.mpyu.nac.hl.s1" => "__builtin_HEXAGON_M2_mpyu_nac_hl_s1", + "llvm.hexagon.M2.mpyu.nac.lh.s0" => "__builtin_HEXAGON_M2_mpyu_nac_lh_s0", + "llvm.hexagon.M2.mpyu.nac.lh.s1" => "__builtin_HEXAGON_M2_mpyu_nac_lh_s1", + "llvm.hexagon.M2.mpyu.nac.ll.s0" => "__builtin_HEXAGON_M2_mpyu_nac_ll_s0", + "llvm.hexagon.M2.mpyu.nac.ll.s1" => "__builtin_HEXAGON_M2_mpyu_nac_ll_s1", + "llvm.hexagon.M2.mpyu.up" => "__builtin_HEXAGON_M2_mpyu_up", + "llvm.hexagon.M2.mpyud.acc.hh.s0" => "__builtin_HEXAGON_M2_mpyud_acc_hh_s0", + "llvm.hexagon.M2.mpyud.acc.hh.s1" => "__builtin_HEXAGON_M2_mpyud_acc_hh_s1", + "llvm.hexagon.M2.mpyud.acc.hl.s0" => "__builtin_HEXAGON_M2_mpyud_acc_hl_s0", + "llvm.hexagon.M2.mpyud.acc.hl.s1" => "__builtin_HEXAGON_M2_mpyud_acc_hl_s1", + "llvm.hexagon.M2.mpyud.acc.lh.s0" => "__builtin_HEXAGON_M2_mpyud_acc_lh_s0", + "llvm.hexagon.M2.mpyud.acc.lh.s1" => "__builtin_HEXAGON_M2_mpyud_acc_lh_s1", + "llvm.hexagon.M2.mpyud.acc.ll.s0" => "__builtin_HEXAGON_M2_mpyud_acc_ll_s0", + "llvm.hexagon.M2.mpyud.acc.ll.s1" => "__builtin_HEXAGON_M2_mpyud_acc_ll_s1", + "llvm.hexagon.M2.mpyud.hh.s0" => "__builtin_HEXAGON_M2_mpyud_hh_s0", + "llvm.hexagon.M2.mpyud.hh.s1" => "__builtin_HEXAGON_M2_mpyud_hh_s1", + "llvm.hexagon.M2.mpyud.hl.s0" => "__builtin_HEXAGON_M2_mpyud_hl_s0", + "llvm.hexagon.M2.mpyud.hl.s1" => "__builtin_HEXAGON_M2_mpyud_hl_s1", + "llvm.hexagon.M2.mpyud.lh.s0" => "__builtin_HEXAGON_M2_mpyud_lh_s0", + "llvm.hexagon.M2.mpyud.lh.s1" => "__builtin_HEXAGON_M2_mpyud_lh_s1", + "llvm.hexagon.M2.mpyud.ll.s0" => "__builtin_HEXAGON_M2_mpyud_ll_s0", + "llvm.hexagon.M2.mpyud.ll.s1" => "__builtin_HEXAGON_M2_mpyud_ll_s1", + "llvm.hexagon.M2.mpyud.nac.hh.s0" => "__builtin_HEXAGON_M2_mpyud_nac_hh_s0", + "llvm.hexagon.M2.mpyud.nac.hh.s1" => "__builtin_HEXAGON_M2_mpyud_nac_hh_s1", + "llvm.hexagon.M2.mpyud.nac.hl.s0" => "__builtin_HEXAGON_M2_mpyud_nac_hl_s0", + "llvm.hexagon.M2.mpyud.nac.hl.s1" => "__builtin_HEXAGON_M2_mpyud_nac_hl_s1", + "llvm.hexagon.M2.mpyud.nac.lh.s0" => "__builtin_HEXAGON_M2_mpyud_nac_lh_s0", + "llvm.hexagon.M2.mpyud.nac.lh.s1" => "__builtin_HEXAGON_M2_mpyud_nac_lh_s1", + "llvm.hexagon.M2.mpyud.nac.ll.s0" => "__builtin_HEXAGON_M2_mpyud_nac_ll_s0", + "llvm.hexagon.M2.mpyud.nac.ll.s1" => "__builtin_HEXAGON_M2_mpyud_nac_ll_s1", + "llvm.hexagon.M2.mpyui" => "__builtin_HEXAGON_M2_mpyui", + "llvm.hexagon.M2.nacci" => "__builtin_HEXAGON_M2_nacci", + "llvm.hexagon.M2.naccii" => "__builtin_HEXAGON_M2_naccii", + "llvm.hexagon.M2.subacc" => "__builtin_HEXAGON_M2_subacc", + "llvm.hexagon.M2.vabsdiffh" => "__builtin_HEXAGON_M2_vabsdiffh", + "llvm.hexagon.M2.vabsdiffw" => "__builtin_HEXAGON_M2_vabsdiffw", + "llvm.hexagon.M2.vcmac.s0.sat.i" => "__builtin_HEXAGON_M2_vcmac_s0_sat_i", + "llvm.hexagon.M2.vcmac.s0.sat.r" => "__builtin_HEXAGON_M2_vcmac_s0_sat_r", + "llvm.hexagon.M2.vcmpy.s0.sat.i" => "__builtin_HEXAGON_M2_vcmpy_s0_sat_i", + "llvm.hexagon.M2.vcmpy.s0.sat.r" => "__builtin_HEXAGON_M2_vcmpy_s0_sat_r", + "llvm.hexagon.M2.vcmpy.s1.sat.i" => "__builtin_HEXAGON_M2_vcmpy_s1_sat_i", + "llvm.hexagon.M2.vcmpy.s1.sat.r" => "__builtin_HEXAGON_M2_vcmpy_s1_sat_r", + "llvm.hexagon.M2.vdmacs.s0" => "__builtin_HEXAGON_M2_vdmacs_s0", + "llvm.hexagon.M2.vdmacs.s1" => "__builtin_HEXAGON_M2_vdmacs_s1", + "llvm.hexagon.M2.vdmpyrs.s0" => "__builtin_HEXAGON_M2_vdmpyrs_s0", + "llvm.hexagon.M2.vdmpyrs.s1" => "__builtin_HEXAGON_M2_vdmpyrs_s1", + "llvm.hexagon.M2.vdmpys.s0" => "__builtin_HEXAGON_M2_vdmpys_s0", + "llvm.hexagon.M2.vdmpys.s1" => "__builtin_HEXAGON_M2_vdmpys_s1", + "llvm.hexagon.M2.vmac2" => "__builtin_HEXAGON_M2_vmac2", + "llvm.hexagon.M2.vmac2es" => "__builtin_HEXAGON_M2_vmac2es", + "llvm.hexagon.M2.vmac2es.s0" => "__builtin_HEXAGON_M2_vmac2es_s0", + "llvm.hexagon.M2.vmac2es.s1" => "__builtin_HEXAGON_M2_vmac2es_s1", + "llvm.hexagon.M2.vmac2s.s0" => "__builtin_HEXAGON_M2_vmac2s_s0", + "llvm.hexagon.M2.vmac2s.s1" => "__builtin_HEXAGON_M2_vmac2s_s1", + "llvm.hexagon.M2.vmac2su.s0" => "__builtin_HEXAGON_M2_vmac2su_s0", + "llvm.hexagon.M2.vmac2su.s1" => "__builtin_HEXAGON_M2_vmac2su_s1", + "llvm.hexagon.M2.vmpy2es.s0" => "__builtin_HEXAGON_M2_vmpy2es_s0", + "llvm.hexagon.M2.vmpy2es.s1" => "__builtin_HEXAGON_M2_vmpy2es_s1", + "llvm.hexagon.M2.vmpy2s.s0" => "__builtin_HEXAGON_M2_vmpy2s_s0", + "llvm.hexagon.M2.vmpy2s.s0pack" => "__builtin_HEXAGON_M2_vmpy2s_s0pack", + "llvm.hexagon.M2.vmpy2s.s1" => "__builtin_HEXAGON_M2_vmpy2s_s1", + "llvm.hexagon.M2.vmpy2s.s1pack" => "__builtin_HEXAGON_M2_vmpy2s_s1pack", + "llvm.hexagon.M2.vmpy2su.s0" => "__builtin_HEXAGON_M2_vmpy2su_s0", + "llvm.hexagon.M2.vmpy2su.s1" => "__builtin_HEXAGON_M2_vmpy2su_s1", + "llvm.hexagon.M2.vraddh" => "__builtin_HEXAGON_M2_vraddh", + "llvm.hexagon.M2.vradduh" => "__builtin_HEXAGON_M2_vradduh", + "llvm.hexagon.M2.vrcmaci.s0" => "__builtin_HEXAGON_M2_vrcmaci_s0", + "llvm.hexagon.M2.vrcmaci.s0c" => "__builtin_HEXAGON_M2_vrcmaci_s0c", + "llvm.hexagon.M2.vrcmacr.s0" => "__builtin_HEXAGON_M2_vrcmacr_s0", + "llvm.hexagon.M2.vrcmacr.s0c" => "__builtin_HEXAGON_M2_vrcmacr_s0c", + "llvm.hexagon.M2.vrcmpyi.s0" => "__builtin_HEXAGON_M2_vrcmpyi_s0", + "llvm.hexagon.M2.vrcmpyi.s0c" => "__builtin_HEXAGON_M2_vrcmpyi_s0c", + "llvm.hexagon.M2.vrcmpyr.s0" => "__builtin_HEXAGON_M2_vrcmpyr_s0", + "llvm.hexagon.M2.vrcmpyr.s0c" => "__builtin_HEXAGON_M2_vrcmpyr_s0c", + "llvm.hexagon.M2.vrcmpys.acc.s1" => "__builtin_HEXAGON_M2_vrcmpys_acc_s1", + "llvm.hexagon.M2.vrcmpys.s1" => "__builtin_HEXAGON_M2_vrcmpys_s1", + "llvm.hexagon.M2.vrcmpys.s1rp" => "__builtin_HEXAGON_M2_vrcmpys_s1rp", + "llvm.hexagon.M2.vrmac.s0" => "__builtin_HEXAGON_M2_vrmac_s0", + "llvm.hexagon.M2.vrmpy.s0" => "__builtin_HEXAGON_M2_vrmpy_s0", + "llvm.hexagon.M2.xor.xacc" => "__builtin_HEXAGON_M2_xor_xacc", + "llvm.hexagon.M4.and.and" => "__builtin_HEXAGON_M4_and_and", + "llvm.hexagon.M4.and.andn" => "__builtin_HEXAGON_M4_and_andn", + "llvm.hexagon.M4.and.or" => "__builtin_HEXAGON_M4_and_or", + "llvm.hexagon.M4.and.xor" => "__builtin_HEXAGON_M4_and_xor", + "llvm.hexagon.M4.cmpyi.wh" => "__builtin_HEXAGON_M4_cmpyi_wh", + "llvm.hexagon.M4.cmpyi.whc" => "__builtin_HEXAGON_M4_cmpyi_whc", + "llvm.hexagon.M4.cmpyr.wh" => "__builtin_HEXAGON_M4_cmpyr_wh", + "llvm.hexagon.M4.cmpyr.whc" => "__builtin_HEXAGON_M4_cmpyr_whc", + "llvm.hexagon.M4.mac.up.s1.sat" => "__builtin_HEXAGON_M4_mac_up_s1_sat", + "llvm.hexagon.M4.mpyri.addi" => "__builtin_HEXAGON_M4_mpyri_addi", + "llvm.hexagon.M4.mpyri.addr" => "__builtin_HEXAGON_M4_mpyri_addr", + "llvm.hexagon.M4.mpyri.addr.u2" => "__builtin_HEXAGON_M4_mpyri_addr_u2", + "llvm.hexagon.M4.mpyrr.addi" => "__builtin_HEXAGON_M4_mpyrr_addi", + "llvm.hexagon.M4.mpyrr.addr" => "__builtin_HEXAGON_M4_mpyrr_addr", + "llvm.hexagon.M4.nac.up.s1.sat" => "__builtin_HEXAGON_M4_nac_up_s1_sat", + "llvm.hexagon.M4.or.and" => "__builtin_HEXAGON_M4_or_and", + "llvm.hexagon.M4.or.andn" => "__builtin_HEXAGON_M4_or_andn", + "llvm.hexagon.M4.or.or" => "__builtin_HEXAGON_M4_or_or", + "llvm.hexagon.M4.or.xor" => "__builtin_HEXAGON_M4_or_xor", + "llvm.hexagon.M4.pmpyw" => "__builtin_HEXAGON_M4_pmpyw", + "llvm.hexagon.M4.pmpyw.acc" => "__builtin_HEXAGON_M4_pmpyw_acc", + "llvm.hexagon.M4.vpmpyh" => "__builtin_HEXAGON_M4_vpmpyh", + "llvm.hexagon.M4.vpmpyh.acc" => "__builtin_HEXAGON_M4_vpmpyh_acc", + "llvm.hexagon.M4.vrmpyeh.acc.s0" => "__builtin_HEXAGON_M4_vrmpyeh_acc_s0", + "llvm.hexagon.M4.vrmpyeh.acc.s1" => "__builtin_HEXAGON_M4_vrmpyeh_acc_s1", + "llvm.hexagon.M4.vrmpyeh.s0" => "__builtin_HEXAGON_M4_vrmpyeh_s0", + "llvm.hexagon.M4.vrmpyeh.s1" => "__builtin_HEXAGON_M4_vrmpyeh_s1", + "llvm.hexagon.M4.vrmpyoh.acc.s0" => "__builtin_HEXAGON_M4_vrmpyoh_acc_s0", + "llvm.hexagon.M4.vrmpyoh.acc.s1" => "__builtin_HEXAGON_M4_vrmpyoh_acc_s1", + "llvm.hexagon.M4.vrmpyoh.s0" => "__builtin_HEXAGON_M4_vrmpyoh_s0", + "llvm.hexagon.M4.vrmpyoh.s1" => "__builtin_HEXAGON_M4_vrmpyoh_s1", + "llvm.hexagon.M4.xor.and" => "__builtin_HEXAGON_M4_xor_and", + "llvm.hexagon.M4.xor.andn" => "__builtin_HEXAGON_M4_xor_andn", + "llvm.hexagon.M4.xor.or" => "__builtin_HEXAGON_M4_xor_or", + "llvm.hexagon.M4.xor.xacc" => "__builtin_HEXAGON_M4_xor_xacc", + "llvm.hexagon.M5.vdmacbsu" => "__builtin_HEXAGON_M5_vdmacbsu", + "llvm.hexagon.M5.vdmpybsu" => "__builtin_HEXAGON_M5_vdmpybsu", + "llvm.hexagon.M5.vmacbsu" => "__builtin_HEXAGON_M5_vmacbsu", + "llvm.hexagon.M5.vmacbuu" => "__builtin_HEXAGON_M5_vmacbuu", + "llvm.hexagon.M5.vmpybsu" => "__builtin_HEXAGON_M5_vmpybsu", + "llvm.hexagon.M5.vmpybuu" => "__builtin_HEXAGON_M5_vmpybuu", + "llvm.hexagon.M5.vrmacbsu" => "__builtin_HEXAGON_M5_vrmacbsu", + "llvm.hexagon.M5.vrmacbuu" => "__builtin_HEXAGON_M5_vrmacbuu", + "llvm.hexagon.M5.vrmpybsu" => "__builtin_HEXAGON_M5_vrmpybsu", + "llvm.hexagon.M5.vrmpybuu" => "__builtin_HEXAGON_M5_vrmpybuu", + "llvm.hexagon.M6.vabsdiffb" => "__builtin_HEXAGON_M6_vabsdiffb", + "llvm.hexagon.M6.vabsdiffub" => "__builtin_HEXAGON_M6_vabsdiffub", + "llvm.hexagon.S2.addasl.rrri" => "__builtin_HEXAGON_S2_addasl_rrri", + "llvm.hexagon.S2.asl.i.p" => "__builtin_HEXAGON_S2_asl_i_p", + "llvm.hexagon.S2.asl.i.p.acc" => "__builtin_HEXAGON_S2_asl_i_p_acc", + "llvm.hexagon.S2.asl.i.p.and" => "__builtin_HEXAGON_S2_asl_i_p_and", + "llvm.hexagon.S2.asl.i.p.nac" => "__builtin_HEXAGON_S2_asl_i_p_nac", + "llvm.hexagon.S2.asl.i.p.or" => "__builtin_HEXAGON_S2_asl_i_p_or", + "llvm.hexagon.S2.asl.i.p.xacc" => "__builtin_HEXAGON_S2_asl_i_p_xacc", + "llvm.hexagon.S2.asl.i.r" => "__builtin_HEXAGON_S2_asl_i_r", + "llvm.hexagon.S2.asl.i.r.acc" => "__builtin_HEXAGON_S2_asl_i_r_acc", + "llvm.hexagon.S2.asl.i.r.and" => "__builtin_HEXAGON_S2_asl_i_r_and", + "llvm.hexagon.S2.asl.i.r.nac" => "__builtin_HEXAGON_S2_asl_i_r_nac", + "llvm.hexagon.S2.asl.i.r.or" => "__builtin_HEXAGON_S2_asl_i_r_or", + "llvm.hexagon.S2.asl.i.r.sat" => "__builtin_HEXAGON_S2_asl_i_r_sat", + "llvm.hexagon.S2.asl.i.r.xacc" => "__builtin_HEXAGON_S2_asl_i_r_xacc", + "llvm.hexagon.S2.asl.i.vh" => "__builtin_HEXAGON_S2_asl_i_vh", + "llvm.hexagon.S2.asl.i.vw" => "__builtin_HEXAGON_S2_asl_i_vw", + "llvm.hexagon.S2.asl.r.p" => "__builtin_HEXAGON_S2_asl_r_p", + "llvm.hexagon.S2.asl.r.p.acc" => "__builtin_HEXAGON_S2_asl_r_p_acc", + "llvm.hexagon.S2.asl.r.p.and" => "__builtin_HEXAGON_S2_asl_r_p_and", + "llvm.hexagon.S2.asl.r.p.nac" => "__builtin_HEXAGON_S2_asl_r_p_nac", + "llvm.hexagon.S2.asl.r.p.or" => "__builtin_HEXAGON_S2_asl_r_p_or", + "llvm.hexagon.S2.asl.r.p.xor" => "__builtin_HEXAGON_S2_asl_r_p_xor", + "llvm.hexagon.S2.asl.r.r" => "__builtin_HEXAGON_S2_asl_r_r", + "llvm.hexagon.S2.asl.r.r.acc" => "__builtin_HEXAGON_S2_asl_r_r_acc", + "llvm.hexagon.S2.asl.r.r.and" => "__builtin_HEXAGON_S2_asl_r_r_and", + "llvm.hexagon.S2.asl.r.r.nac" => "__builtin_HEXAGON_S2_asl_r_r_nac", + "llvm.hexagon.S2.asl.r.r.or" => "__builtin_HEXAGON_S2_asl_r_r_or", + "llvm.hexagon.S2.asl.r.r.sat" => "__builtin_HEXAGON_S2_asl_r_r_sat", + "llvm.hexagon.S2.asl.r.vh" => "__builtin_HEXAGON_S2_asl_r_vh", + "llvm.hexagon.S2.asl.r.vw" => "__builtin_HEXAGON_S2_asl_r_vw", + "llvm.hexagon.S2.asr.i.p" => "__builtin_HEXAGON_S2_asr_i_p", + "llvm.hexagon.S2.asr.i.p.acc" => "__builtin_HEXAGON_S2_asr_i_p_acc", + "llvm.hexagon.S2.asr.i.p.and" => "__builtin_HEXAGON_S2_asr_i_p_and", + "llvm.hexagon.S2.asr.i.p.nac" => "__builtin_HEXAGON_S2_asr_i_p_nac", + "llvm.hexagon.S2.asr.i.p.or" => "__builtin_HEXAGON_S2_asr_i_p_or", + "llvm.hexagon.S2.asr.i.p.rnd" => "__builtin_HEXAGON_S2_asr_i_p_rnd", + "llvm.hexagon.S2.asr.i.p.rnd.goodsyntax" => "__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax", + "llvm.hexagon.S2.asr.i.r" => "__builtin_HEXAGON_S2_asr_i_r", + "llvm.hexagon.S2.asr.i.r.acc" => "__builtin_HEXAGON_S2_asr_i_r_acc", + "llvm.hexagon.S2.asr.i.r.and" => "__builtin_HEXAGON_S2_asr_i_r_and", + "llvm.hexagon.S2.asr.i.r.nac" => "__builtin_HEXAGON_S2_asr_i_r_nac", + "llvm.hexagon.S2.asr.i.r.or" => "__builtin_HEXAGON_S2_asr_i_r_or", + "llvm.hexagon.S2.asr.i.r.rnd" => "__builtin_HEXAGON_S2_asr_i_r_rnd", + "llvm.hexagon.S2.asr.i.r.rnd.goodsyntax" => "__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax", + "llvm.hexagon.S2.asr.i.svw.trun" => "__builtin_HEXAGON_S2_asr_i_svw_trun", + "llvm.hexagon.S2.asr.i.vh" => "__builtin_HEXAGON_S2_asr_i_vh", + "llvm.hexagon.S2.asr.i.vw" => "__builtin_HEXAGON_S2_asr_i_vw", + "llvm.hexagon.S2.asr.r.p" => "__builtin_HEXAGON_S2_asr_r_p", + "llvm.hexagon.S2.asr.r.p.acc" => "__builtin_HEXAGON_S2_asr_r_p_acc", + "llvm.hexagon.S2.asr.r.p.and" => "__builtin_HEXAGON_S2_asr_r_p_and", + "llvm.hexagon.S2.asr.r.p.nac" => "__builtin_HEXAGON_S2_asr_r_p_nac", + "llvm.hexagon.S2.asr.r.p.or" => "__builtin_HEXAGON_S2_asr_r_p_or", + "llvm.hexagon.S2.asr.r.p.xor" => "__builtin_HEXAGON_S2_asr_r_p_xor", + "llvm.hexagon.S2.asr.r.r" => "__builtin_HEXAGON_S2_asr_r_r", + "llvm.hexagon.S2.asr.r.r.acc" => "__builtin_HEXAGON_S2_asr_r_r_acc", + "llvm.hexagon.S2.asr.r.r.and" => "__builtin_HEXAGON_S2_asr_r_r_and", + "llvm.hexagon.S2.asr.r.r.nac" => "__builtin_HEXAGON_S2_asr_r_r_nac", + "llvm.hexagon.S2.asr.r.r.or" => "__builtin_HEXAGON_S2_asr_r_r_or", + "llvm.hexagon.S2.asr.r.r.sat" => "__builtin_HEXAGON_S2_asr_r_r_sat", + "llvm.hexagon.S2.asr.r.svw.trun" => "__builtin_HEXAGON_S2_asr_r_svw_trun", + "llvm.hexagon.S2.asr.r.vh" => "__builtin_HEXAGON_S2_asr_r_vh", + "llvm.hexagon.S2.asr.r.vw" => "__builtin_HEXAGON_S2_asr_r_vw", + "llvm.hexagon.S2.brev" => "__builtin_HEXAGON_S2_brev", + "llvm.hexagon.S2.brevp" => "__builtin_HEXAGON_S2_brevp", + "llvm.hexagon.S2.cabacencbin" => "__builtin_HEXAGON_S2_cabacencbin", + "llvm.hexagon.S2.cl0" => "__builtin_HEXAGON_S2_cl0", + "llvm.hexagon.S2.cl0p" => "__builtin_HEXAGON_S2_cl0p", + "llvm.hexagon.S2.cl1" => "__builtin_HEXAGON_S2_cl1", + "llvm.hexagon.S2.cl1p" => "__builtin_HEXAGON_S2_cl1p", + "llvm.hexagon.S2.clb" => "__builtin_HEXAGON_S2_clb", + "llvm.hexagon.S2.clbnorm" => "__builtin_HEXAGON_S2_clbnorm", + "llvm.hexagon.S2.clbp" => "__builtin_HEXAGON_S2_clbp", + "llvm.hexagon.S2.clrbit.i" => "__builtin_HEXAGON_S2_clrbit_i", + "llvm.hexagon.S2.clrbit.r" => "__builtin_HEXAGON_S2_clrbit_r", + "llvm.hexagon.S2.ct0" => "__builtin_HEXAGON_S2_ct0", + "llvm.hexagon.S2.ct0p" => "__builtin_HEXAGON_S2_ct0p", + "llvm.hexagon.S2.ct1" => "__builtin_HEXAGON_S2_ct1", + "llvm.hexagon.S2.ct1p" => "__builtin_HEXAGON_S2_ct1p", + "llvm.hexagon.S2.deinterleave" => "__builtin_HEXAGON_S2_deinterleave", + "llvm.hexagon.S2.extractu" => "__builtin_HEXAGON_S2_extractu", + "llvm.hexagon.S2.extractu.rp" => "__builtin_HEXAGON_S2_extractu_rp", + "llvm.hexagon.S2.extractup" => "__builtin_HEXAGON_S2_extractup", + "llvm.hexagon.S2.extractup.rp" => "__builtin_HEXAGON_S2_extractup_rp", + "llvm.hexagon.S2.insert" => "__builtin_HEXAGON_S2_insert", + "llvm.hexagon.S2.insert.rp" => "__builtin_HEXAGON_S2_insert_rp", + "llvm.hexagon.S2.insertp" => "__builtin_HEXAGON_S2_insertp", + "llvm.hexagon.S2.insertp.rp" => "__builtin_HEXAGON_S2_insertp_rp", + "llvm.hexagon.S2.interleave" => "__builtin_HEXAGON_S2_interleave", + "llvm.hexagon.S2.lfsp" => "__builtin_HEXAGON_S2_lfsp", + "llvm.hexagon.S2.lsl.r.p" => "__builtin_HEXAGON_S2_lsl_r_p", + "llvm.hexagon.S2.lsl.r.p.acc" => "__builtin_HEXAGON_S2_lsl_r_p_acc", + "llvm.hexagon.S2.lsl.r.p.and" => "__builtin_HEXAGON_S2_lsl_r_p_and", + "llvm.hexagon.S2.lsl.r.p.nac" => "__builtin_HEXAGON_S2_lsl_r_p_nac", + "llvm.hexagon.S2.lsl.r.p.or" => "__builtin_HEXAGON_S2_lsl_r_p_or", + "llvm.hexagon.S2.lsl.r.p.xor" => "__builtin_HEXAGON_S2_lsl_r_p_xor", + "llvm.hexagon.S2.lsl.r.r" => "__builtin_HEXAGON_S2_lsl_r_r", + "llvm.hexagon.S2.lsl.r.r.acc" => "__builtin_HEXAGON_S2_lsl_r_r_acc", + "llvm.hexagon.S2.lsl.r.r.and" => "__builtin_HEXAGON_S2_lsl_r_r_and", + "llvm.hexagon.S2.lsl.r.r.nac" => "__builtin_HEXAGON_S2_lsl_r_r_nac", + "llvm.hexagon.S2.lsl.r.r.or" => "__builtin_HEXAGON_S2_lsl_r_r_or", + "llvm.hexagon.S2.lsl.r.vh" => "__builtin_HEXAGON_S2_lsl_r_vh", + "llvm.hexagon.S2.lsl.r.vw" => "__builtin_HEXAGON_S2_lsl_r_vw", + "llvm.hexagon.S2.lsr.i.p" => "__builtin_HEXAGON_S2_lsr_i_p", + "llvm.hexagon.S2.lsr.i.p.acc" => "__builtin_HEXAGON_S2_lsr_i_p_acc", + "llvm.hexagon.S2.lsr.i.p.and" => "__builtin_HEXAGON_S2_lsr_i_p_and", + "llvm.hexagon.S2.lsr.i.p.nac" => "__builtin_HEXAGON_S2_lsr_i_p_nac", + "llvm.hexagon.S2.lsr.i.p.or" => "__builtin_HEXAGON_S2_lsr_i_p_or", + "llvm.hexagon.S2.lsr.i.p.xacc" => "__builtin_HEXAGON_S2_lsr_i_p_xacc", + "llvm.hexagon.S2.lsr.i.r" => "__builtin_HEXAGON_S2_lsr_i_r", + "llvm.hexagon.S2.lsr.i.r.acc" => "__builtin_HEXAGON_S2_lsr_i_r_acc", + "llvm.hexagon.S2.lsr.i.r.and" => "__builtin_HEXAGON_S2_lsr_i_r_and", + "llvm.hexagon.S2.lsr.i.r.nac" => "__builtin_HEXAGON_S2_lsr_i_r_nac", + "llvm.hexagon.S2.lsr.i.r.or" => "__builtin_HEXAGON_S2_lsr_i_r_or", + "llvm.hexagon.S2.lsr.i.r.xacc" => "__builtin_HEXAGON_S2_lsr_i_r_xacc", + "llvm.hexagon.S2.lsr.i.vh" => "__builtin_HEXAGON_S2_lsr_i_vh", + "llvm.hexagon.S2.lsr.i.vw" => "__builtin_HEXAGON_S2_lsr_i_vw", + "llvm.hexagon.S2.lsr.r.p" => "__builtin_HEXAGON_S2_lsr_r_p", + "llvm.hexagon.S2.lsr.r.p.acc" => "__builtin_HEXAGON_S2_lsr_r_p_acc", + "llvm.hexagon.S2.lsr.r.p.and" => "__builtin_HEXAGON_S2_lsr_r_p_and", + "llvm.hexagon.S2.lsr.r.p.nac" => "__builtin_HEXAGON_S2_lsr_r_p_nac", + "llvm.hexagon.S2.lsr.r.p.or" => "__builtin_HEXAGON_S2_lsr_r_p_or", + "llvm.hexagon.S2.lsr.r.p.xor" => "__builtin_HEXAGON_S2_lsr_r_p_xor", + "llvm.hexagon.S2.lsr.r.r" => "__builtin_HEXAGON_S2_lsr_r_r", + "llvm.hexagon.S2.lsr.r.r.acc" => "__builtin_HEXAGON_S2_lsr_r_r_acc", + "llvm.hexagon.S2.lsr.r.r.and" => "__builtin_HEXAGON_S2_lsr_r_r_and", + "llvm.hexagon.S2.lsr.r.r.nac" => "__builtin_HEXAGON_S2_lsr_r_r_nac", + "llvm.hexagon.S2.lsr.r.r.or" => "__builtin_HEXAGON_S2_lsr_r_r_or", + "llvm.hexagon.S2.lsr.r.vh" => "__builtin_HEXAGON_S2_lsr_r_vh", + "llvm.hexagon.S2.lsr.r.vw" => "__builtin_HEXAGON_S2_lsr_r_vw", + "llvm.hexagon.S2.packhl" => "__builtin_HEXAGON_S2_packhl", + "llvm.hexagon.S2.parityp" => "__builtin_HEXAGON_S2_parityp", + "llvm.hexagon.S2.setbit.i" => "__builtin_HEXAGON_S2_setbit_i", + "llvm.hexagon.S2.setbit.r" => "__builtin_HEXAGON_S2_setbit_r", + "llvm.hexagon.S2.shuffeb" => "__builtin_HEXAGON_S2_shuffeb", + "llvm.hexagon.S2.shuffeh" => "__builtin_HEXAGON_S2_shuffeh", + "llvm.hexagon.S2.shuffob" => "__builtin_HEXAGON_S2_shuffob", + "llvm.hexagon.S2.shuffoh" => "__builtin_HEXAGON_S2_shuffoh", + "llvm.hexagon.S2.svsathb" => "__builtin_HEXAGON_S2_svsathb", + "llvm.hexagon.S2.svsathub" => "__builtin_HEXAGON_S2_svsathub", + "llvm.hexagon.S2.tableidxb.goodsyntax" => "__builtin_HEXAGON_S2_tableidxb_goodsyntax", + "llvm.hexagon.S2.tableidxd.goodsyntax" => "__builtin_HEXAGON_S2_tableidxd_goodsyntax", + "llvm.hexagon.S2.tableidxh.goodsyntax" => "__builtin_HEXAGON_S2_tableidxh_goodsyntax", + "llvm.hexagon.S2.tableidxw.goodsyntax" => "__builtin_HEXAGON_S2_tableidxw_goodsyntax", + "llvm.hexagon.S2.togglebit.i" => "__builtin_HEXAGON_S2_togglebit_i", + "llvm.hexagon.S2.togglebit.r" => "__builtin_HEXAGON_S2_togglebit_r", + "llvm.hexagon.S2.tstbit.i" => "__builtin_HEXAGON_S2_tstbit_i", + "llvm.hexagon.S2.tstbit.r" => "__builtin_HEXAGON_S2_tstbit_r", + "llvm.hexagon.S2.valignib" => "__builtin_HEXAGON_S2_valignib", + "llvm.hexagon.S2.valignrb" => "__builtin_HEXAGON_S2_valignrb", + "llvm.hexagon.S2.vcnegh" => "__builtin_HEXAGON_S2_vcnegh", + "llvm.hexagon.S2.vcrotate" => "__builtin_HEXAGON_S2_vcrotate", + "llvm.hexagon.S2.vrcnegh" => "__builtin_HEXAGON_S2_vrcnegh", + "llvm.hexagon.S2.vrndpackwh" => "__builtin_HEXAGON_S2_vrndpackwh", + "llvm.hexagon.S2.vrndpackwhs" => "__builtin_HEXAGON_S2_vrndpackwhs", + "llvm.hexagon.S2.vsathb" => "__builtin_HEXAGON_S2_vsathb", + "llvm.hexagon.S2.vsathb.nopack" => "__builtin_HEXAGON_S2_vsathb_nopack", + "llvm.hexagon.S2.vsathub" => "__builtin_HEXAGON_S2_vsathub", + "llvm.hexagon.S2.vsathub.nopack" => "__builtin_HEXAGON_S2_vsathub_nopack", + "llvm.hexagon.S2.vsatwh" => "__builtin_HEXAGON_S2_vsatwh", + "llvm.hexagon.S2.vsatwh.nopack" => "__builtin_HEXAGON_S2_vsatwh_nopack", + "llvm.hexagon.S2.vsatwuh" => "__builtin_HEXAGON_S2_vsatwuh", + "llvm.hexagon.S2.vsatwuh.nopack" => "__builtin_HEXAGON_S2_vsatwuh_nopack", + "llvm.hexagon.S2.vsplatrb" => "__builtin_HEXAGON_S2_vsplatrb", + "llvm.hexagon.S2.vsplatrh" => "__builtin_HEXAGON_S2_vsplatrh", + "llvm.hexagon.S2.vspliceib" => "__builtin_HEXAGON_S2_vspliceib", + "llvm.hexagon.S2.vsplicerb" => "__builtin_HEXAGON_S2_vsplicerb", + "llvm.hexagon.S2.vsxtbh" => "__builtin_HEXAGON_S2_vsxtbh", + "llvm.hexagon.S2.vsxthw" => "__builtin_HEXAGON_S2_vsxthw", + "llvm.hexagon.S2.vtrunehb" => "__builtin_HEXAGON_S2_vtrunehb", + "llvm.hexagon.S2.vtrunewh" => "__builtin_HEXAGON_S2_vtrunewh", + "llvm.hexagon.S2.vtrunohb" => "__builtin_HEXAGON_S2_vtrunohb", + "llvm.hexagon.S2.vtrunowh" => "__builtin_HEXAGON_S2_vtrunowh", + "llvm.hexagon.S2.vzxtbh" => "__builtin_HEXAGON_S2_vzxtbh", + "llvm.hexagon.S2.vzxthw" => "__builtin_HEXAGON_S2_vzxthw", + "llvm.hexagon.S4.addaddi" => "__builtin_HEXAGON_S4_addaddi", + "llvm.hexagon.S4.addi.asl.ri" => "__builtin_HEXAGON_S4_addi_asl_ri", + "llvm.hexagon.S4.addi.lsr.ri" => "__builtin_HEXAGON_S4_addi_lsr_ri", + "llvm.hexagon.S4.andi.asl.ri" => "__builtin_HEXAGON_S4_andi_asl_ri", + "llvm.hexagon.S4.andi.lsr.ri" => "__builtin_HEXAGON_S4_andi_lsr_ri", + "llvm.hexagon.S4.clbaddi" => "__builtin_HEXAGON_S4_clbaddi", + "llvm.hexagon.S4.clbpaddi" => "__builtin_HEXAGON_S4_clbpaddi", + "llvm.hexagon.S4.clbpnorm" => "__builtin_HEXAGON_S4_clbpnorm", + "llvm.hexagon.S4.extract" => "__builtin_HEXAGON_S4_extract", + "llvm.hexagon.S4.extract.rp" => "__builtin_HEXAGON_S4_extract_rp", + "llvm.hexagon.S4.extractp" => "__builtin_HEXAGON_S4_extractp", + "llvm.hexagon.S4.extractp.rp" => "__builtin_HEXAGON_S4_extractp_rp", + "llvm.hexagon.S4.lsli" => "__builtin_HEXAGON_S4_lsli", + "llvm.hexagon.S4.ntstbit.i" => "__builtin_HEXAGON_S4_ntstbit_i", + "llvm.hexagon.S4.ntstbit.r" => "__builtin_HEXAGON_S4_ntstbit_r", + "llvm.hexagon.S4.or.andi" => "__builtin_HEXAGON_S4_or_andi", + "llvm.hexagon.S4.or.andix" => "__builtin_HEXAGON_S4_or_andix", + "llvm.hexagon.S4.or.ori" => "__builtin_HEXAGON_S4_or_ori", + "llvm.hexagon.S4.ori.asl.ri" => "__builtin_HEXAGON_S4_ori_asl_ri", + "llvm.hexagon.S4.ori.lsr.ri" => "__builtin_HEXAGON_S4_ori_lsr_ri", + "llvm.hexagon.S4.parity" => "__builtin_HEXAGON_S4_parity", + "llvm.hexagon.S4.subaddi" => "__builtin_HEXAGON_S4_subaddi", + "llvm.hexagon.S4.subi.asl.ri" => "__builtin_HEXAGON_S4_subi_asl_ri", + "llvm.hexagon.S4.subi.lsr.ri" => "__builtin_HEXAGON_S4_subi_lsr_ri", + "llvm.hexagon.S4.vrcrotate" => "__builtin_HEXAGON_S4_vrcrotate", + "llvm.hexagon.S4.vrcrotate.acc" => "__builtin_HEXAGON_S4_vrcrotate_acc", + "llvm.hexagon.S4.vxaddsubh" => "__builtin_HEXAGON_S4_vxaddsubh", + "llvm.hexagon.S4.vxaddsubhr" => "__builtin_HEXAGON_S4_vxaddsubhr", + "llvm.hexagon.S4.vxaddsubw" => "__builtin_HEXAGON_S4_vxaddsubw", + "llvm.hexagon.S4.vxsubaddh" => "__builtin_HEXAGON_S4_vxsubaddh", + "llvm.hexagon.S4.vxsubaddhr" => "__builtin_HEXAGON_S4_vxsubaddhr", + "llvm.hexagon.S4.vxsubaddw" => "__builtin_HEXAGON_S4_vxsubaddw", + "llvm.hexagon.S5.asrhub.rnd.sat.goodsyntax" => "__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax", + "llvm.hexagon.S5.asrhub.sat" => "__builtin_HEXAGON_S5_asrhub_sat", + "llvm.hexagon.S5.popcountp" => "__builtin_HEXAGON_S5_popcountp", + "llvm.hexagon.S5.vasrhrnd.goodsyntax" => "__builtin_HEXAGON_S5_vasrhrnd_goodsyntax", + "llvm.hexagon.S6.rol.i.p" => "__builtin_HEXAGON_S6_rol_i_p", + "llvm.hexagon.S6.rol.i.p.acc" => "__builtin_HEXAGON_S6_rol_i_p_acc", + "llvm.hexagon.S6.rol.i.p.and" => "__builtin_HEXAGON_S6_rol_i_p_and", + "llvm.hexagon.S6.rol.i.p.nac" => "__builtin_HEXAGON_S6_rol_i_p_nac", + "llvm.hexagon.S6.rol.i.p.or" => "__builtin_HEXAGON_S6_rol_i_p_or", + "llvm.hexagon.S6.rol.i.p.xacc" => "__builtin_HEXAGON_S6_rol_i_p_xacc", + "llvm.hexagon.S6.rol.i.r" => "__builtin_HEXAGON_S6_rol_i_r", + "llvm.hexagon.S6.rol.i.r.acc" => "__builtin_HEXAGON_S6_rol_i_r_acc", + "llvm.hexagon.S6.rol.i.r.and" => "__builtin_HEXAGON_S6_rol_i_r_and", + "llvm.hexagon.S6.rol.i.r.nac" => "__builtin_HEXAGON_S6_rol_i_r_nac", + "llvm.hexagon.S6.rol.i.r.or" => "__builtin_HEXAGON_S6_rol_i_r_or", + "llvm.hexagon.S6.rol.i.r.xacc" => "__builtin_HEXAGON_S6_rol_i_r_xacc", + "llvm.hexagon.S6.vsplatrbp" => "__builtin_HEXAGON_S6_vsplatrbp", + "llvm.hexagon.S6.vtrunehb.ppp" => "__builtin_HEXAGON_S6_vtrunehb_ppp", + "llvm.hexagon.S6.vtrunohb.ppp" => "__builtin_HEXAGON_S6_vtrunohb_ppp", + "llvm.hexagon.SI.to.SXTHI.asrh" => "__builtin_SI_to_SXTHI_asrh", + "llvm.hexagon.V6.extractw" => "__builtin_HEXAGON_V6_extractw", + "llvm.hexagon.V6.extractw.128B" => "__builtin_HEXAGON_V6_extractw_128B", + "llvm.hexagon.V6.hi" => "__builtin_HEXAGON_V6_hi", + "llvm.hexagon.V6.hi.128B" => "__builtin_HEXAGON_V6_hi_128B", + "llvm.hexagon.V6.lo" => "__builtin_HEXAGON_V6_lo", + "llvm.hexagon.V6.lo.128B" => "__builtin_HEXAGON_V6_lo_128B", + "llvm.hexagon.V6.lvsplatw" => "__builtin_HEXAGON_V6_lvsplatw", + "llvm.hexagon.V6.lvsplatw.128B" => "__builtin_HEXAGON_V6_lvsplatw_128B", + "llvm.hexagon.V6.vabsdiffh" => "__builtin_HEXAGON_V6_vabsdiffh", + "llvm.hexagon.V6.vabsdiffh.128B" => "__builtin_HEXAGON_V6_vabsdiffh_128B", + "llvm.hexagon.V6.vabsdiffub" => "__builtin_HEXAGON_V6_vabsdiffub", + "llvm.hexagon.V6.vabsdiffub.128B" => "__builtin_HEXAGON_V6_vabsdiffub_128B", + "llvm.hexagon.V6.vabsdiffuh" => "__builtin_HEXAGON_V6_vabsdiffuh", + "llvm.hexagon.V6.vabsdiffuh.128B" => "__builtin_HEXAGON_V6_vabsdiffuh_128B", + "llvm.hexagon.V6.vabsdiffw" => "__builtin_HEXAGON_V6_vabsdiffw", + "llvm.hexagon.V6.vabsdiffw.128B" => "__builtin_HEXAGON_V6_vabsdiffw_128B", + "llvm.hexagon.V6.vabsh" => "__builtin_HEXAGON_V6_vabsh", + "llvm.hexagon.V6.vabsh.128B" => "__builtin_HEXAGON_V6_vabsh_128B", + "llvm.hexagon.V6.vabsh.sat" => "__builtin_HEXAGON_V6_vabsh_sat", + "llvm.hexagon.V6.vabsh.sat.128B" => "__builtin_HEXAGON_V6_vabsh_sat_128B", + "llvm.hexagon.V6.vabsw" => "__builtin_HEXAGON_V6_vabsw", + "llvm.hexagon.V6.vabsw.128B" => "__builtin_HEXAGON_V6_vabsw_128B", + "llvm.hexagon.V6.vabsw.sat" => "__builtin_HEXAGON_V6_vabsw_sat", + "llvm.hexagon.V6.vabsw.sat.128B" => "__builtin_HEXAGON_V6_vabsw_sat_128B", + "llvm.hexagon.V6.vaddb" => "__builtin_HEXAGON_V6_vaddb", + "llvm.hexagon.V6.vaddb.128B" => "__builtin_HEXAGON_V6_vaddb_128B", + "llvm.hexagon.V6.vaddb.dv" => "__builtin_HEXAGON_V6_vaddb_dv", + "llvm.hexagon.V6.vaddb.dv.128B" => "__builtin_HEXAGON_V6_vaddb_dv_128B", + "llvm.hexagon.V6.vaddh" => "__builtin_HEXAGON_V6_vaddh", + "llvm.hexagon.V6.vaddh.128B" => "__builtin_HEXAGON_V6_vaddh_128B", + "llvm.hexagon.V6.vaddh.dv" => "__builtin_HEXAGON_V6_vaddh_dv", + "llvm.hexagon.V6.vaddh.dv.128B" => "__builtin_HEXAGON_V6_vaddh_dv_128B", + "llvm.hexagon.V6.vaddhsat" => "__builtin_HEXAGON_V6_vaddhsat", + "llvm.hexagon.V6.vaddhsat.128B" => "__builtin_HEXAGON_V6_vaddhsat_128B", + "llvm.hexagon.V6.vaddhsat.dv" => "__builtin_HEXAGON_V6_vaddhsat_dv", + "llvm.hexagon.V6.vaddhsat.dv.128B" => "__builtin_HEXAGON_V6_vaddhsat_dv_128B", + "llvm.hexagon.V6.vaddhw" => "__builtin_HEXAGON_V6_vaddhw", + "llvm.hexagon.V6.vaddhw.128B" => "__builtin_HEXAGON_V6_vaddhw_128B", + "llvm.hexagon.V6.vaddubh" => "__builtin_HEXAGON_V6_vaddubh", + "llvm.hexagon.V6.vaddubh.128B" => "__builtin_HEXAGON_V6_vaddubh_128B", + "llvm.hexagon.V6.vaddubsat" => "__builtin_HEXAGON_V6_vaddubsat", + "llvm.hexagon.V6.vaddubsat.128B" => "__builtin_HEXAGON_V6_vaddubsat_128B", + "llvm.hexagon.V6.vaddubsat.dv" => "__builtin_HEXAGON_V6_vaddubsat_dv", + "llvm.hexagon.V6.vaddubsat.dv.128B" => "__builtin_HEXAGON_V6_vaddubsat_dv_128B", + "llvm.hexagon.V6.vadduhsat" => "__builtin_HEXAGON_V6_vadduhsat", + "llvm.hexagon.V6.vadduhsat.128B" => "__builtin_HEXAGON_V6_vadduhsat_128B", + "llvm.hexagon.V6.vadduhsat.dv" => "__builtin_HEXAGON_V6_vadduhsat_dv", + "llvm.hexagon.V6.vadduhsat.dv.128B" => "__builtin_HEXAGON_V6_vadduhsat_dv_128B", + "llvm.hexagon.V6.vadduhw" => "__builtin_HEXAGON_V6_vadduhw", + "llvm.hexagon.V6.vadduhw.128B" => "__builtin_HEXAGON_V6_vadduhw_128B", + "llvm.hexagon.V6.vaddw" => "__builtin_HEXAGON_V6_vaddw", + "llvm.hexagon.V6.vaddw.128B" => "__builtin_HEXAGON_V6_vaddw_128B", + "llvm.hexagon.V6.vaddw.dv" => "__builtin_HEXAGON_V6_vaddw_dv", + "llvm.hexagon.V6.vaddw.dv.128B" => "__builtin_HEXAGON_V6_vaddw_dv_128B", + "llvm.hexagon.V6.vaddwsat" => "__builtin_HEXAGON_V6_vaddwsat", + "llvm.hexagon.V6.vaddwsat.128B" => "__builtin_HEXAGON_V6_vaddwsat_128B", + "llvm.hexagon.V6.vaddwsat.dv" => "__builtin_HEXAGON_V6_vaddwsat_dv", + "llvm.hexagon.V6.vaddwsat.dv.128B" => "__builtin_HEXAGON_V6_vaddwsat_dv_128B", + "llvm.hexagon.V6.valignb" => "__builtin_HEXAGON_V6_valignb", + "llvm.hexagon.V6.valignb.128B" => "__builtin_HEXAGON_V6_valignb_128B", + "llvm.hexagon.V6.valignbi" => "__builtin_HEXAGON_V6_valignbi", + "llvm.hexagon.V6.valignbi.128B" => "__builtin_HEXAGON_V6_valignbi_128B", + "llvm.hexagon.V6.vand" => "__builtin_HEXAGON_V6_vand", + "llvm.hexagon.V6.vand.128B" => "__builtin_HEXAGON_V6_vand_128B", + "llvm.hexagon.V6.vaslh" => "__builtin_HEXAGON_V6_vaslh", + "llvm.hexagon.V6.vaslh.128B" => "__builtin_HEXAGON_V6_vaslh_128B", + "llvm.hexagon.V6.vaslhv" => "__builtin_HEXAGON_V6_vaslhv", + "llvm.hexagon.V6.vaslhv.128B" => "__builtin_HEXAGON_V6_vaslhv_128B", + "llvm.hexagon.V6.vaslw" => "__builtin_HEXAGON_V6_vaslw", + "llvm.hexagon.V6.vaslw.128B" => "__builtin_HEXAGON_V6_vaslw_128B", + "llvm.hexagon.V6.vaslw.acc" => "__builtin_HEXAGON_V6_vaslw_acc", + "llvm.hexagon.V6.vaslw.acc.128B" => "__builtin_HEXAGON_V6_vaslw_acc_128B", + "llvm.hexagon.V6.vaslwv" => "__builtin_HEXAGON_V6_vaslwv", + "llvm.hexagon.V6.vaslwv.128B" => "__builtin_HEXAGON_V6_vaslwv_128B", + "llvm.hexagon.V6.vasrh" => "__builtin_HEXAGON_V6_vasrh", + "llvm.hexagon.V6.vasrh.128B" => "__builtin_HEXAGON_V6_vasrh_128B", + "llvm.hexagon.V6.vasrhbrndsat" => "__builtin_HEXAGON_V6_vasrhbrndsat", + "llvm.hexagon.V6.vasrhbrndsat.128B" => "__builtin_HEXAGON_V6_vasrhbrndsat_128B", + "llvm.hexagon.V6.vasrhubrndsat" => "__builtin_HEXAGON_V6_vasrhubrndsat", + "llvm.hexagon.V6.vasrhubrndsat.128B" => "__builtin_HEXAGON_V6_vasrhubrndsat_128B", + "llvm.hexagon.V6.vasrhubsat" => "__builtin_HEXAGON_V6_vasrhubsat", + "llvm.hexagon.V6.vasrhubsat.128B" => "__builtin_HEXAGON_V6_vasrhubsat_128B", + "llvm.hexagon.V6.vasrhv" => "__builtin_HEXAGON_V6_vasrhv", + "llvm.hexagon.V6.vasrhv.128B" => "__builtin_HEXAGON_V6_vasrhv_128B", + "llvm.hexagon.V6.vasrw" => "__builtin_HEXAGON_V6_vasrw", + "llvm.hexagon.V6.vasrw.128B" => "__builtin_HEXAGON_V6_vasrw_128B", + "llvm.hexagon.V6.vasrw.acc" => "__builtin_HEXAGON_V6_vasrw_acc", + "llvm.hexagon.V6.vasrw.acc.128B" => "__builtin_HEXAGON_V6_vasrw_acc_128B", + "llvm.hexagon.V6.vasrwh" => "__builtin_HEXAGON_V6_vasrwh", + "llvm.hexagon.V6.vasrwh.128B" => "__builtin_HEXAGON_V6_vasrwh_128B", + "llvm.hexagon.V6.vasrwhrndsat" => "__builtin_HEXAGON_V6_vasrwhrndsat", + "llvm.hexagon.V6.vasrwhrndsat.128B" => "__builtin_HEXAGON_V6_vasrwhrndsat_128B", + "llvm.hexagon.V6.vasrwhsat" => "__builtin_HEXAGON_V6_vasrwhsat", + "llvm.hexagon.V6.vasrwhsat.128B" => "__builtin_HEXAGON_V6_vasrwhsat_128B", + "llvm.hexagon.V6.vasrwuhsat" => "__builtin_HEXAGON_V6_vasrwuhsat", + "llvm.hexagon.V6.vasrwuhsat.128B" => "__builtin_HEXAGON_V6_vasrwuhsat_128B", + "llvm.hexagon.V6.vasrwv" => "__builtin_HEXAGON_V6_vasrwv", + "llvm.hexagon.V6.vasrwv.128B" => "__builtin_HEXAGON_V6_vasrwv_128B", + "llvm.hexagon.V6.vassign" => "__builtin_HEXAGON_V6_vassign", + "llvm.hexagon.V6.vassign.128B" => "__builtin_HEXAGON_V6_vassign_128B", + "llvm.hexagon.V6.vassignp" => "__builtin_HEXAGON_V6_vassignp", + "llvm.hexagon.V6.vassignp.128B" => "__builtin_HEXAGON_V6_vassignp_128B", + "llvm.hexagon.V6.vavgh" => "__builtin_HEXAGON_V6_vavgh", + "llvm.hexagon.V6.vavgh.128B" => "__builtin_HEXAGON_V6_vavgh_128B", + "llvm.hexagon.V6.vavghrnd" => "__builtin_HEXAGON_V6_vavghrnd", + "llvm.hexagon.V6.vavghrnd.128B" => "__builtin_HEXAGON_V6_vavghrnd_128B", + "llvm.hexagon.V6.vavgub" => "__builtin_HEXAGON_V6_vavgub", + "llvm.hexagon.V6.vavgub.128B" => "__builtin_HEXAGON_V6_vavgub_128B", + "llvm.hexagon.V6.vavgubrnd" => "__builtin_HEXAGON_V6_vavgubrnd", + "llvm.hexagon.V6.vavgubrnd.128B" => "__builtin_HEXAGON_V6_vavgubrnd_128B", + "llvm.hexagon.V6.vavguh" => "__builtin_HEXAGON_V6_vavguh", + "llvm.hexagon.V6.vavguh.128B" => "__builtin_HEXAGON_V6_vavguh_128B", + "llvm.hexagon.V6.vavguhrnd" => "__builtin_HEXAGON_V6_vavguhrnd", + "llvm.hexagon.V6.vavguhrnd.128B" => "__builtin_HEXAGON_V6_vavguhrnd_128B", + "llvm.hexagon.V6.vavgw" => "__builtin_HEXAGON_V6_vavgw", + "llvm.hexagon.V6.vavgw.128B" => "__builtin_HEXAGON_V6_vavgw_128B", + "llvm.hexagon.V6.vavgwrnd" => "__builtin_HEXAGON_V6_vavgwrnd", + "llvm.hexagon.V6.vavgwrnd.128B" => "__builtin_HEXAGON_V6_vavgwrnd_128B", + "llvm.hexagon.V6.vcl0h" => "__builtin_HEXAGON_V6_vcl0h", + "llvm.hexagon.V6.vcl0h.128B" => "__builtin_HEXAGON_V6_vcl0h_128B", + "llvm.hexagon.V6.vcl0w" => "__builtin_HEXAGON_V6_vcl0w", + "llvm.hexagon.V6.vcl0w.128B" => "__builtin_HEXAGON_V6_vcl0w_128B", + "llvm.hexagon.V6.vcombine" => "__builtin_HEXAGON_V6_vcombine", + "llvm.hexagon.V6.vcombine.128B" => "__builtin_HEXAGON_V6_vcombine_128B", + "llvm.hexagon.V6.vd0" => "__builtin_HEXAGON_V6_vd0", + "llvm.hexagon.V6.vd0.128B" => "__builtin_HEXAGON_V6_vd0_128B", + "llvm.hexagon.V6.vdealb" => "__builtin_HEXAGON_V6_vdealb", + "llvm.hexagon.V6.vdealb.128B" => "__builtin_HEXAGON_V6_vdealb_128B", + "llvm.hexagon.V6.vdealb4w" => "__builtin_HEXAGON_V6_vdealb4w", + "llvm.hexagon.V6.vdealb4w.128B" => "__builtin_HEXAGON_V6_vdealb4w_128B", + "llvm.hexagon.V6.vdealh" => "__builtin_HEXAGON_V6_vdealh", + "llvm.hexagon.V6.vdealh.128B" => "__builtin_HEXAGON_V6_vdealh_128B", + "llvm.hexagon.V6.vdealvdd" => "__builtin_HEXAGON_V6_vdealvdd", + "llvm.hexagon.V6.vdealvdd.128B" => "__builtin_HEXAGON_V6_vdealvdd_128B", + "llvm.hexagon.V6.vdelta" => "__builtin_HEXAGON_V6_vdelta", + "llvm.hexagon.V6.vdelta.128B" => "__builtin_HEXAGON_V6_vdelta_128B", + "llvm.hexagon.V6.vdmpybus" => "__builtin_HEXAGON_V6_vdmpybus", + "llvm.hexagon.V6.vdmpybus.128B" => "__builtin_HEXAGON_V6_vdmpybus_128B", + "llvm.hexagon.V6.vdmpybus.acc" => "__builtin_HEXAGON_V6_vdmpybus_acc", + "llvm.hexagon.V6.vdmpybus.acc.128B" => "__builtin_HEXAGON_V6_vdmpybus_acc_128B", + "llvm.hexagon.V6.vdmpybus.dv" => "__builtin_HEXAGON_V6_vdmpybus_dv", + "llvm.hexagon.V6.vdmpybus.dv.128B" => "__builtin_HEXAGON_V6_vdmpybus_dv_128B", + "llvm.hexagon.V6.vdmpybus.dv.acc" => "__builtin_HEXAGON_V6_vdmpybus_dv_acc", + "llvm.hexagon.V6.vdmpybus.dv.acc.128B" => "__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B", + "llvm.hexagon.V6.vdmpyhb" => "__builtin_HEXAGON_V6_vdmpyhb", + "llvm.hexagon.V6.vdmpyhb.128B" => "__builtin_HEXAGON_V6_vdmpyhb_128B", + "llvm.hexagon.V6.vdmpyhb.acc" => "__builtin_HEXAGON_V6_vdmpyhb_acc", + "llvm.hexagon.V6.vdmpyhb.acc.128B" => "__builtin_HEXAGON_V6_vdmpyhb_acc_128B", + "llvm.hexagon.V6.vdmpyhb.dv" => "__builtin_HEXAGON_V6_vdmpyhb_dv", + "llvm.hexagon.V6.vdmpyhb.dv.128B" => "__builtin_HEXAGON_V6_vdmpyhb_dv_128B", + "llvm.hexagon.V6.vdmpyhb.dv.acc" => "__builtin_HEXAGON_V6_vdmpyhb_dv_acc", + "llvm.hexagon.V6.vdmpyhb.dv.acc.128B" => "__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B", + "llvm.hexagon.V6.vdmpyhisat" => "__builtin_HEXAGON_V6_vdmpyhisat", + "llvm.hexagon.V6.vdmpyhisat.128B" => "__builtin_HEXAGON_V6_vdmpyhisat_128B", + "llvm.hexagon.V6.vdmpyhisat.acc" => "__builtin_HEXAGON_V6_vdmpyhisat_acc", + "llvm.hexagon.V6.vdmpyhisat.acc.128B" => "__builtin_HEXAGON_V6_vdmpyhisat_acc_128B", + "llvm.hexagon.V6.vdmpyhsat" => "__builtin_HEXAGON_V6_vdmpyhsat", + "llvm.hexagon.V6.vdmpyhsat.128B" => "__builtin_HEXAGON_V6_vdmpyhsat_128B", + "llvm.hexagon.V6.vdmpyhsat.acc" => "__builtin_HEXAGON_V6_vdmpyhsat_acc", + "llvm.hexagon.V6.vdmpyhsat.acc.128B" => "__builtin_HEXAGON_V6_vdmpyhsat_acc_128B", + "llvm.hexagon.V6.vdmpyhsuisat" => "__builtin_HEXAGON_V6_vdmpyhsuisat", + "llvm.hexagon.V6.vdmpyhsuisat.128B" => "__builtin_HEXAGON_V6_vdmpyhsuisat_128B", + "llvm.hexagon.V6.vdmpyhsuisat.acc" => "__builtin_HEXAGON_V6_vdmpyhsuisat_acc", + "llvm.hexagon.V6.vdmpyhsuisat.acc.128B" => "__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B", + "llvm.hexagon.V6.vdmpyhsusat" => "__builtin_HEXAGON_V6_vdmpyhsusat", + "llvm.hexagon.V6.vdmpyhsusat.128B" => "__builtin_HEXAGON_V6_vdmpyhsusat_128B", + "llvm.hexagon.V6.vdmpyhsusat.acc" => "__builtin_HEXAGON_V6_vdmpyhsusat_acc", + "llvm.hexagon.V6.vdmpyhsusat.acc.128B" => "__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B", + "llvm.hexagon.V6.vdmpyhvsat" => "__builtin_HEXAGON_V6_vdmpyhvsat", + "llvm.hexagon.V6.vdmpyhvsat.128B" => "__builtin_HEXAGON_V6_vdmpyhvsat_128B", + "llvm.hexagon.V6.vdmpyhvsat.acc" => "__builtin_HEXAGON_V6_vdmpyhvsat_acc", + "llvm.hexagon.V6.vdmpyhvsat.acc.128B" => "__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B", + "llvm.hexagon.V6.vdsaduh" => "__builtin_HEXAGON_V6_vdsaduh", + "llvm.hexagon.V6.vdsaduh.128B" => "__builtin_HEXAGON_V6_vdsaduh_128B", + "llvm.hexagon.V6.vdsaduh.acc" => "__builtin_HEXAGON_V6_vdsaduh_acc", + "llvm.hexagon.V6.vdsaduh.acc.128B" => "__builtin_HEXAGON_V6_vdsaduh_acc_128B", + "llvm.hexagon.V6.vinsertwr" => "__builtin_HEXAGON_V6_vinsertwr", + "llvm.hexagon.V6.vinsertwr.128B" => "__builtin_HEXAGON_V6_vinsertwr_128B", + "llvm.hexagon.V6.vlalignb" => "__builtin_HEXAGON_V6_vlalignb", + "llvm.hexagon.V6.vlalignb.128B" => "__builtin_HEXAGON_V6_vlalignb_128B", + "llvm.hexagon.V6.vlalignbi" => "__builtin_HEXAGON_V6_vlalignbi", + "llvm.hexagon.V6.vlalignbi.128B" => "__builtin_HEXAGON_V6_vlalignbi_128B", + "llvm.hexagon.V6.vlsrh" => "__builtin_HEXAGON_V6_vlsrh", + "llvm.hexagon.V6.vlsrh.128B" => "__builtin_HEXAGON_V6_vlsrh_128B", + "llvm.hexagon.V6.vlsrhv" => "__builtin_HEXAGON_V6_vlsrhv", + "llvm.hexagon.V6.vlsrhv.128B" => "__builtin_HEXAGON_V6_vlsrhv_128B", + "llvm.hexagon.V6.vlsrw" => "__builtin_HEXAGON_V6_vlsrw", + "llvm.hexagon.V6.vlsrw.128B" => "__builtin_HEXAGON_V6_vlsrw_128B", + "llvm.hexagon.V6.vlsrwv" => "__builtin_HEXAGON_V6_vlsrwv", + "llvm.hexagon.V6.vlsrwv.128B" => "__builtin_HEXAGON_V6_vlsrwv_128B", + "llvm.hexagon.V6.vlutb" => "__builtin_HEXAGON_V6_vlutb", + "llvm.hexagon.V6.vlutb.128B" => "__builtin_HEXAGON_V6_vlutb_128B", + "llvm.hexagon.V6.vlutb.acc" => "__builtin_HEXAGON_V6_vlutb_acc", + "llvm.hexagon.V6.vlutb.acc.128B" => "__builtin_HEXAGON_V6_vlutb_acc_128B", + "llvm.hexagon.V6.vlutb.dv" => "__builtin_HEXAGON_V6_vlutb_dv", + "llvm.hexagon.V6.vlutb.dv.128B" => "__builtin_HEXAGON_V6_vlutb_dv_128B", + "llvm.hexagon.V6.vlutb.dv.acc" => "__builtin_HEXAGON_V6_vlutb_dv_acc", + "llvm.hexagon.V6.vlutb.dv.acc.128B" => "__builtin_HEXAGON_V6_vlutb_dv_acc_128B", + "llvm.hexagon.V6.vlutvvb" => "__builtin_HEXAGON_V6_vlutvvb", + "llvm.hexagon.V6.vlutvvb.128B" => "__builtin_HEXAGON_V6_vlutvvb_128B", + "llvm.hexagon.V6.vlutvvb.oracc" => "__builtin_HEXAGON_V6_vlutvvb_oracc", + "llvm.hexagon.V6.vlutvvb.oracc.128B" => "__builtin_HEXAGON_V6_vlutvvb_oracc_128B", + "llvm.hexagon.V6.vlutvwh" => "__builtin_HEXAGON_V6_vlutvwh", + "llvm.hexagon.V6.vlutvwh.128B" => "__builtin_HEXAGON_V6_vlutvwh_128B", + "llvm.hexagon.V6.vlutvwh.oracc" => "__builtin_HEXAGON_V6_vlutvwh_oracc", + "llvm.hexagon.V6.vlutvwh.oracc.128B" => "__builtin_HEXAGON_V6_vlutvwh_oracc_128B", + "llvm.hexagon.V6.vmaxh" => "__builtin_HEXAGON_V6_vmaxh", + "llvm.hexagon.V6.vmaxh.128B" => "__builtin_HEXAGON_V6_vmaxh_128B", + "llvm.hexagon.V6.vmaxub" => "__builtin_HEXAGON_V6_vmaxub", + "llvm.hexagon.V6.vmaxub.128B" => "__builtin_HEXAGON_V6_vmaxub_128B", + "llvm.hexagon.V6.vmaxuh" => "__builtin_HEXAGON_V6_vmaxuh", + "llvm.hexagon.V6.vmaxuh.128B" => "__builtin_HEXAGON_V6_vmaxuh_128B", + "llvm.hexagon.V6.vmaxw" => "__builtin_HEXAGON_V6_vmaxw", + "llvm.hexagon.V6.vmaxw.128B" => "__builtin_HEXAGON_V6_vmaxw_128B", + "llvm.hexagon.V6.vminh" => "__builtin_HEXAGON_V6_vminh", + "llvm.hexagon.V6.vminh.128B" => "__builtin_HEXAGON_V6_vminh_128B", + "llvm.hexagon.V6.vminub" => "__builtin_HEXAGON_V6_vminub", + "llvm.hexagon.V6.vminub.128B" => "__builtin_HEXAGON_V6_vminub_128B", + "llvm.hexagon.V6.vminuh" => "__builtin_HEXAGON_V6_vminuh", + "llvm.hexagon.V6.vminuh.128B" => "__builtin_HEXAGON_V6_vminuh_128B", + "llvm.hexagon.V6.vminw" => "__builtin_HEXAGON_V6_vminw", + "llvm.hexagon.V6.vminw.128B" => "__builtin_HEXAGON_V6_vminw_128B", + "llvm.hexagon.V6.vmpabus" => "__builtin_HEXAGON_V6_vmpabus", + "llvm.hexagon.V6.vmpabus.128B" => "__builtin_HEXAGON_V6_vmpabus_128B", + "llvm.hexagon.V6.vmpabus.acc" => "__builtin_HEXAGON_V6_vmpabus_acc", + "llvm.hexagon.V6.vmpabus.acc.128B" => "__builtin_HEXAGON_V6_vmpabus_acc_128B", + "llvm.hexagon.V6.vmpabusv" => "__builtin_HEXAGON_V6_vmpabusv", + "llvm.hexagon.V6.vmpabusv.128B" => "__builtin_HEXAGON_V6_vmpabusv_128B", + "llvm.hexagon.V6.vmpabuuv" => "__builtin_HEXAGON_V6_vmpabuuv", + "llvm.hexagon.V6.vmpabuuv.128B" => "__builtin_HEXAGON_V6_vmpabuuv_128B", + "llvm.hexagon.V6.vmpahb" => "__builtin_HEXAGON_V6_vmpahb", + "llvm.hexagon.V6.vmpahb.128B" => "__builtin_HEXAGON_V6_vmpahb_128B", + "llvm.hexagon.V6.vmpahb.acc" => "__builtin_HEXAGON_V6_vmpahb_acc", + "llvm.hexagon.V6.vmpahb.acc.128B" => "__builtin_HEXAGON_V6_vmpahb_acc_128B", + "llvm.hexagon.V6.vmpybus" => "__builtin_HEXAGON_V6_vmpybus", + "llvm.hexagon.V6.vmpybus.128B" => "__builtin_HEXAGON_V6_vmpybus_128B", + "llvm.hexagon.V6.vmpybus.acc" => "__builtin_HEXAGON_V6_vmpybus_acc", + "llvm.hexagon.V6.vmpybus.acc.128B" => "__builtin_HEXAGON_V6_vmpybus_acc_128B", + "llvm.hexagon.V6.vmpybusv" => "__builtin_HEXAGON_V6_vmpybusv", + "llvm.hexagon.V6.vmpybusv.128B" => "__builtin_HEXAGON_V6_vmpybusv_128B", + "llvm.hexagon.V6.vmpybusv.acc" => "__builtin_HEXAGON_V6_vmpybusv_acc", + "llvm.hexagon.V6.vmpybusv.acc.128B" => "__builtin_HEXAGON_V6_vmpybusv_acc_128B", + "llvm.hexagon.V6.vmpybv" => "__builtin_HEXAGON_V6_vmpybv", + "llvm.hexagon.V6.vmpybv.128B" => "__builtin_HEXAGON_V6_vmpybv_128B", + "llvm.hexagon.V6.vmpybv.acc" => "__builtin_HEXAGON_V6_vmpybv_acc", + "llvm.hexagon.V6.vmpybv.acc.128B" => "__builtin_HEXAGON_V6_vmpybv_acc_128B", + "llvm.hexagon.V6.vmpyewuh" => "__builtin_HEXAGON_V6_vmpyewuh", + "llvm.hexagon.V6.vmpyewuh.128B" => "__builtin_HEXAGON_V6_vmpyewuh_128B", + "llvm.hexagon.V6.vmpyh" => "__builtin_HEXAGON_V6_vmpyh", + "llvm.hexagon.V6.vmpyh.128B" => "__builtin_HEXAGON_V6_vmpyh_128B", + "llvm.hexagon.V6.vmpyhsat.acc" => "__builtin_HEXAGON_V6_vmpyhsat_acc", + "llvm.hexagon.V6.vmpyhsat.acc.128B" => "__builtin_HEXAGON_V6_vmpyhsat_acc_128B", + "llvm.hexagon.V6.vmpyhsrs" => "__builtin_HEXAGON_V6_vmpyhsrs", + "llvm.hexagon.V6.vmpyhsrs.128B" => "__builtin_HEXAGON_V6_vmpyhsrs_128B", + "llvm.hexagon.V6.vmpyhss" => "__builtin_HEXAGON_V6_vmpyhss", + "llvm.hexagon.V6.vmpyhss.128B" => "__builtin_HEXAGON_V6_vmpyhss_128B", + "llvm.hexagon.V6.vmpyhus" => "__builtin_HEXAGON_V6_vmpyhus", + "llvm.hexagon.V6.vmpyhus.128B" => "__builtin_HEXAGON_V6_vmpyhus_128B", + "llvm.hexagon.V6.vmpyhus.acc" => "__builtin_HEXAGON_V6_vmpyhus_acc", + "llvm.hexagon.V6.vmpyhus.acc.128B" => "__builtin_HEXAGON_V6_vmpyhus_acc_128B", + "llvm.hexagon.V6.vmpyhv" => "__builtin_HEXAGON_V6_vmpyhv", + "llvm.hexagon.V6.vmpyhv.128B" => "__builtin_HEXAGON_V6_vmpyhv_128B", + "llvm.hexagon.V6.vmpyhv.acc" => "__builtin_HEXAGON_V6_vmpyhv_acc", + "llvm.hexagon.V6.vmpyhv.acc.128B" => "__builtin_HEXAGON_V6_vmpyhv_acc_128B", + "llvm.hexagon.V6.vmpyhvsrs" => "__builtin_HEXAGON_V6_vmpyhvsrs", + "llvm.hexagon.V6.vmpyhvsrs.128B" => "__builtin_HEXAGON_V6_vmpyhvsrs_128B", + "llvm.hexagon.V6.vmpyieoh" => "__builtin_HEXAGON_V6_vmpyieoh", + "llvm.hexagon.V6.vmpyieoh.128B" => "__builtin_HEXAGON_V6_vmpyieoh_128B", + "llvm.hexagon.V6.vmpyiewh.acc" => "__builtin_HEXAGON_V6_vmpyiewh_acc", + "llvm.hexagon.V6.vmpyiewh.acc.128B" => "__builtin_HEXAGON_V6_vmpyiewh_acc_128B", + "llvm.hexagon.V6.vmpyiewuh" => "__builtin_HEXAGON_V6_vmpyiewuh", + "llvm.hexagon.V6.vmpyiewuh.128B" => "__builtin_HEXAGON_V6_vmpyiewuh_128B", + "llvm.hexagon.V6.vmpyiewuh.acc" => "__builtin_HEXAGON_V6_vmpyiewuh_acc", + "llvm.hexagon.V6.vmpyiewuh.acc.128B" => "__builtin_HEXAGON_V6_vmpyiewuh_acc_128B", + "llvm.hexagon.V6.vmpyih" => "__builtin_HEXAGON_V6_vmpyih", + "llvm.hexagon.V6.vmpyih.128B" => "__builtin_HEXAGON_V6_vmpyih_128B", + "llvm.hexagon.V6.vmpyih.acc" => "__builtin_HEXAGON_V6_vmpyih_acc", + "llvm.hexagon.V6.vmpyih.acc.128B" => "__builtin_HEXAGON_V6_vmpyih_acc_128B", + "llvm.hexagon.V6.vmpyihb" => "__builtin_HEXAGON_V6_vmpyihb", + "llvm.hexagon.V6.vmpyihb.128B" => "__builtin_HEXAGON_V6_vmpyihb_128B", + "llvm.hexagon.V6.vmpyihb.acc" => "__builtin_HEXAGON_V6_vmpyihb_acc", + "llvm.hexagon.V6.vmpyihb.acc.128B" => "__builtin_HEXAGON_V6_vmpyihb_acc_128B", + "llvm.hexagon.V6.vmpyiowh" => "__builtin_HEXAGON_V6_vmpyiowh", + "llvm.hexagon.V6.vmpyiowh.128B" => "__builtin_HEXAGON_V6_vmpyiowh_128B", + "llvm.hexagon.V6.vmpyiwb" => "__builtin_HEXAGON_V6_vmpyiwb", + "llvm.hexagon.V6.vmpyiwb.128B" => "__builtin_HEXAGON_V6_vmpyiwb_128B", + "llvm.hexagon.V6.vmpyiwb.acc" => "__builtin_HEXAGON_V6_vmpyiwb_acc", + "llvm.hexagon.V6.vmpyiwb.acc.128B" => "__builtin_HEXAGON_V6_vmpyiwb_acc_128B", + "llvm.hexagon.V6.vmpyiwh" => "__builtin_HEXAGON_V6_vmpyiwh", + "llvm.hexagon.V6.vmpyiwh.128B" => "__builtin_HEXAGON_V6_vmpyiwh_128B", + "llvm.hexagon.V6.vmpyiwh.acc" => "__builtin_HEXAGON_V6_vmpyiwh_acc", + "llvm.hexagon.V6.vmpyiwh.acc.128B" => "__builtin_HEXAGON_V6_vmpyiwh_acc_128B", + "llvm.hexagon.V6.vmpyowh" => "__builtin_HEXAGON_V6_vmpyowh", + "llvm.hexagon.V6.vmpyowh.128B" => "__builtin_HEXAGON_V6_vmpyowh_128B", + "llvm.hexagon.V6.vmpyowh.rnd" => "__builtin_HEXAGON_V6_vmpyowh_rnd", + "llvm.hexagon.V6.vmpyowh.rnd.128B" => "__builtin_HEXAGON_V6_vmpyowh_rnd_128B", + "llvm.hexagon.V6.vmpyowh.rnd.sacc" => "__builtin_HEXAGON_V6_vmpyowh_rnd_sacc", + "llvm.hexagon.V6.vmpyowh.rnd.sacc.128B" => "__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B", + "llvm.hexagon.V6.vmpyowh.sacc" => "__builtin_HEXAGON_V6_vmpyowh_sacc", + "llvm.hexagon.V6.vmpyowh.sacc.128B" => "__builtin_HEXAGON_V6_vmpyowh_sacc_128B", + "llvm.hexagon.V6.vmpyub" => "__builtin_HEXAGON_V6_vmpyub", + "llvm.hexagon.V6.vmpyub.128B" => "__builtin_HEXAGON_V6_vmpyub_128B", + "llvm.hexagon.V6.vmpyub.acc" => "__builtin_HEXAGON_V6_vmpyub_acc", + "llvm.hexagon.V6.vmpyub.acc.128B" => "__builtin_HEXAGON_V6_vmpyub_acc_128B", + "llvm.hexagon.V6.vmpyubv" => "__builtin_HEXAGON_V6_vmpyubv", + "llvm.hexagon.V6.vmpyubv.128B" => "__builtin_HEXAGON_V6_vmpyubv_128B", + "llvm.hexagon.V6.vmpyubv.acc" => "__builtin_HEXAGON_V6_vmpyubv_acc", + "llvm.hexagon.V6.vmpyubv.acc.128B" => "__builtin_HEXAGON_V6_vmpyubv_acc_128B", + "llvm.hexagon.V6.vmpyuh" => "__builtin_HEXAGON_V6_vmpyuh", + "llvm.hexagon.V6.vmpyuh.128B" => "__builtin_HEXAGON_V6_vmpyuh_128B", + "llvm.hexagon.V6.vmpyuh.acc" => "__builtin_HEXAGON_V6_vmpyuh_acc", + "llvm.hexagon.V6.vmpyuh.acc.128B" => "__builtin_HEXAGON_V6_vmpyuh_acc_128B", + "llvm.hexagon.V6.vmpyuhv" => "__builtin_HEXAGON_V6_vmpyuhv", + "llvm.hexagon.V6.vmpyuhv.128B" => "__builtin_HEXAGON_V6_vmpyuhv_128B", + "llvm.hexagon.V6.vmpyuhv.acc" => "__builtin_HEXAGON_V6_vmpyuhv_acc", + "llvm.hexagon.V6.vmpyuhv.acc.128B" => "__builtin_HEXAGON_V6_vmpyuhv_acc_128B", + "llvm.hexagon.V6.vnavgh" => "__builtin_HEXAGON_V6_vnavgh", + "llvm.hexagon.V6.vnavgh.128B" => "__builtin_HEXAGON_V6_vnavgh_128B", + "llvm.hexagon.V6.vnavgub" => "__builtin_HEXAGON_V6_vnavgub", + "llvm.hexagon.V6.vnavgub.128B" => "__builtin_HEXAGON_V6_vnavgub_128B", + "llvm.hexagon.V6.vnavgw" => "__builtin_HEXAGON_V6_vnavgw", + "llvm.hexagon.V6.vnavgw.128B" => "__builtin_HEXAGON_V6_vnavgw_128B", + "llvm.hexagon.V6.vnormamth" => "__builtin_HEXAGON_V6_vnormamth", + "llvm.hexagon.V6.vnormamth.128B" => "__builtin_HEXAGON_V6_vnormamth_128B", + "llvm.hexagon.V6.vnormamtw" => "__builtin_HEXAGON_V6_vnormamtw", + "llvm.hexagon.V6.vnormamtw.128B" => "__builtin_HEXAGON_V6_vnormamtw_128B", + "llvm.hexagon.V6.vnot" => "__builtin_HEXAGON_V6_vnot", + "llvm.hexagon.V6.vnot.128B" => "__builtin_HEXAGON_V6_vnot_128B", + "llvm.hexagon.V6.vor" => "__builtin_HEXAGON_V6_vor", + "llvm.hexagon.V6.vor.128B" => "__builtin_HEXAGON_V6_vor_128B", + "llvm.hexagon.V6.vpackeb" => "__builtin_HEXAGON_V6_vpackeb", + "llvm.hexagon.V6.vpackeb.128B" => "__builtin_HEXAGON_V6_vpackeb_128B", + "llvm.hexagon.V6.vpackeh" => "__builtin_HEXAGON_V6_vpackeh", + "llvm.hexagon.V6.vpackeh.128B" => "__builtin_HEXAGON_V6_vpackeh_128B", + "llvm.hexagon.V6.vpackhb.sat" => "__builtin_HEXAGON_V6_vpackhb_sat", + "llvm.hexagon.V6.vpackhb.sat.128B" => "__builtin_HEXAGON_V6_vpackhb_sat_128B", + "llvm.hexagon.V6.vpackhub.sat" => "__builtin_HEXAGON_V6_vpackhub_sat", + "llvm.hexagon.V6.vpackhub.sat.128B" => "__builtin_HEXAGON_V6_vpackhub_sat_128B", + "llvm.hexagon.V6.vpackob" => "__builtin_HEXAGON_V6_vpackob", + "llvm.hexagon.V6.vpackob.128B" => "__builtin_HEXAGON_V6_vpackob_128B", + "llvm.hexagon.V6.vpackoh" => "__builtin_HEXAGON_V6_vpackoh", + "llvm.hexagon.V6.vpackoh.128B" => "__builtin_HEXAGON_V6_vpackoh_128B", + "llvm.hexagon.V6.vpackwh.sat" => "__builtin_HEXAGON_V6_vpackwh_sat", + "llvm.hexagon.V6.vpackwh.sat.128B" => "__builtin_HEXAGON_V6_vpackwh_sat_128B", + "llvm.hexagon.V6.vpackwuh.sat" => "__builtin_HEXAGON_V6_vpackwuh_sat", + "llvm.hexagon.V6.vpackwuh.sat.128B" => "__builtin_HEXAGON_V6_vpackwuh_sat_128B", + "llvm.hexagon.V6.vpopcounth" => "__builtin_HEXAGON_V6_vpopcounth", + "llvm.hexagon.V6.vpopcounth.128B" => "__builtin_HEXAGON_V6_vpopcounth_128B", + "llvm.hexagon.V6.vrdelta" => "__builtin_HEXAGON_V6_vrdelta", + "llvm.hexagon.V6.vrdelta.128B" => "__builtin_HEXAGON_V6_vrdelta_128B", + "llvm.hexagon.V6.vrmpybus" => "__builtin_HEXAGON_V6_vrmpybus", + "llvm.hexagon.V6.vrmpybus.128B" => "__builtin_HEXAGON_V6_vrmpybus_128B", + "llvm.hexagon.V6.vrmpybus.acc" => "__builtin_HEXAGON_V6_vrmpybus_acc", + "llvm.hexagon.V6.vrmpybus.acc.128B" => "__builtin_HEXAGON_V6_vrmpybus_acc_128B", + "llvm.hexagon.V6.vrmpybusi" => "__builtin_HEXAGON_V6_vrmpybusi", + "llvm.hexagon.V6.vrmpybusi.128B" => "__builtin_HEXAGON_V6_vrmpybusi_128B", + "llvm.hexagon.V6.vrmpybusi.acc" => "__builtin_HEXAGON_V6_vrmpybusi_acc", + "llvm.hexagon.V6.vrmpybusi.acc.128B" => "__builtin_HEXAGON_V6_vrmpybusi_acc_128B", + "llvm.hexagon.V6.vrmpybusv" => "__builtin_HEXAGON_V6_vrmpybusv", + "llvm.hexagon.V6.vrmpybusv.128B" => "__builtin_HEXAGON_V6_vrmpybusv_128B", + "llvm.hexagon.V6.vrmpybusv.acc" => "__builtin_HEXAGON_V6_vrmpybusv_acc", + "llvm.hexagon.V6.vrmpybusv.acc.128B" => "__builtin_HEXAGON_V6_vrmpybusv_acc_128B", + "llvm.hexagon.V6.vrmpybv" => "__builtin_HEXAGON_V6_vrmpybv", + "llvm.hexagon.V6.vrmpybv.128B" => "__builtin_HEXAGON_V6_vrmpybv_128B", + "llvm.hexagon.V6.vrmpybv.acc" => "__builtin_HEXAGON_V6_vrmpybv_acc", + "llvm.hexagon.V6.vrmpybv.acc.128B" => "__builtin_HEXAGON_V6_vrmpybv_acc_128B", + "llvm.hexagon.V6.vrmpyub" => "__builtin_HEXAGON_V6_vrmpyub", + "llvm.hexagon.V6.vrmpyub.128B" => "__builtin_HEXAGON_V6_vrmpyub_128B", + "llvm.hexagon.V6.vrmpyub.acc" => "__builtin_HEXAGON_V6_vrmpyub_acc", + "llvm.hexagon.V6.vrmpyub.acc.128B" => "__builtin_HEXAGON_V6_vrmpyub_acc_128B", + "llvm.hexagon.V6.vrmpyubi" => "__builtin_HEXAGON_V6_vrmpyubi", + "llvm.hexagon.V6.vrmpyubi.128B" => "__builtin_HEXAGON_V6_vrmpyubi_128B", + "llvm.hexagon.V6.vrmpyubi.acc" => "__builtin_HEXAGON_V6_vrmpyubi_acc", + "llvm.hexagon.V6.vrmpyubi.acc.128B" => "__builtin_HEXAGON_V6_vrmpyubi_acc_128B", + "llvm.hexagon.V6.vrmpyubv" => "__builtin_HEXAGON_V6_vrmpyubv", + "llvm.hexagon.V6.vrmpyubv.128B" => "__builtin_HEXAGON_V6_vrmpyubv_128B", + "llvm.hexagon.V6.vrmpyubv.acc" => "__builtin_HEXAGON_V6_vrmpyubv_acc", + "llvm.hexagon.V6.vrmpyubv.acc.128B" => "__builtin_HEXAGON_V6_vrmpyubv_acc_128B", + "llvm.hexagon.V6.vror" => "__builtin_HEXAGON_V6_vror", + "llvm.hexagon.V6.vror.128B" => "__builtin_HEXAGON_V6_vror_128B", + "llvm.hexagon.V6.vroundhb" => "__builtin_HEXAGON_V6_vroundhb", + "llvm.hexagon.V6.vroundhb.128B" => "__builtin_HEXAGON_V6_vroundhb_128B", + "llvm.hexagon.V6.vroundhub" => "__builtin_HEXAGON_V6_vroundhub", + "llvm.hexagon.V6.vroundhub.128B" => "__builtin_HEXAGON_V6_vroundhub_128B", + "llvm.hexagon.V6.vroundwh" => "__builtin_HEXAGON_V6_vroundwh", + "llvm.hexagon.V6.vroundwh.128B" => "__builtin_HEXAGON_V6_vroundwh_128B", + "llvm.hexagon.V6.vroundwuh" => "__builtin_HEXAGON_V6_vroundwuh", + "llvm.hexagon.V6.vroundwuh.128B" => "__builtin_HEXAGON_V6_vroundwuh_128B", + "llvm.hexagon.V6.vrsadubi" => "__builtin_HEXAGON_V6_vrsadubi", + "llvm.hexagon.V6.vrsadubi.128B" => "__builtin_HEXAGON_V6_vrsadubi_128B", + "llvm.hexagon.V6.vrsadubi.acc" => "__builtin_HEXAGON_V6_vrsadubi_acc", + "llvm.hexagon.V6.vrsadubi.acc.128B" => "__builtin_HEXAGON_V6_vrsadubi_acc_128B", + "llvm.hexagon.V6.vsathub" => "__builtin_HEXAGON_V6_vsathub", + "llvm.hexagon.V6.vsathub.128B" => "__builtin_HEXAGON_V6_vsathub_128B", + "llvm.hexagon.V6.vsatwh" => "__builtin_HEXAGON_V6_vsatwh", + "llvm.hexagon.V6.vsatwh.128B" => "__builtin_HEXAGON_V6_vsatwh_128B", + "llvm.hexagon.V6.vsb" => "__builtin_HEXAGON_V6_vsb", + "llvm.hexagon.V6.vsb.128B" => "__builtin_HEXAGON_V6_vsb_128B", + "llvm.hexagon.V6.vsh" => "__builtin_HEXAGON_V6_vsh", + "llvm.hexagon.V6.vsh.128B" => "__builtin_HEXAGON_V6_vsh_128B", + "llvm.hexagon.V6.vshufeh" => "__builtin_HEXAGON_V6_vshufeh", + "llvm.hexagon.V6.vshufeh.128B" => "__builtin_HEXAGON_V6_vshufeh_128B", + "llvm.hexagon.V6.vshuffb" => "__builtin_HEXAGON_V6_vshuffb", + "llvm.hexagon.V6.vshuffb.128B" => "__builtin_HEXAGON_V6_vshuffb_128B", + "llvm.hexagon.V6.vshuffeb" => "__builtin_HEXAGON_V6_vshuffeb", + "llvm.hexagon.V6.vshuffeb.128B" => "__builtin_HEXAGON_V6_vshuffeb_128B", + "llvm.hexagon.V6.vshuffh" => "__builtin_HEXAGON_V6_vshuffh", + "llvm.hexagon.V6.vshuffh.128B" => "__builtin_HEXAGON_V6_vshuffh_128B", + "llvm.hexagon.V6.vshuffob" => "__builtin_HEXAGON_V6_vshuffob", + "llvm.hexagon.V6.vshuffob.128B" => "__builtin_HEXAGON_V6_vshuffob_128B", + "llvm.hexagon.V6.vshuffvdd" => "__builtin_HEXAGON_V6_vshuffvdd", + "llvm.hexagon.V6.vshuffvdd.128B" => "__builtin_HEXAGON_V6_vshuffvdd_128B", + "llvm.hexagon.V6.vshufoeb" => "__builtin_HEXAGON_V6_vshufoeb", + "llvm.hexagon.V6.vshufoeb.128B" => "__builtin_HEXAGON_V6_vshufoeb_128B", + "llvm.hexagon.V6.vshufoeh" => "__builtin_HEXAGON_V6_vshufoeh", + "llvm.hexagon.V6.vshufoeh.128B" => "__builtin_HEXAGON_V6_vshufoeh_128B", + "llvm.hexagon.V6.vshufoh" => "__builtin_HEXAGON_V6_vshufoh", + "llvm.hexagon.V6.vshufoh.128B" => "__builtin_HEXAGON_V6_vshufoh_128B", + "llvm.hexagon.V6.vsubb" => "__builtin_HEXAGON_V6_vsubb", + "llvm.hexagon.V6.vsubb.128B" => "__builtin_HEXAGON_V6_vsubb_128B", + "llvm.hexagon.V6.vsubb.dv" => "__builtin_HEXAGON_V6_vsubb_dv", + "llvm.hexagon.V6.vsubb.dv.128B" => "__builtin_HEXAGON_V6_vsubb_dv_128B", + "llvm.hexagon.V6.vsubh" => "__builtin_HEXAGON_V6_vsubh", + "llvm.hexagon.V6.vsubh.128B" => "__builtin_HEXAGON_V6_vsubh_128B", + "llvm.hexagon.V6.vsubh.dv" => "__builtin_HEXAGON_V6_vsubh_dv", + "llvm.hexagon.V6.vsubh.dv.128B" => "__builtin_HEXAGON_V6_vsubh_dv_128B", + "llvm.hexagon.V6.vsubhsat" => "__builtin_HEXAGON_V6_vsubhsat", + "llvm.hexagon.V6.vsubhsat.128B" => "__builtin_HEXAGON_V6_vsubhsat_128B", + "llvm.hexagon.V6.vsubhsat.dv" => "__builtin_HEXAGON_V6_vsubhsat_dv", + "llvm.hexagon.V6.vsubhsat.dv.128B" => "__builtin_HEXAGON_V6_vsubhsat_dv_128B", + "llvm.hexagon.V6.vsubhw" => "__builtin_HEXAGON_V6_vsubhw", + "llvm.hexagon.V6.vsubhw.128B" => "__builtin_HEXAGON_V6_vsubhw_128B", + "llvm.hexagon.V6.vsububh" => "__builtin_HEXAGON_V6_vsububh", + "llvm.hexagon.V6.vsububh.128B" => "__builtin_HEXAGON_V6_vsububh_128B", + "llvm.hexagon.V6.vsububsat" => "__builtin_HEXAGON_V6_vsububsat", + "llvm.hexagon.V6.vsububsat.128B" => "__builtin_HEXAGON_V6_vsububsat_128B", + "llvm.hexagon.V6.vsububsat.dv" => "__builtin_HEXAGON_V6_vsububsat_dv", + "llvm.hexagon.V6.vsububsat.dv.128B" => "__builtin_HEXAGON_V6_vsububsat_dv_128B", + "llvm.hexagon.V6.vsubuhsat" => "__builtin_HEXAGON_V6_vsubuhsat", + "llvm.hexagon.V6.vsubuhsat.128B" => "__builtin_HEXAGON_V6_vsubuhsat_128B", + "llvm.hexagon.V6.vsubuhsat.dv" => "__builtin_HEXAGON_V6_vsubuhsat_dv", + "llvm.hexagon.V6.vsubuhsat.dv.128B" => "__builtin_HEXAGON_V6_vsubuhsat_dv_128B", + "llvm.hexagon.V6.vsubuhw" => "__builtin_HEXAGON_V6_vsubuhw", + "llvm.hexagon.V6.vsubuhw.128B" => "__builtin_HEXAGON_V6_vsubuhw_128B", + "llvm.hexagon.V6.vsubw" => "__builtin_HEXAGON_V6_vsubw", + "llvm.hexagon.V6.vsubw.128B" => "__builtin_HEXAGON_V6_vsubw_128B", + "llvm.hexagon.V6.vsubw.dv" => "__builtin_HEXAGON_V6_vsubw_dv", + "llvm.hexagon.V6.vsubw.dv.128B" => "__builtin_HEXAGON_V6_vsubw_dv_128B", + "llvm.hexagon.V6.vsubwsat" => "__builtin_HEXAGON_V6_vsubwsat", + "llvm.hexagon.V6.vsubwsat.128B" => "__builtin_HEXAGON_V6_vsubwsat_128B", + "llvm.hexagon.V6.vsubwsat.dv" => "__builtin_HEXAGON_V6_vsubwsat_dv", + "llvm.hexagon.V6.vsubwsat.dv.128B" => "__builtin_HEXAGON_V6_vsubwsat_dv_128B", + "llvm.hexagon.V6.vtmpyb" => "__builtin_HEXAGON_V6_vtmpyb", + "llvm.hexagon.V6.vtmpyb.128B" => "__builtin_HEXAGON_V6_vtmpyb_128B", + "llvm.hexagon.V6.vtmpyb.acc" => "__builtin_HEXAGON_V6_vtmpyb_acc", + "llvm.hexagon.V6.vtmpyb.acc.128B" => "__builtin_HEXAGON_V6_vtmpyb_acc_128B", + "llvm.hexagon.V6.vtmpybus" => "__builtin_HEXAGON_V6_vtmpybus", + "llvm.hexagon.V6.vtmpybus.128B" => "__builtin_HEXAGON_V6_vtmpybus_128B", + "llvm.hexagon.V6.vtmpybus.acc" => "__builtin_HEXAGON_V6_vtmpybus_acc", + "llvm.hexagon.V6.vtmpybus.acc.128B" => "__builtin_HEXAGON_V6_vtmpybus_acc_128B", + "llvm.hexagon.V6.vtmpyhb" => "__builtin_HEXAGON_V6_vtmpyhb", + "llvm.hexagon.V6.vtmpyhb.128B" => "__builtin_HEXAGON_V6_vtmpyhb_128B", + "llvm.hexagon.V6.vtmpyhb.acc" => "__builtin_HEXAGON_V6_vtmpyhb_acc", + "llvm.hexagon.V6.vtmpyhb.acc.128B" => "__builtin_HEXAGON_V6_vtmpyhb_acc_128B", + "llvm.hexagon.V6.vunpackb" => "__builtin_HEXAGON_V6_vunpackb", + "llvm.hexagon.V6.vunpackb.128B" => "__builtin_HEXAGON_V6_vunpackb_128B", + "llvm.hexagon.V6.vunpackh" => "__builtin_HEXAGON_V6_vunpackh", + "llvm.hexagon.V6.vunpackh.128B" => "__builtin_HEXAGON_V6_vunpackh_128B", + "llvm.hexagon.V6.vunpackob" => "__builtin_HEXAGON_V6_vunpackob", + "llvm.hexagon.V6.vunpackob.128B" => "__builtin_HEXAGON_V6_vunpackob_128B", + "llvm.hexagon.V6.vunpackoh" => "__builtin_HEXAGON_V6_vunpackoh", + "llvm.hexagon.V6.vunpackoh.128B" => "__builtin_HEXAGON_V6_vunpackoh_128B", + "llvm.hexagon.V6.vunpackub" => "__builtin_HEXAGON_V6_vunpackub", + "llvm.hexagon.V6.vunpackub.128B" => "__builtin_HEXAGON_V6_vunpackub_128B", + "llvm.hexagon.V6.vunpackuh" => "__builtin_HEXAGON_V6_vunpackuh", + "llvm.hexagon.V6.vunpackuh.128B" => "__builtin_HEXAGON_V6_vunpackuh_128B", + "llvm.hexagon.V6.vxor" => "__builtin_HEXAGON_V6_vxor", + "llvm.hexagon.V6.vxor.128B" => "__builtin_HEXAGON_V6_vxor_128B", + "llvm.hexagon.V6.vzb" => "__builtin_HEXAGON_V6_vzb", + "llvm.hexagon.V6.vzb.128B" => "__builtin_HEXAGON_V6_vzb_128B", + "llvm.hexagon.V6.vzh" => "__builtin_HEXAGON_V6_vzh", + "llvm.hexagon.V6.vzh.128B" => "__builtin_HEXAGON_V6_vzh_128B", + "llvm.hexagon.brev.ldb" => "__builtin_brev_ldb", + "llvm.hexagon.brev.ldd" => "__builtin_brev_ldd", + "llvm.hexagon.brev.ldh" => "__builtin_brev_ldh", + "llvm.hexagon.brev.ldub" => "__builtin_brev_ldub", + "llvm.hexagon.brev.lduh" => "__builtin_brev_lduh", + "llvm.hexagon.brev.ldw" => "__builtin_brev_ldw", + "llvm.hexagon.brev.stb" => "__builtin_brev_stb", + "llvm.hexagon.brev.std" => "__builtin_brev_std", + "llvm.hexagon.brev.sth" => "__builtin_brev_sth", + "llvm.hexagon.brev.sthhi" => "__builtin_brev_sthhi", + "llvm.hexagon.brev.stw" => "__builtin_brev_stw", + "llvm.hexagon.circ.ldb" => "__builtin_circ_ldb", + "llvm.hexagon.circ.ldd" => "__builtin_circ_ldd", + "llvm.hexagon.circ.ldh" => "__builtin_circ_ldh", + "llvm.hexagon.circ.ldub" => "__builtin_circ_ldub", + "llvm.hexagon.circ.lduh" => "__builtin_circ_lduh", + "llvm.hexagon.circ.ldw" => "__builtin_circ_ldw", + "llvm.hexagon.circ.stb" => "__builtin_circ_stb", + "llvm.hexagon.circ.std" => "__builtin_circ_std", + "llvm.hexagon.circ.sth" => "__builtin_circ_sth", + "llvm.hexagon.circ.sthhi" => "__builtin_circ_sthhi", + "llvm.hexagon.circ.stw" => "__builtin_circ_stw", + "llvm.hexagon.mm256i.vaddw" => "__builtin__mm256i_vaddw", + "llvm.hexagon.prefetch" => "__builtin_HEXAGON_prefetch", + // mips + "llvm.mips.absq.s.ph" => "__builtin_mips_absq_s_ph", + "llvm.mips.absq.s.qb" => "__builtin_mips_absq_s_qb", + "llvm.mips.absq.s.w" => "__builtin_mips_absq_s_w", + "llvm.mips.add.a.b" => "__builtin_msa_add_a_b", + "llvm.mips.add.a.d" => "__builtin_msa_add_a_d", + "llvm.mips.add.a.h" => "__builtin_msa_add_a_h", + "llvm.mips.add.a.w" => "__builtin_msa_add_a_w", + "llvm.mips.addq.ph" => "__builtin_mips_addq_ph", + "llvm.mips.addq.s.ph" => "__builtin_mips_addq_s_ph", + "llvm.mips.addq.s.w" => "__builtin_mips_addq_s_w", + "llvm.mips.addqh.ph" => "__builtin_mips_addqh_ph", + "llvm.mips.addqh.r.ph" => "__builtin_mips_addqh_r_ph", + "llvm.mips.addqh.r.w" => "__builtin_mips_addqh_r_w", + "llvm.mips.addqh.w" => "__builtin_mips_addqh_w", + "llvm.mips.adds.a.b" => "__builtin_msa_adds_a_b", + "llvm.mips.adds.a.d" => "__builtin_msa_adds_a_d", + "llvm.mips.adds.a.h" => "__builtin_msa_adds_a_h", + "llvm.mips.adds.a.w" => "__builtin_msa_adds_a_w", + "llvm.mips.adds.s.b" => "__builtin_msa_adds_s_b", + "llvm.mips.adds.s.d" => "__builtin_msa_adds_s_d", + "llvm.mips.adds.s.h" => "__builtin_msa_adds_s_h", + "llvm.mips.adds.s.w" => "__builtin_msa_adds_s_w", + "llvm.mips.adds.u.b" => "__builtin_msa_adds_u_b", + "llvm.mips.adds.u.d" => "__builtin_msa_adds_u_d", + "llvm.mips.adds.u.h" => "__builtin_msa_adds_u_h", + "llvm.mips.adds.u.w" => "__builtin_msa_adds_u_w", + "llvm.mips.addsc" => "__builtin_mips_addsc", + "llvm.mips.addu.ph" => "__builtin_mips_addu_ph", + "llvm.mips.addu.qb" => "__builtin_mips_addu_qb", + "llvm.mips.addu.s.ph" => "__builtin_mips_addu_s_ph", + "llvm.mips.addu.s.qb" => "__builtin_mips_addu_s_qb", + "llvm.mips.adduh.qb" => "__builtin_mips_adduh_qb", + "llvm.mips.adduh.r.qb" => "__builtin_mips_adduh_r_qb", + "llvm.mips.addv.b" => "__builtin_msa_addv_b", + "llvm.mips.addv.d" => "__builtin_msa_addv_d", + "llvm.mips.addv.h" => "__builtin_msa_addv_h", + "llvm.mips.addv.w" => "__builtin_msa_addv_w", + "llvm.mips.addvi.b" => "__builtin_msa_addvi_b", + "llvm.mips.addvi.d" => "__builtin_msa_addvi_d", + "llvm.mips.addvi.h" => "__builtin_msa_addvi_h", + "llvm.mips.addvi.w" => "__builtin_msa_addvi_w", + "llvm.mips.addwc" => "__builtin_mips_addwc", + "llvm.mips.and.v" => "__builtin_msa_and_v", + "llvm.mips.andi.b" => "__builtin_msa_andi_b", + "llvm.mips.append" => "__builtin_mips_append", + "llvm.mips.asub.s.b" => "__builtin_msa_asub_s_b", + "llvm.mips.asub.s.d" => "__builtin_msa_asub_s_d", + "llvm.mips.asub.s.h" => "__builtin_msa_asub_s_h", + "llvm.mips.asub.s.w" => "__builtin_msa_asub_s_w", + "llvm.mips.asub.u.b" => "__builtin_msa_asub_u_b", + "llvm.mips.asub.u.d" => "__builtin_msa_asub_u_d", + "llvm.mips.asub.u.h" => "__builtin_msa_asub_u_h", + "llvm.mips.asub.u.w" => "__builtin_msa_asub_u_w", + "llvm.mips.ave.s.b" => "__builtin_msa_ave_s_b", + "llvm.mips.ave.s.d" => "__builtin_msa_ave_s_d", + "llvm.mips.ave.s.h" => "__builtin_msa_ave_s_h", + "llvm.mips.ave.s.w" => "__builtin_msa_ave_s_w", + "llvm.mips.ave.u.b" => "__builtin_msa_ave_u_b", + "llvm.mips.ave.u.d" => "__builtin_msa_ave_u_d", + "llvm.mips.ave.u.h" => "__builtin_msa_ave_u_h", + "llvm.mips.ave.u.w" => "__builtin_msa_ave_u_w", + "llvm.mips.aver.s.b" => "__builtin_msa_aver_s_b", + "llvm.mips.aver.s.d" => "__builtin_msa_aver_s_d", + "llvm.mips.aver.s.h" => "__builtin_msa_aver_s_h", + "llvm.mips.aver.s.w" => "__builtin_msa_aver_s_w", + "llvm.mips.aver.u.b" => "__builtin_msa_aver_u_b", + "llvm.mips.aver.u.d" => "__builtin_msa_aver_u_d", + "llvm.mips.aver.u.h" => "__builtin_msa_aver_u_h", + "llvm.mips.aver.u.w" => "__builtin_msa_aver_u_w", + "llvm.mips.balign" => "__builtin_mips_balign", + "llvm.mips.bclr.b" => "__builtin_msa_bclr_b", + "llvm.mips.bclr.d" => "__builtin_msa_bclr_d", + "llvm.mips.bclr.h" => "__builtin_msa_bclr_h", + "llvm.mips.bclr.w" => "__builtin_msa_bclr_w", + "llvm.mips.bclri.b" => "__builtin_msa_bclri_b", + "llvm.mips.bclri.d" => "__builtin_msa_bclri_d", + "llvm.mips.bclri.h" => "__builtin_msa_bclri_h", + "llvm.mips.bclri.w" => "__builtin_msa_bclri_w", + "llvm.mips.binsl.b" => "__builtin_msa_binsl_b", + "llvm.mips.binsl.d" => "__builtin_msa_binsl_d", + "llvm.mips.binsl.h" => "__builtin_msa_binsl_h", + "llvm.mips.binsl.w" => "__builtin_msa_binsl_w", + "llvm.mips.binsli.b" => "__builtin_msa_binsli_b", + "llvm.mips.binsli.d" => "__builtin_msa_binsli_d", + "llvm.mips.binsli.h" => "__builtin_msa_binsli_h", + "llvm.mips.binsli.w" => "__builtin_msa_binsli_w", + "llvm.mips.binsr.b" => "__builtin_msa_binsr_b", + "llvm.mips.binsr.d" => "__builtin_msa_binsr_d", + "llvm.mips.binsr.h" => "__builtin_msa_binsr_h", + "llvm.mips.binsr.w" => "__builtin_msa_binsr_w", + "llvm.mips.binsri.b" => "__builtin_msa_binsri_b", + "llvm.mips.binsri.d" => "__builtin_msa_binsri_d", + "llvm.mips.binsri.h" => "__builtin_msa_binsri_h", + "llvm.mips.binsri.w" => "__builtin_msa_binsri_w", + "llvm.mips.bitrev" => "__builtin_mips_bitrev", + "llvm.mips.bmnz.v" => "__builtin_msa_bmnz_v", + "llvm.mips.bmnzi.b" => "__builtin_msa_bmnzi_b", + "llvm.mips.bmz.v" => "__builtin_msa_bmz_v", + "llvm.mips.bmzi.b" => "__builtin_msa_bmzi_b", + "llvm.mips.bneg.b" => "__builtin_msa_bneg_b", + "llvm.mips.bneg.d" => "__builtin_msa_bneg_d", + "llvm.mips.bneg.h" => "__builtin_msa_bneg_h", + "llvm.mips.bneg.w" => "__builtin_msa_bneg_w", + "llvm.mips.bnegi.b" => "__builtin_msa_bnegi_b", + "llvm.mips.bnegi.d" => "__builtin_msa_bnegi_d", + "llvm.mips.bnegi.h" => "__builtin_msa_bnegi_h", + "llvm.mips.bnegi.w" => "__builtin_msa_bnegi_w", + "llvm.mips.bnz.b" => "__builtin_msa_bnz_b", + "llvm.mips.bnz.d" => "__builtin_msa_bnz_d", + "llvm.mips.bnz.h" => "__builtin_msa_bnz_h", + "llvm.mips.bnz.v" => "__builtin_msa_bnz_v", + "llvm.mips.bnz.w" => "__builtin_msa_bnz_w", + "llvm.mips.bposge32" => "__builtin_mips_bposge32", + "llvm.mips.bsel.v" => "__builtin_msa_bsel_v", + "llvm.mips.bseli.b" => "__builtin_msa_bseli_b", + "llvm.mips.bset.b" => "__builtin_msa_bset_b", + "llvm.mips.bset.d" => "__builtin_msa_bset_d", + "llvm.mips.bset.h" => "__builtin_msa_bset_h", + "llvm.mips.bset.w" => "__builtin_msa_bset_w", + "llvm.mips.bseti.b" => "__builtin_msa_bseti_b", + "llvm.mips.bseti.d" => "__builtin_msa_bseti_d", + "llvm.mips.bseti.h" => "__builtin_msa_bseti_h", + "llvm.mips.bseti.w" => "__builtin_msa_bseti_w", + "llvm.mips.bz.b" => "__builtin_msa_bz_b", + "llvm.mips.bz.d" => "__builtin_msa_bz_d", + "llvm.mips.bz.h" => "__builtin_msa_bz_h", + "llvm.mips.bz.v" => "__builtin_msa_bz_v", + "llvm.mips.bz.w" => "__builtin_msa_bz_w", + "llvm.mips.ceq.b" => "__builtin_msa_ceq_b", + "llvm.mips.ceq.d" => "__builtin_msa_ceq_d", + "llvm.mips.ceq.h" => "__builtin_msa_ceq_h", + "llvm.mips.ceq.w" => "__builtin_msa_ceq_w", + "llvm.mips.ceqi.b" => "__builtin_msa_ceqi_b", + "llvm.mips.ceqi.d" => "__builtin_msa_ceqi_d", + "llvm.mips.ceqi.h" => "__builtin_msa_ceqi_h", + "llvm.mips.ceqi.w" => "__builtin_msa_ceqi_w", + "llvm.mips.cfcmsa" => "__builtin_msa_cfcmsa", + "llvm.mips.cle.s.b" => "__builtin_msa_cle_s_b", + "llvm.mips.cle.s.d" => "__builtin_msa_cle_s_d", + "llvm.mips.cle.s.h" => "__builtin_msa_cle_s_h", + "llvm.mips.cle.s.w" => "__builtin_msa_cle_s_w", + "llvm.mips.cle.u.b" => "__builtin_msa_cle_u_b", + "llvm.mips.cle.u.d" => "__builtin_msa_cle_u_d", + "llvm.mips.cle.u.h" => "__builtin_msa_cle_u_h", + "llvm.mips.cle.u.w" => "__builtin_msa_cle_u_w", + "llvm.mips.clei.s.b" => "__builtin_msa_clei_s_b", + "llvm.mips.clei.s.d" => "__builtin_msa_clei_s_d", + "llvm.mips.clei.s.h" => "__builtin_msa_clei_s_h", + "llvm.mips.clei.s.w" => "__builtin_msa_clei_s_w", + "llvm.mips.clei.u.b" => "__builtin_msa_clei_u_b", + "llvm.mips.clei.u.d" => "__builtin_msa_clei_u_d", + "llvm.mips.clei.u.h" => "__builtin_msa_clei_u_h", + "llvm.mips.clei.u.w" => "__builtin_msa_clei_u_w", + "llvm.mips.clt.s.b" => "__builtin_msa_clt_s_b", + "llvm.mips.clt.s.d" => "__builtin_msa_clt_s_d", + "llvm.mips.clt.s.h" => "__builtin_msa_clt_s_h", + "llvm.mips.clt.s.w" => "__builtin_msa_clt_s_w", + "llvm.mips.clt.u.b" => "__builtin_msa_clt_u_b", + "llvm.mips.clt.u.d" => "__builtin_msa_clt_u_d", + "llvm.mips.clt.u.h" => "__builtin_msa_clt_u_h", + "llvm.mips.clt.u.w" => "__builtin_msa_clt_u_w", + "llvm.mips.clti.s.b" => "__builtin_msa_clti_s_b", + "llvm.mips.clti.s.d" => "__builtin_msa_clti_s_d", + "llvm.mips.clti.s.h" => "__builtin_msa_clti_s_h", + "llvm.mips.clti.s.w" => "__builtin_msa_clti_s_w", + "llvm.mips.clti.u.b" => "__builtin_msa_clti_u_b", + "llvm.mips.clti.u.d" => "__builtin_msa_clti_u_d", + "llvm.mips.clti.u.h" => "__builtin_msa_clti_u_h", + "llvm.mips.clti.u.w" => "__builtin_msa_clti_u_w", + "llvm.mips.cmp.eq.ph" => "__builtin_mips_cmp_eq_ph", + "llvm.mips.cmp.le.ph" => "__builtin_mips_cmp_le_ph", + "llvm.mips.cmp.lt.ph" => "__builtin_mips_cmp_lt_ph", + "llvm.mips.cmpgdu.eq.qb" => "__builtin_mips_cmpgdu_eq_qb", + "llvm.mips.cmpgdu.le.qb" => "__builtin_mips_cmpgdu_le_qb", + "llvm.mips.cmpgdu.lt.qb" => "__builtin_mips_cmpgdu_lt_qb", + "llvm.mips.cmpgu.eq.qb" => "__builtin_mips_cmpgu_eq_qb", + "llvm.mips.cmpgu.le.qb" => "__builtin_mips_cmpgu_le_qb", + "llvm.mips.cmpgu.lt.qb" => "__builtin_mips_cmpgu_lt_qb", + "llvm.mips.cmpu.eq.qb" => "__builtin_mips_cmpu_eq_qb", + "llvm.mips.cmpu.le.qb" => "__builtin_mips_cmpu_le_qb", + "llvm.mips.cmpu.lt.qb" => "__builtin_mips_cmpu_lt_qb", + "llvm.mips.copy.s.b" => "__builtin_msa_copy_s_b", + "llvm.mips.copy.s.d" => "__builtin_msa_copy_s_d", + "llvm.mips.copy.s.h" => "__builtin_msa_copy_s_h", + "llvm.mips.copy.s.w" => "__builtin_msa_copy_s_w", + "llvm.mips.copy.u.b" => "__builtin_msa_copy_u_b", + "llvm.mips.copy.u.d" => "__builtin_msa_copy_u_d", + "llvm.mips.copy.u.h" => "__builtin_msa_copy_u_h", + "llvm.mips.copy.u.w" => "__builtin_msa_copy_u_w", + "llvm.mips.ctcmsa" => "__builtin_msa_ctcmsa", + "llvm.mips.div.s.b" => "__builtin_msa_div_s_b", + "llvm.mips.div.s.d" => "__builtin_msa_div_s_d", + "llvm.mips.div.s.h" => "__builtin_msa_div_s_h", + "llvm.mips.div.s.w" => "__builtin_msa_div_s_w", + "llvm.mips.div.u.b" => "__builtin_msa_div_u_b", + "llvm.mips.div.u.d" => "__builtin_msa_div_u_d", + "llvm.mips.div.u.h" => "__builtin_msa_div_u_h", + "llvm.mips.div.u.w" => "__builtin_msa_div_u_w", + "llvm.mips.dlsa" => "__builtin_mips_dlsa", + "llvm.mips.dotp.s.d" => "__builtin_msa_dotp_s_d", + "llvm.mips.dotp.s.h" => "__builtin_msa_dotp_s_h", + "llvm.mips.dotp.s.w" => "__builtin_msa_dotp_s_w", + "llvm.mips.dotp.u.d" => "__builtin_msa_dotp_u_d", + "llvm.mips.dotp.u.h" => "__builtin_msa_dotp_u_h", + "llvm.mips.dotp.u.w" => "__builtin_msa_dotp_u_w", + "llvm.mips.dpa.w.ph" => "__builtin_mips_dpa_w_ph", + "llvm.mips.dpadd.s.d" => "__builtin_msa_dpadd_s_d", + "llvm.mips.dpadd.s.h" => "__builtin_msa_dpadd_s_h", + "llvm.mips.dpadd.s.w" => "__builtin_msa_dpadd_s_w", + "llvm.mips.dpadd.u.d" => "__builtin_msa_dpadd_u_d", + "llvm.mips.dpadd.u.h" => "__builtin_msa_dpadd_u_h", + "llvm.mips.dpadd.u.w" => "__builtin_msa_dpadd_u_w", + "llvm.mips.dpaq.s.w.ph" => "__builtin_mips_dpaq_s_w_ph", + "llvm.mips.dpaq.sa.l.w" => "__builtin_mips_dpaq_sa_l_w", + "llvm.mips.dpaqx.s.w.ph" => "__builtin_mips_dpaqx_s_w_ph", + "llvm.mips.dpaqx.sa.w.ph" => "__builtin_mips_dpaqx_sa_w_ph", + "llvm.mips.dpau.h.qbl" => "__builtin_mips_dpau_h_qbl", + "llvm.mips.dpau.h.qbr" => "__builtin_mips_dpau_h_qbr", + "llvm.mips.dpax.w.ph" => "__builtin_mips_dpax_w_ph", + "llvm.mips.dps.w.ph" => "__builtin_mips_dps_w_ph", + "llvm.mips.dpsq.s.w.ph" => "__builtin_mips_dpsq_s_w_ph", + "llvm.mips.dpsq.sa.l.w" => "__builtin_mips_dpsq_sa_l_w", + "llvm.mips.dpsqx.s.w.ph" => "__builtin_mips_dpsqx_s_w_ph", + "llvm.mips.dpsqx.sa.w.ph" => "__builtin_mips_dpsqx_sa_w_ph", + "llvm.mips.dpsu.h.qbl" => "__builtin_mips_dpsu_h_qbl", + "llvm.mips.dpsu.h.qbr" => "__builtin_mips_dpsu_h_qbr", + "llvm.mips.dpsub.s.d" => "__builtin_msa_dpsub_s_d", + "llvm.mips.dpsub.s.h" => "__builtin_msa_dpsub_s_h", + "llvm.mips.dpsub.s.w" => "__builtin_msa_dpsub_s_w", + "llvm.mips.dpsub.u.d" => "__builtin_msa_dpsub_u_d", + "llvm.mips.dpsub.u.h" => "__builtin_msa_dpsub_u_h", + "llvm.mips.dpsub.u.w" => "__builtin_msa_dpsub_u_w", + "llvm.mips.dpsx.w.ph" => "__builtin_mips_dpsx_w_ph", + "llvm.mips.extp" => "__builtin_mips_extp", + "llvm.mips.extpdp" => "__builtin_mips_extpdp", + "llvm.mips.extr.r.w" => "__builtin_mips_extr_r_w", + "llvm.mips.extr.rs.w" => "__builtin_mips_extr_rs_w", + "llvm.mips.extr.s.h" => "__builtin_mips_extr_s_h", + "llvm.mips.extr.w" => "__builtin_mips_extr_w", + "llvm.mips.fadd.d" => "__builtin_msa_fadd_d", + "llvm.mips.fadd.w" => "__builtin_msa_fadd_w", + "llvm.mips.fcaf.d" => "__builtin_msa_fcaf_d", + "llvm.mips.fcaf.w" => "__builtin_msa_fcaf_w", + "llvm.mips.fceq.d" => "__builtin_msa_fceq_d", + "llvm.mips.fceq.w" => "__builtin_msa_fceq_w", + "llvm.mips.fclass.d" => "__builtin_msa_fclass_d", + "llvm.mips.fclass.w" => "__builtin_msa_fclass_w", + "llvm.mips.fcle.d" => "__builtin_msa_fcle_d", + "llvm.mips.fcle.w" => "__builtin_msa_fcle_w", + "llvm.mips.fclt.d" => "__builtin_msa_fclt_d", + "llvm.mips.fclt.w" => "__builtin_msa_fclt_w", + "llvm.mips.fcne.d" => "__builtin_msa_fcne_d", + "llvm.mips.fcne.w" => "__builtin_msa_fcne_w", + "llvm.mips.fcor.d" => "__builtin_msa_fcor_d", + "llvm.mips.fcor.w" => "__builtin_msa_fcor_w", + "llvm.mips.fcueq.d" => "__builtin_msa_fcueq_d", + "llvm.mips.fcueq.w" => "__builtin_msa_fcueq_w", + "llvm.mips.fcule.d" => "__builtin_msa_fcule_d", + "llvm.mips.fcule.w" => "__builtin_msa_fcule_w", + "llvm.mips.fcult.d" => "__builtin_msa_fcult_d", + "llvm.mips.fcult.w" => "__builtin_msa_fcult_w", + "llvm.mips.fcun.d" => "__builtin_msa_fcun_d", + "llvm.mips.fcun.w" => "__builtin_msa_fcun_w", + "llvm.mips.fcune.d" => "__builtin_msa_fcune_d", + "llvm.mips.fcune.w" => "__builtin_msa_fcune_w", + "llvm.mips.fdiv.d" => "__builtin_msa_fdiv_d", + "llvm.mips.fdiv.w" => "__builtin_msa_fdiv_w", + "llvm.mips.fexdo.h" => "__builtin_msa_fexdo_h", + "llvm.mips.fexdo.w" => "__builtin_msa_fexdo_w", + "llvm.mips.fexp2.d" => "__builtin_msa_fexp2_d", + "llvm.mips.fexp2.w" => "__builtin_msa_fexp2_w", + "llvm.mips.fexupl.d" => "__builtin_msa_fexupl_d", + "llvm.mips.fexupl.w" => "__builtin_msa_fexupl_w", + "llvm.mips.fexupr.d" => "__builtin_msa_fexupr_d", + "llvm.mips.fexupr.w" => "__builtin_msa_fexupr_w", + "llvm.mips.ffint.s.d" => "__builtin_msa_ffint_s_d", + "llvm.mips.ffint.s.w" => "__builtin_msa_ffint_s_w", + "llvm.mips.ffint.u.d" => "__builtin_msa_ffint_u_d", + "llvm.mips.ffint.u.w" => "__builtin_msa_ffint_u_w", + "llvm.mips.ffql.d" => "__builtin_msa_ffql_d", + "llvm.mips.ffql.w" => "__builtin_msa_ffql_w", + "llvm.mips.ffqr.d" => "__builtin_msa_ffqr_d", + "llvm.mips.ffqr.w" => "__builtin_msa_ffqr_w", + "llvm.mips.fill.b" => "__builtin_msa_fill_b", + "llvm.mips.fill.d" => "__builtin_msa_fill_d", + "llvm.mips.fill.h" => "__builtin_msa_fill_h", + "llvm.mips.fill.w" => "__builtin_msa_fill_w", + "llvm.mips.flog2.d" => "__builtin_msa_flog2_d", + "llvm.mips.flog2.w" => "__builtin_msa_flog2_w", + "llvm.mips.fmadd.d" => "__builtin_msa_fmadd_d", + "llvm.mips.fmadd.w" => "__builtin_msa_fmadd_w", + "llvm.mips.fmax.a.d" => "__builtin_msa_fmax_a_d", + "llvm.mips.fmax.a.w" => "__builtin_msa_fmax_a_w", + "llvm.mips.fmax.d" => "__builtin_msa_fmax_d", + "llvm.mips.fmax.w" => "__builtin_msa_fmax_w", + "llvm.mips.fmin.a.d" => "__builtin_msa_fmin_a_d", + "llvm.mips.fmin.a.w" => "__builtin_msa_fmin_a_w", + "llvm.mips.fmin.d" => "__builtin_msa_fmin_d", + "llvm.mips.fmin.w" => "__builtin_msa_fmin_w", + "llvm.mips.fmsub.d" => "__builtin_msa_fmsub_d", + "llvm.mips.fmsub.w" => "__builtin_msa_fmsub_w", + "llvm.mips.fmul.d" => "__builtin_msa_fmul_d", + "llvm.mips.fmul.w" => "__builtin_msa_fmul_w", + "llvm.mips.frcp.d" => "__builtin_msa_frcp_d", + "llvm.mips.frcp.w" => "__builtin_msa_frcp_w", + "llvm.mips.frint.d" => "__builtin_msa_frint_d", + "llvm.mips.frint.w" => "__builtin_msa_frint_w", + "llvm.mips.frsqrt.d" => "__builtin_msa_frsqrt_d", + "llvm.mips.frsqrt.w" => "__builtin_msa_frsqrt_w", + "llvm.mips.fsaf.d" => "__builtin_msa_fsaf_d", + "llvm.mips.fsaf.w" => "__builtin_msa_fsaf_w", + "llvm.mips.fseq.d" => "__builtin_msa_fseq_d", + "llvm.mips.fseq.w" => "__builtin_msa_fseq_w", + "llvm.mips.fsle.d" => "__builtin_msa_fsle_d", + "llvm.mips.fsle.w" => "__builtin_msa_fsle_w", + "llvm.mips.fslt.d" => "__builtin_msa_fslt_d", + "llvm.mips.fslt.w" => "__builtin_msa_fslt_w", + "llvm.mips.fsne.d" => "__builtin_msa_fsne_d", + "llvm.mips.fsne.w" => "__builtin_msa_fsne_w", + "llvm.mips.fsor.d" => "__builtin_msa_fsor_d", + "llvm.mips.fsor.w" => "__builtin_msa_fsor_w", + "llvm.mips.fsqrt.d" => "__builtin_msa_fsqrt_d", + "llvm.mips.fsqrt.w" => "__builtin_msa_fsqrt_w", + "llvm.mips.fsub.d" => "__builtin_msa_fsub_d", + "llvm.mips.fsub.w" => "__builtin_msa_fsub_w", + "llvm.mips.fsueq.d" => "__builtin_msa_fsueq_d", + "llvm.mips.fsueq.w" => "__builtin_msa_fsueq_w", + "llvm.mips.fsule.d" => "__builtin_msa_fsule_d", + "llvm.mips.fsule.w" => "__builtin_msa_fsule_w", + "llvm.mips.fsult.d" => "__builtin_msa_fsult_d", + "llvm.mips.fsult.w" => "__builtin_msa_fsult_w", + "llvm.mips.fsun.d" => "__builtin_msa_fsun_d", + "llvm.mips.fsun.w" => "__builtin_msa_fsun_w", + "llvm.mips.fsune.d" => "__builtin_msa_fsune_d", + "llvm.mips.fsune.w" => "__builtin_msa_fsune_w", + "llvm.mips.ftint.s.d" => "__builtin_msa_ftint_s_d", + "llvm.mips.ftint.s.w" => "__builtin_msa_ftint_s_w", + "llvm.mips.ftint.u.d" => "__builtin_msa_ftint_u_d", + "llvm.mips.ftint.u.w" => "__builtin_msa_ftint_u_w", + "llvm.mips.ftq.h" => "__builtin_msa_ftq_h", + "llvm.mips.ftq.w" => "__builtin_msa_ftq_w", + "llvm.mips.ftrunc.s.d" => "__builtin_msa_ftrunc_s_d", + "llvm.mips.ftrunc.s.w" => "__builtin_msa_ftrunc_s_w", + "llvm.mips.ftrunc.u.d" => "__builtin_msa_ftrunc_u_d", + "llvm.mips.ftrunc.u.w" => "__builtin_msa_ftrunc_u_w", + "llvm.mips.hadd.s.d" => "__builtin_msa_hadd_s_d", + "llvm.mips.hadd.s.h" => "__builtin_msa_hadd_s_h", + "llvm.mips.hadd.s.w" => "__builtin_msa_hadd_s_w", + "llvm.mips.hadd.u.d" => "__builtin_msa_hadd_u_d", + "llvm.mips.hadd.u.h" => "__builtin_msa_hadd_u_h", + "llvm.mips.hadd.u.w" => "__builtin_msa_hadd_u_w", + "llvm.mips.hsub.s.d" => "__builtin_msa_hsub_s_d", + "llvm.mips.hsub.s.h" => "__builtin_msa_hsub_s_h", + "llvm.mips.hsub.s.w" => "__builtin_msa_hsub_s_w", + "llvm.mips.hsub.u.d" => "__builtin_msa_hsub_u_d", + "llvm.mips.hsub.u.h" => "__builtin_msa_hsub_u_h", + "llvm.mips.hsub.u.w" => "__builtin_msa_hsub_u_w", + "llvm.mips.ilvev.b" => "__builtin_msa_ilvev_b", + "llvm.mips.ilvev.d" => "__builtin_msa_ilvev_d", + "llvm.mips.ilvev.h" => "__builtin_msa_ilvev_h", + "llvm.mips.ilvev.w" => "__builtin_msa_ilvev_w", + "llvm.mips.ilvl.b" => "__builtin_msa_ilvl_b", + "llvm.mips.ilvl.d" => "__builtin_msa_ilvl_d", + "llvm.mips.ilvl.h" => "__builtin_msa_ilvl_h", + "llvm.mips.ilvl.w" => "__builtin_msa_ilvl_w", + "llvm.mips.ilvod.b" => "__builtin_msa_ilvod_b", + "llvm.mips.ilvod.d" => "__builtin_msa_ilvod_d", + "llvm.mips.ilvod.h" => "__builtin_msa_ilvod_h", + "llvm.mips.ilvod.w" => "__builtin_msa_ilvod_w", + "llvm.mips.ilvr.b" => "__builtin_msa_ilvr_b", + "llvm.mips.ilvr.d" => "__builtin_msa_ilvr_d", + "llvm.mips.ilvr.h" => "__builtin_msa_ilvr_h", + "llvm.mips.ilvr.w" => "__builtin_msa_ilvr_w", + "llvm.mips.insert.b" => "__builtin_msa_insert_b", + "llvm.mips.insert.d" => "__builtin_msa_insert_d", + "llvm.mips.insert.h" => "__builtin_msa_insert_h", + "llvm.mips.insert.w" => "__builtin_msa_insert_w", + "llvm.mips.insv" => "__builtin_mips_insv", + "llvm.mips.insve.b" => "__builtin_msa_insve_b", + "llvm.mips.insve.d" => "__builtin_msa_insve_d", + "llvm.mips.insve.h" => "__builtin_msa_insve_h", + "llvm.mips.insve.w" => "__builtin_msa_insve_w", + "llvm.mips.lbux" => "__builtin_mips_lbux", + "llvm.mips.ld.b" => "__builtin_msa_ld_b", + "llvm.mips.ld.d" => "__builtin_msa_ld_d", + "llvm.mips.ld.h" => "__builtin_msa_ld_h", + "llvm.mips.ld.w" => "__builtin_msa_ld_w", + "llvm.mips.ldi.b" => "__builtin_msa_ldi_b", + "llvm.mips.ldi.d" => "__builtin_msa_ldi_d", + "llvm.mips.ldi.h" => "__builtin_msa_ldi_h", + "llvm.mips.ldi.w" => "__builtin_msa_ldi_w", + "llvm.mips.ldr.d" => "__builtin_msa_ldr_d", + "llvm.mips.ldr.w" => "__builtin_msa_ldr_w", + "llvm.mips.lhx" => "__builtin_mips_lhx", + "llvm.mips.lsa" => "__builtin_mips_lsa", + "llvm.mips.lwx" => "__builtin_mips_lwx", + "llvm.mips.madd" => "__builtin_mips_madd", + "llvm.mips.madd.q.h" => "__builtin_msa_madd_q_h", + "llvm.mips.madd.q.w" => "__builtin_msa_madd_q_w", + "llvm.mips.maddr.q.h" => "__builtin_msa_maddr_q_h", + "llvm.mips.maddr.q.w" => "__builtin_msa_maddr_q_w", + "llvm.mips.maddu" => "__builtin_mips_maddu", + "llvm.mips.maddv.b" => "__builtin_msa_maddv_b", + "llvm.mips.maddv.d" => "__builtin_msa_maddv_d", + "llvm.mips.maddv.h" => "__builtin_msa_maddv_h", + "llvm.mips.maddv.w" => "__builtin_msa_maddv_w", + "llvm.mips.maq.s.w.phl" => "__builtin_mips_maq_s_w_phl", + "llvm.mips.maq.s.w.phr" => "__builtin_mips_maq_s_w_phr", + "llvm.mips.maq.sa.w.phl" => "__builtin_mips_maq_sa_w_phl", + "llvm.mips.maq.sa.w.phr" => "__builtin_mips_maq_sa_w_phr", + "llvm.mips.max.a.b" => "__builtin_msa_max_a_b", + "llvm.mips.max.a.d" => "__builtin_msa_max_a_d", + "llvm.mips.max.a.h" => "__builtin_msa_max_a_h", + "llvm.mips.max.a.w" => "__builtin_msa_max_a_w", + "llvm.mips.max.s.b" => "__builtin_msa_max_s_b", + "llvm.mips.max.s.d" => "__builtin_msa_max_s_d", + "llvm.mips.max.s.h" => "__builtin_msa_max_s_h", + "llvm.mips.max.s.w" => "__builtin_msa_max_s_w", + "llvm.mips.max.u.b" => "__builtin_msa_max_u_b", + "llvm.mips.max.u.d" => "__builtin_msa_max_u_d", + "llvm.mips.max.u.h" => "__builtin_msa_max_u_h", + "llvm.mips.max.u.w" => "__builtin_msa_max_u_w", + "llvm.mips.maxi.s.b" => "__builtin_msa_maxi_s_b", + "llvm.mips.maxi.s.d" => "__builtin_msa_maxi_s_d", + "llvm.mips.maxi.s.h" => "__builtin_msa_maxi_s_h", + "llvm.mips.maxi.s.w" => "__builtin_msa_maxi_s_w", + "llvm.mips.maxi.u.b" => "__builtin_msa_maxi_u_b", + "llvm.mips.maxi.u.d" => "__builtin_msa_maxi_u_d", + "llvm.mips.maxi.u.h" => "__builtin_msa_maxi_u_h", + "llvm.mips.maxi.u.w" => "__builtin_msa_maxi_u_w", + "llvm.mips.min.a.b" => "__builtin_msa_min_a_b", + "llvm.mips.min.a.d" => "__builtin_msa_min_a_d", + "llvm.mips.min.a.h" => "__builtin_msa_min_a_h", + "llvm.mips.min.a.w" => "__builtin_msa_min_a_w", + "llvm.mips.min.s.b" => "__builtin_msa_min_s_b", + "llvm.mips.min.s.d" => "__builtin_msa_min_s_d", + "llvm.mips.min.s.h" => "__builtin_msa_min_s_h", + "llvm.mips.min.s.w" => "__builtin_msa_min_s_w", + "llvm.mips.min.u.b" => "__builtin_msa_min_u_b", + "llvm.mips.min.u.d" => "__builtin_msa_min_u_d", + "llvm.mips.min.u.h" => "__builtin_msa_min_u_h", + "llvm.mips.min.u.w" => "__builtin_msa_min_u_w", + "llvm.mips.mini.s.b" => "__builtin_msa_mini_s_b", + "llvm.mips.mini.s.d" => "__builtin_msa_mini_s_d", + "llvm.mips.mini.s.h" => "__builtin_msa_mini_s_h", + "llvm.mips.mini.s.w" => "__builtin_msa_mini_s_w", + "llvm.mips.mini.u.b" => "__builtin_msa_mini_u_b", + "llvm.mips.mini.u.d" => "__builtin_msa_mini_u_d", + "llvm.mips.mini.u.h" => "__builtin_msa_mini_u_h", + "llvm.mips.mini.u.w" => "__builtin_msa_mini_u_w", + "llvm.mips.mod.s.b" => "__builtin_msa_mod_s_b", + "llvm.mips.mod.s.d" => "__builtin_msa_mod_s_d", + "llvm.mips.mod.s.h" => "__builtin_msa_mod_s_h", + "llvm.mips.mod.s.w" => "__builtin_msa_mod_s_w", + "llvm.mips.mod.u.b" => "__builtin_msa_mod_u_b", + "llvm.mips.mod.u.d" => "__builtin_msa_mod_u_d", + "llvm.mips.mod.u.h" => "__builtin_msa_mod_u_h", + "llvm.mips.mod.u.w" => "__builtin_msa_mod_u_w", + "llvm.mips.modsub" => "__builtin_mips_modsub", + "llvm.mips.move.v" => "__builtin_msa_move_v", + "llvm.mips.msub" => "__builtin_mips_msub", + "llvm.mips.msub.q.h" => "__builtin_msa_msub_q_h", + "llvm.mips.msub.q.w" => "__builtin_msa_msub_q_w", + "llvm.mips.msubr.q.h" => "__builtin_msa_msubr_q_h", + "llvm.mips.msubr.q.w" => "__builtin_msa_msubr_q_w", + "llvm.mips.msubu" => "__builtin_mips_msubu", + "llvm.mips.msubv.b" => "__builtin_msa_msubv_b", + "llvm.mips.msubv.d" => "__builtin_msa_msubv_d", + "llvm.mips.msubv.h" => "__builtin_msa_msubv_h", + "llvm.mips.msubv.w" => "__builtin_msa_msubv_w", + "llvm.mips.mthlip" => "__builtin_mips_mthlip", + "llvm.mips.mul.ph" => "__builtin_mips_mul_ph", + "llvm.mips.mul.q.h" => "__builtin_msa_mul_q_h", + "llvm.mips.mul.q.w" => "__builtin_msa_mul_q_w", + "llvm.mips.mul.s.ph" => "__builtin_mips_mul_s_ph", + "llvm.mips.muleq.s.w.phl" => "__builtin_mips_muleq_s_w_phl", + "llvm.mips.muleq.s.w.phr" => "__builtin_mips_muleq_s_w_phr", + "llvm.mips.muleu.s.ph.qbl" => "__builtin_mips_muleu_s_ph_qbl", + "llvm.mips.muleu.s.ph.qbr" => "__builtin_mips_muleu_s_ph_qbr", + "llvm.mips.mulq.rs.ph" => "__builtin_mips_mulq_rs_ph", + "llvm.mips.mulq.rs.w" => "__builtin_mips_mulq_rs_w", + "llvm.mips.mulq.s.ph" => "__builtin_mips_mulq_s_ph", + "llvm.mips.mulq.s.w" => "__builtin_mips_mulq_s_w", + "llvm.mips.mulr.q.h" => "__builtin_msa_mulr_q_h", + "llvm.mips.mulr.q.w" => "__builtin_msa_mulr_q_w", + "llvm.mips.mulsa.w.ph" => "__builtin_mips_mulsa_w_ph", + "llvm.mips.mulsaq.s.w.ph" => "__builtin_mips_mulsaq_s_w_ph", + "llvm.mips.mult" => "__builtin_mips_mult", + "llvm.mips.multu" => "__builtin_mips_multu", + "llvm.mips.mulv.b" => "__builtin_msa_mulv_b", + "llvm.mips.mulv.d" => "__builtin_msa_mulv_d", + "llvm.mips.mulv.h" => "__builtin_msa_mulv_h", + "llvm.mips.mulv.w" => "__builtin_msa_mulv_w", + "llvm.mips.nloc.b" => "__builtin_msa_nloc_b", + "llvm.mips.nloc.d" => "__builtin_msa_nloc_d", + "llvm.mips.nloc.h" => "__builtin_msa_nloc_h", + "llvm.mips.nloc.w" => "__builtin_msa_nloc_w", + "llvm.mips.nlzc.b" => "__builtin_msa_nlzc_b", + "llvm.mips.nlzc.d" => "__builtin_msa_nlzc_d", + "llvm.mips.nlzc.h" => "__builtin_msa_nlzc_h", + "llvm.mips.nlzc.w" => "__builtin_msa_nlzc_w", + "llvm.mips.nor.v" => "__builtin_msa_nor_v", + "llvm.mips.nori.b" => "__builtin_msa_nori_b", + "llvm.mips.or.v" => "__builtin_msa_or_v", + "llvm.mips.ori.b" => "__builtin_msa_ori_b", + "llvm.mips.packrl.ph" => "__builtin_mips_packrl_ph", + "llvm.mips.pckev.b" => "__builtin_msa_pckev_b", + "llvm.mips.pckev.d" => "__builtin_msa_pckev_d", + "llvm.mips.pckev.h" => "__builtin_msa_pckev_h", + "llvm.mips.pckev.w" => "__builtin_msa_pckev_w", + "llvm.mips.pckod.b" => "__builtin_msa_pckod_b", + "llvm.mips.pckod.d" => "__builtin_msa_pckod_d", + "llvm.mips.pckod.h" => "__builtin_msa_pckod_h", + "llvm.mips.pckod.w" => "__builtin_msa_pckod_w", + "llvm.mips.pcnt.b" => "__builtin_msa_pcnt_b", + "llvm.mips.pcnt.d" => "__builtin_msa_pcnt_d", + "llvm.mips.pcnt.h" => "__builtin_msa_pcnt_h", + "llvm.mips.pcnt.w" => "__builtin_msa_pcnt_w", + "llvm.mips.pick.ph" => "__builtin_mips_pick_ph", + "llvm.mips.pick.qb" => "__builtin_mips_pick_qb", + "llvm.mips.preceq.w.phl" => "__builtin_mips_preceq_w_phl", + "llvm.mips.preceq.w.phr" => "__builtin_mips_preceq_w_phr", + "llvm.mips.precequ.ph.qbl" => "__builtin_mips_precequ_ph_qbl", + "llvm.mips.precequ.ph.qbla" => "__builtin_mips_precequ_ph_qbla", + "llvm.mips.precequ.ph.qbr" => "__builtin_mips_precequ_ph_qbr", + "llvm.mips.precequ.ph.qbra" => "__builtin_mips_precequ_ph_qbra", + "llvm.mips.preceu.ph.qbl" => "__builtin_mips_preceu_ph_qbl", + "llvm.mips.preceu.ph.qbla" => "__builtin_mips_preceu_ph_qbla", + "llvm.mips.preceu.ph.qbr" => "__builtin_mips_preceu_ph_qbr", + "llvm.mips.preceu.ph.qbra" => "__builtin_mips_preceu_ph_qbra", + "llvm.mips.precr.qb.ph" => "__builtin_mips_precr_qb_ph", + "llvm.mips.precr.sra.ph.w" => "__builtin_mips_precr_sra_ph_w", + "llvm.mips.precr.sra.r.ph.w" => "__builtin_mips_precr_sra_r_ph_w", + "llvm.mips.precrq.ph.w" => "__builtin_mips_precrq_ph_w", + "llvm.mips.precrq.qb.ph" => "__builtin_mips_precrq_qb_ph", + "llvm.mips.precrq.rs.ph.w" => "__builtin_mips_precrq_rs_ph_w", + "llvm.mips.precrqu.s.qb.ph" => "__builtin_mips_precrqu_s_qb_ph", + "llvm.mips.prepend" => "__builtin_mips_prepend", + "llvm.mips.raddu.w.qb" => "__builtin_mips_raddu_w_qb", + "llvm.mips.rddsp" => "__builtin_mips_rddsp", + "llvm.mips.repl.ph" => "__builtin_mips_repl_ph", + "llvm.mips.repl.qb" => "__builtin_mips_repl_qb", + "llvm.mips.sat.s.b" => "__builtin_msa_sat_s_b", + "llvm.mips.sat.s.d" => "__builtin_msa_sat_s_d", + "llvm.mips.sat.s.h" => "__builtin_msa_sat_s_h", + "llvm.mips.sat.s.w" => "__builtin_msa_sat_s_w", + "llvm.mips.sat.u.b" => "__builtin_msa_sat_u_b", + "llvm.mips.sat.u.d" => "__builtin_msa_sat_u_d", + "llvm.mips.sat.u.h" => "__builtin_msa_sat_u_h", + "llvm.mips.sat.u.w" => "__builtin_msa_sat_u_w", + "llvm.mips.shf.b" => "__builtin_msa_shf_b", + "llvm.mips.shf.h" => "__builtin_msa_shf_h", + "llvm.mips.shf.w" => "__builtin_msa_shf_w", + "llvm.mips.shilo" => "__builtin_mips_shilo", + "llvm.mips.shll.ph" => "__builtin_mips_shll_ph", + "llvm.mips.shll.qb" => "__builtin_mips_shll_qb", + "llvm.mips.shll.s.ph" => "__builtin_mips_shll_s_ph", + "llvm.mips.shll.s.w" => "__builtin_mips_shll_s_w", + "llvm.mips.shra.ph" => "__builtin_mips_shra_ph", + "llvm.mips.shra.qb" => "__builtin_mips_shra_qb", + "llvm.mips.shra.r.ph" => "__builtin_mips_shra_r_ph", + "llvm.mips.shra.r.qb" => "__builtin_mips_shra_r_qb", + "llvm.mips.shra.r.w" => "__builtin_mips_shra_r_w", + "llvm.mips.shrl.ph" => "__builtin_mips_shrl_ph", + "llvm.mips.shrl.qb" => "__builtin_mips_shrl_qb", + "llvm.mips.sld.b" => "__builtin_msa_sld_b", + "llvm.mips.sld.d" => "__builtin_msa_sld_d", + "llvm.mips.sld.h" => "__builtin_msa_sld_h", + "llvm.mips.sld.w" => "__builtin_msa_sld_w", + "llvm.mips.sldi.b" => "__builtin_msa_sldi_b", + "llvm.mips.sldi.d" => "__builtin_msa_sldi_d", + "llvm.mips.sldi.h" => "__builtin_msa_sldi_h", + "llvm.mips.sldi.w" => "__builtin_msa_sldi_w", + "llvm.mips.sll.b" => "__builtin_msa_sll_b", + "llvm.mips.sll.d" => "__builtin_msa_sll_d", + "llvm.mips.sll.h" => "__builtin_msa_sll_h", + "llvm.mips.sll.w" => "__builtin_msa_sll_w", + "llvm.mips.slli.b" => "__builtin_msa_slli_b", + "llvm.mips.slli.d" => "__builtin_msa_slli_d", + "llvm.mips.slli.h" => "__builtin_msa_slli_h", + "llvm.mips.slli.w" => "__builtin_msa_slli_w", + "llvm.mips.splat.b" => "__builtin_msa_splat_b", + "llvm.mips.splat.d" => "__builtin_msa_splat_d", + "llvm.mips.splat.h" => "__builtin_msa_splat_h", + "llvm.mips.splat.w" => "__builtin_msa_splat_w", + "llvm.mips.splati.b" => "__builtin_msa_splati_b", + "llvm.mips.splati.d" => "__builtin_msa_splati_d", + "llvm.mips.splati.h" => "__builtin_msa_splati_h", + "llvm.mips.splati.w" => "__builtin_msa_splati_w", + "llvm.mips.sra.b" => "__builtin_msa_sra_b", + "llvm.mips.sra.d" => "__builtin_msa_sra_d", + "llvm.mips.sra.h" => "__builtin_msa_sra_h", + "llvm.mips.sra.w" => "__builtin_msa_sra_w", + "llvm.mips.srai.b" => "__builtin_msa_srai_b", + "llvm.mips.srai.d" => "__builtin_msa_srai_d", + "llvm.mips.srai.h" => "__builtin_msa_srai_h", + "llvm.mips.srai.w" => "__builtin_msa_srai_w", + "llvm.mips.srar.b" => "__builtin_msa_srar_b", + "llvm.mips.srar.d" => "__builtin_msa_srar_d", + "llvm.mips.srar.h" => "__builtin_msa_srar_h", + "llvm.mips.srar.w" => "__builtin_msa_srar_w", + "llvm.mips.srari.b" => "__builtin_msa_srari_b", + "llvm.mips.srari.d" => "__builtin_msa_srari_d", + "llvm.mips.srari.h" => "__builtin_msa_srari_h", + "llvm.mips.srari.w" => "__builtin_msa_srari_w", + "llvm.mips.srl.b" => "__builtin_msa_srl_b", + "llvm.mips.srl.d" => "__builtin_msa_srl_d", + "llvm.mips.srl.h" => "__builtin_msa_srl_h", + "llvm.mips.srl.w" => "__builtin_msa_srl_w", + "llvm.mips.srli.b" => "__builtin_msa_srli_b", + "llvm.mips.srli.d" => "__builtin_msa_srli_d", + "llvm.mips.srli.h" => "__builtin_msa_srli_h", + "llvm.mips.srli.w" => "__builtin_msa_srli_w", + "llvm.mips.srlr.b" => "__builtin_msa_srlr_b", + "llvm.mips.srlr.d" => "__builtin_msa_srlr_d", + "llvm.mips.srlr.h" => "__builtin_msa_srlr_h", + "llvm.mips.srlr.w" => "__builtin_msa_srlr_w", + "llvm.mips.srlri.b" => "__builtin_msa_srlri_b", + "llvm.mips.srlri.d" => "__builtin_msa_srlri_d", + "llvm.mips.srlri.h" => "__builtin_msa_srlri_h", + "llvm.mips.srlri.w" => "__builtin_msa_srlri_w", + "llvm.mips.st.b" => "__builtin_msa_st_b", + "llvm.mips.st.d" => "__builtin_msa_st_d", + "llvm.mips.st.h" => "__builtin_msa_st_h", + "llvm.mips.st.w" => "__builtin_msa_st_w", + "llvm.mips.str.d" => "__builtin_msa_str_d", + "llvm.mips.str.w" => "__builtin_msa_str_w", + "llvm.mips.subq.ph" => "__builtin_mips_subq_ph", + "llvm.mips.subq.s.ph" => "__builtin_mips_subq_s_ph", + "llvm.mips.subq.s.w" => "__builtin_mips_subq_s_w", + "llvm.mips.subqh.ph" => "__builtin_mips_subqh_ph", + "llvm.mips.subqh.r.ph" => "__builtin_mips_subqh_r_ph", + "llvm.mips.subqh.r.w" => "__builtin_mips_subqh_r_w", + "llvm.mips.subqh.w" => "__builtin_mips_subqh_w", + "llvm.mips.subs.s.b" => "__builtin_msa_subs_s_b", + "llvm.mips.subs.s.d" => "__builtin_msa_subs_s_d", + "llvm.mips.subs.s.h" => "__builtin_msa_subs_s_h", + "llvm.mips.subs.s.w" => "__builtin_msa_subs_s_w", + "llvm.mips.subs.u.b" => "__builtin_msa_subs_u_b", + "llvm.mips.subs.u.d" => "__builtin_msa_subs_u_d", + "llvm.mips.subs.u.h" => "__builtin_msa_subs_u_h", + "llvm.mips.subs.u.w" => "__builtin_msa_subs_u_w", + "llvm.mips.subsus.u.b" => "__builtin_msa_subsus_u_b", + "llvm.mips.subsus.u.d" => "__builtin_msa_subsus_u_d", + "llvm.mips.subsus.u.h" => "__builtin_msa_subsus_u_h", + "llvm.mips.subsus.u.w" => "__builtin_msa_subsus_u_w", + "llvm.mips.subsuu.s.b" => "__builtin_msa_subsuu_s_b", + "llvm.mips.subsuu.s.d" => "__builtin_msa_subsuu_s_d", + "llvm.mips.subsuu.s.h" => "__builtin_msa_subsuu_s_h", + "llvm.mips.subsuu.s.w" => "__builtin_msa_subsuu_s_w", + "llvm.mips.subu.ph" => "__builtin_mips_subu_ph", + "llvm.mips.subu.qb" => "__builtin_mips_subu_qb", + "llvm.mips.subu.s.ph" => "__builtin_mips_subu_s_ph", + "llvm.mips.subu.s.qb" => "__builtin_mips_subu_s_qb", + "llvm.mips.subuh.qb" => "__builtin_mips_subuh_qb", + "llvm.mips.subuh.r.qb" => "__builtin_mips_subuh_r_qb", + "llvm.mips.subv.b" => "__builtin_msa_subv_b", + "llvm.mips.subv.d" => "__builtin_msa_subv_d", + "llvm.mips.subv.h" => "__builtin_msa_subv_h", + "llvm.mips.subv.w" => "__builtin_msa_subv_w", + "llvm.mips.subvi.b" => "__builtin_msa_subvi_b", + "llvm.mips.subvi.d" => "__builtin_msa_subvi_d", + "llvm.mips.subvi.h" => "__builtin_msa_subvi_h", + "llvm.mips.subvi.w" => "__builtin_msa_subvi_w", + "llvm.mips.vshf.b" => "__builtin_msa_vshf_b", + "llvm.mips.vshf.d" => "__builtin_msa_vshf_d", + "llvm.mips.vshf.h" => "__builtin_msa_vshf_h", + "llvm.mips.vshf.w" => "__builtin_msa_vshf_w", + "llvm.mips.wrdsp" => "__builtin_mips_wrdsp", + "llvm.mips.xor.v" => "__builtin_msa_xor_v", + "llvm.mips.xori.b" => "__builtin_msa_xori_b", + // nvvm + "llvm.nvvm.abs.i" => "__nvvm_abs_i", + "llvm.nvvm.abs.ll" => "__nvvm_abs_ll", + "llvm.nvvm.add.rm.d" => "__nvvm_add_rm_d", + "llvm.nvvm.add.rm.f" => "__nvvm_add_rm_f", + "llvm.nvvm.add.rm.ftz.f" => "__nvvm_add_rm_ftz_f", + "llvm.nvvm.add.rn.d" => "__nvvm_add_rn_d", + "llvm.nvvm.add.rn.f" => "__nvvm_add_rn_f", + "llvm.nvvm.add.rn.ftz.f" => "__nvvm_add_rn_ftz_f", + "llvm.nvvm.add.rp.d" => "__nvvm_add_rp_d", + "llvm.nvvm.add.rp.f" => "__nvvm_add_rp_f", + "llvm.nvvm.add.rp.ftz.f" => "__nvvm_add_rp_ftz_f", + "llvm.nvvm.add.rz.d" => "__nvvm_add_rz_d", + "llvm.nvvm.add.rz.f" => "__nvvm_add_rz_f", + "llvm.nvvm.add.rz.ftz.f" => "__nvvm_add_rz_ftz_f", + "llvm.nvvm.bar.sync" => "__nvvm_bar_sync", + "llvm.nvvm.barrier0" => "__nvvm_bar0", + // [DUPLICATE]: "llvm.nvvm.barrier0" => "__syncthreads", + "llvm.nvvm.barrier0.and" => "__nvvm_bar0_and", + "llvm.nvvm.barrier0.or" => "__nvvm_bar0_or", + "llvm.nvvm.barrier0.popc" => "__nvvm_bar0_popc", + "llvm.nvvm.bitcast.d2ll" => "__nvvm_bitcast_d2ll", + "llvm.nvvm.bitcast.f2i" => "__nvvm_bitcast_f2i", + "llvm.nvvm.bitcast.i2f" => "__nvvm_bitcast_i2f", + "llvm.nvvm.bitcast.ll2d" => "__nvvm_bitcast_ll2d", + "llvm.nvvm.brev32" => "__nvvm_brev32", + "llvm.nvvm.brev64" => "__nvvm_brev64", + "llvm.nvvm.ceil.d" => "__nvvm_ceil_d", + "llvm.nvvm.ceil.f" => "__nvvm_ceil_f", + "llvm.nvvm.ceil.ftz.f" => "__nvvm_ceil_ftz_f", + "llvm.nvvm.clz.i" => "__nvvm_clz_i", + "llvm.nvvm.clz.ll" => "__nvvm_clz_ll", + "llvm.nvvm.cos.approx.f" => "__nvvm_cos_approx_f", + "llvm.nvvm.cos.approx.ftz.f" => "__nvvm_cos_approx_ftz_f", + "llvm.nvvm.d2f.rm" => "__nvvm_d2f_rm", + "llvm.nvvm.d2f.rm.ftz" => "__nvvm_d2f_rm_ftz", + "llvm.nvvm.d2f.rn" => "__nvvm_d2f_rn", + "llvm.nvvm.d2f.rn.ftz" => "__nvvm_d2f_rn_ftz", + "llvm.nvvm.d2f.rp" => "__nvvm_d2f_rp", + "llvm.nvvm.d2f.rp.ftz" => "__nvvm_d2f_rp_ftz", + "llvm.nvvm.d2f.rz" => "__nvvm_d2f_rz", + "llvm.nvvm.d2f.rz.ftz" => "__nvvm_d2f_rz_ftz", + "llvm.nvvm.d2i.hi" => "__nvvm_d2i_hi", + "llvm.nvvm.d2i.lo" => "__nvvm_d2i_lo", + "llvm.nvvm.d2i.rm" => "__nvvm_d2i_rm", + "llvm.nvvm.d2i.rn" => "__nvvm_d2i_rn", + "llvm.nvvm.d2i.rp" => "__nvvm_d2i_rp", + "llvm.nvvm.d2i.rz" => "__nvvm_d2i_rz", + "llvm.nvvm.d2ll.rm" => "__nvvm_d2ll_rm", + "llvm.nvvm.d2ll.rn" => "__nvvm_d2ll_rn", + "llvm.nvvm.d2ll.rp" => "__nvvm_d2ll_rp", + "llvm.nvvm.d2ll.rz" => "__nvvm_d2ll_rz", + "llvm.nvvm.d2ui.rm" => "__nvvm_d2ui_rm", + "llvm.nvvm.d2ui.rn" => "__nvvm_d2ui_rn", + "llvm.nvvm.d2ui.rp" => "__nvvm_d2ui_rp", + "llvm.nvvm.d2ui.rz" => "__nvvm_d2ui_rz", + "llvm.nvvm.d2ull.rm" => "__nvvm_d2ull_rm", + "llvm.nvvm.d2ull.rn" => "__nvvm_d2ull_rn", + "llvm.nvvm.d2ull.rp" => "__nvvm_d2ull_rp", + "llvm.nvvm.d2ull.rz" => "__nvvm_d2ull_rz", + "llvm.nvvm.div.approx.f" => "__nvvm_div_approx_f", + "llvm.nvvm.div.approx.ftz.f" => "__nvvm_div_approx_ftz_f", + "llvm.nvvm.div.rm.d" => "__nvvm_div_rm_d", + "llvm.nvvm.div.rm.f" => "__nvvm_div_rm_f", + "llvm.nvvm.div.rm.ftz.f" => "__nvvm_div_rm_ftz_f", + "llvm.nvvm.div.rn.d" => "__nvvm_div_rn_d", + "llvm.nvvm.div.rn.f" => "__nvvm_div_rn_f", + "llvm.nvvm.div.rn.ftz.f" => "__nvvm_div_rn_ftz_f", + "llvm.nvvm.div.rp.d" => "__nvvm_div_rp_d", + "llvm.nvvm.div.rp.f" => "__nvvm_div_rp_f", + "llvm.nvvm.div.rp.ftz.f" => "__nvvm_div_rp_ftz_f", + "llvm.nvvm.div.rz.d" => "__nvvm_div_rz_d", + "llvm.nvvm.div.rz.f" => "__nvvm_div_rz_f", + "llvm.nvvm.div.rz.ftz.f" => "__nvvm_div_rz_ftz_f", + "llvm.nvvm.ex2.approx.d" => "__nvvm_ex2_approx_d", + "llvm.nvvm.ex2.approx.f" => "__nvvm_ex2_approx_f", + "llvm.nvvm.ex2.approx.ftz.f" => "__nvvm_ex2_approx_ftz_f", + "llvm.nvvm.f2h.rn" => "__nvvm_f2h_rn", + "llvm.nvvm.f2h.rn.ftz" => "__nvvm_f2h_rn_ftz", + "llvm.nvvm.f2i.rm" => "__nvvm_f2i_rm", + "llvm.nvvm.f2i.rm.ftz" => "__nvvm_f2i_rm_ftz", + "llvm.nvvm.f2i.rn" => "__nvvm_f2i_rn", + "llvm.nvvm.f2i.rn.ftz" => "__nvvm_f2i_rn_ftz", + "llvm.nvvm.f2i.rp" => "__nvvm_f2i_rp", + "llvm.nvvm.f2i.rp.ftz" => "__nvvm_f2i_rp_ftz", + "llvm.nvvm.f2i.rz" => "__nvvm_f2i_rz", + "llvm.nvvm.f2i.rz.ftz" => "__nvvm_f2i_rz_ftz", + "llvm.nvvm.f2ll.rm" => "__nvvm_f2ll_rm", + "llvm.nvvm.f2ll.rm.ftz" => "__nvvm_f2ll_rm_ftz", + "llvm.nvvm.f2ll.rn" => "__nvvm_f2ll_rn", + "llvm.nvvm.f2ll.rn.ftz" => "__nvvm_f2ll_rn_ftz", + "llvm.nvvm.f2ll.rp" => "__nvvm_f2ll_rp", + "llvm.nvvm.f2ll.rp.ftz" => "__nvvm_f2ll_rp_ftz", + "llvm.nvvm.f2ll.rz" => "__nvvm_f2ll_rz", + "llvm.nvvm.f2ll.rz.ftz" => "__nvvm_f2ll_rz_ftz", + "llvm.nvvm.f2ui.rm" => "__nvvm_f2ui_rm", + "llvm.nvvm.f2ui.rm.ftz" => "__nvvm_f2ui_rm_ftz", + "llvm.nvvm.f2ui.rn" => "__nvvm_f2ui_rn", + "llvm.nvvm.f2ui.rn.ftz" => "__nvvm_f2ui_rn_ftz", + "llvm.nvvm.f2ui.rp" => "__nvvm_f2ui_rp", + "llvm.nvvm.f2ui.rp.ftz" => "__nvvm_f2ui_rp_ftz", + "llvm.nvvm.f2ui.rz" => "__nvvm_f2ui_rz", + "llvm.nvvm.f2ui.rz.ftz" => "__nvvm_f2ui_rz_ftz", + "llvm.nvvm.f2ull.rm" => "__nvvm_f2ull_rm", + "llvm.nvvm.f2ull.rm.ftz" => "__nvvm_f2ull_rm_ftz", + "llvm.nvvm.f2ull.rn" => "__nvvm_f2ull_rn", + "llvm.nvvm.f2ull.rn.ftz" => "__nvvm_f2ull_rn_ftz", + "llvm.nvvm.f2ull.rp" => "__nvvm_f2ull_rp", + "llvm.nvvm.f2ull.rp.ftz" => "__nvvm_f2ull_rp_ftz", + "llvm.nvvm.f2ull.rz" => "__nvvm_f2ull_rz", + "llvm.nvvm.f2ull.rz.ftz" => "__nvvm_f2ull_rz_ftz", + "llvm.nvvm.fabs.d" => "__nvvm_fabs_d", + "llvm.nvvm.fabs.f" => "__nvvm_fabs_f", + "llvm.nvvm.fabs.ftz.f" => "__nvvm_fabs_ftz_f", + "llvm.nvvm.floor.d" => "__nvvm_floor_d", + "llvm.nvvm.floor.f" => "__nvvm_floor_f", + "llvm.nvvm.floor.ftz.f" => "__nvvm_floor_ftz_f", + "llvm.nvvm.fma.rm.d" => "__nvvm_fma_rm_d", + "llvm.nvvm.fma.rm.f" => "__nvvm_fma_rm_f", + "llvm.nvvm.fma.rm.ftz.f" => "__nvvm_fma_rm_ftz_f", + "llvm.nvvm.fma.rn.d" => "__nvvm_fma_rn_d", + "llvm.nvvm.fma.rn.f" => "__nvvm_fma_rn_f", + "llvm.nvvm.fma.rn.ftz.f" => "__nvvm_fma_rn_ftz_f", + "llvm.nvvm.fma.rp.d" => "__nvvm_fma_rp_d", + "llvm.nvvm.fma.rp.f" => "__nvvm_fma_rp_f", + "llvm.nvvm.fma.rp.ftz.f" => "__nvvm_fma_rp_ftz_f", + "llvm.nvvm.fma.rz.d" => "__nvvm_fma_rz_d", + "llvm.nvvm.fma.rz.f" => "__nvvm_fma_rz_f", + "llvm.nvvm.fma.rz.ftz.f" => "__nvvm_fma_rz_ftz_f", + "llvm.nvvm.fmax.d" => "__nvvm_fmax_d", + "llvm.nvvm.fmax.f" => "__nvvm_fmax_f", + "llvm.nvvm.fmax.ftz.f" => "__nvvm_fmax_ftz_f", + "llvm.nvvm.fmin.d" => "__nvvm_fmin_d", + "llvm.nvvm.fmin.f" => "__nvvm_fmin_f", + "llvm.nvvm.fmin.ftz.f" => "__nvvm_fmin_ftz_f", + "llvm.nvvm.h2f" => "__nvvm_h2f", + "llvm.nvvm.i2d.rm" => "__nvvm_i2d_rm", + "llvm.nvvm.i2d.rn" => "__nvvm_i2d_rn", + "llvm.nvvm.i2d.rp" => "__nvvm_i2d_rp", + "llvm.nvvm.i2d.rz" => "__nvvm_i2d_rz", + "llvm.nvvm.i2f.rm" => "__nvvm_i2f_rm", + "llvm.nvvm.i2f.rn" => "__nvvm_i2f_rn", + "llvm.nvvm.i2f.rp" => "__nvvm_i2f_rp", + "llvm.nvvm.i2f.rz" => "__nvvm_i2f_rz", + "llvm.nvvm.isspacep.const" => "__nvvm_isspacep_const", + "llvm.nvvm.isspacep.global" => "__nvvm_isspacep_global", + "llvm.nvvm.isspacep.local" => "__nvvm_isspacep_local", + "llvm.nvvm.isspacep.shared" => "__nvvm_isspacep_shared", + "llvm.nvvm.istypep.sampler" => "__nvvm_istypep_sampler", + "llvm.nvvm.istypep.surface" => "__nvvm_istypep_surface", + "llvm.nvvm.istypep.texture" => "__nvvm_istypep_texture", + "llvm.nvvm.lg2.approx.d" => "__nvvm_lg2_approx_d", + "llvm.nvvm.lg2.approx.f" => "__nvvm_lg2_approx_f", + "llvm.nvvm.lg2.approx.ftz.f" => "__nvvm_lg2_approx_ftz_f", + "llvm.nvvm.ll2d.rm" => "__nvvm_ll2d_rm", + "llvm.nvvm.ll2d.rn" => "__nvvm_ll2d_rn", + "llvm.nvvm.ll2d.rp" => "__nvvm_ll2d_rp", + "llvm.nvvm.ll2d.rz" => "__nvvm_ll2d_rz", + "llvm.nvvm.ll2f.rm" => "__nvvm_ll2f_rm", + "llvm.nvvm.ll2f.rn" => "__nvvm_ll2f_rn", + "llvm.nvvm.ll2f.rp" => "__nvvm_ll2f_rp", + "llvm.nvvm.ll2f.rz" => "__nvvm_ll2f_rz", + "llvm.nvvm.lohi.i2d" => "__nvvm_lohi_i2d", + "llvm.nvvm.max.i" => "__nvvm_max_i", + "llvm.nvvm.max.ll" => "__nvvm_max_ll", + "llvm.nvvm.max.ui" => "__nvvm_max_ui", + "llvm.nvvm.max.ull" => "__nvvm_max_ull", + "llvm.nvvm.membar.cta" => "__nvvm_membar_cta", + "llvm.nvvm.membar.gl" => "__nvvm_membar_gl", + "llvm.nvvm.membar.sys" => "__nvvm_membar_sys", + "llvm.nvvm.min.i" => "__nvvm_min_i", + "llvm.nvvm.min.ll" => "__nvvm_min_ll", + "llvm.nvvm.min.ui" => "__nvvm_min_ui", + "llvm.nvvm.min.ull" => "__nvvm_min_ull", + "llvm.nvvm.mul.rm.d" => "__nvvm_mul_rm_d", + "llvm.nvvm.mul.rm.f" => "__nvvm_mul_rm_f", + "llvm.nvvm.mul.rm.ftz.f" => "__nvvm_mul_rm_ftz_f", + "llvm.nvvm.mul.rn.d" => "__nvvm_mul_rn_d", + "llvm.nvvm.mul.rn.f" => "__nvvm_mul_rn_f", + "llvm.nvvm.mul.rn.ftz.f" => "__nvvm_mul_rn_ftz_f", + "llvm.nvvm.mul.rp.d" => "__nvvm_mul_rp_d", + "llvm.nvvm.mul.rp.f" => "__nvvm_mul_rp_f", + "llvm.nvvm.mul.rp.ftz.f" => "__nvvm_mul_rp_ftz_f", + "llvm.nvvm.mul.rz.d" => "__nvvm_mul_rz_d", + "llvm.nvvm.mul.rz.f" => "__nvvm_mul_rz_f", + "llvm.nvvm.mul.rz.ftz.f" => "__nvvm_mul_rz_ftz_f", + "llvm.nvvm.mul24.i" => "__nvvm_mul24_i", + "llvm.nvvm.mul24.ui" => "__nvvm_mul24_ui", + "llvm.nvvm.mulhi.i" => "__nvvm_mulhi_i", + "llvm.nvvm.mulhi.ll" => "__nvvm_mulhi_ll", + "llvm.nvvm.mulhi.ui" => "__nvvm_mulhi_ui", + "llvm.nvvm.mulhi.ull" => "__nvvm_mulhi_ull", + "llvm.nvvm.popc.i" => "__nvvm_popc_i", + "llvm.nvvm.popc.ll" => "__nvvm_popc_ll", + "llvm.nvvm.prmt" => "__nvvm_prmt", + "llvm.nvvm.rcp.approx.ftz.d" => "__nvvm_rcp_approx_ftz_d", + "llvm.nvvm.rcp.rm.d" => "__nvvm_rcp_rm_d", + "llvm.nvvm.rcp.rm.f" => "__nvvm_rcp_rm_f", + "llvm.nvvm.rcp.rm.ftz.f" => "__nvvm_rcp_rm_ftz_f", + "llvm.nvvm.rcp.rn.d" => "__nvvm_rcp_rn_d", + "llvm.nvvm.rcp.rn.f" => "__nvvm_rcp_rn_f", + "llvm.nvvm.rcp.rn.ftz.f" => "__nvvm_rcp_rn_ftz_f", + "llvm.nvvm.rcp.rp.d" => "__nvvm_rcp_rp_d", + "llvm.nvvm.rcp.rp.f" => "__nvvm_rcp_rp_f", + "llvm.nvvm.rcp.rp.ftz.f" => "__nvvm_rcp_rp_ftz_f", + "llvm.nvvm.rcp.rz.d" => "__nvvm_rcp_rz_d", + "llvm.nvvm.rcp.rz.f" => "__nvvm_rcp_rz_f", + "llvm.nvvm.rcp.rz.ftz.f" => "__nvvm_rcp_rz_ftz_f", + "llvm.nvvm.read.ptx.sreg.clock" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.clock64" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.ctaid.x" => "__nvvm_read_ptx_sreg_ctaid_x", + "llvm.nvvm.read.ptx.sreg.ctaid.y" => "__nvvm_read_ptx_sreg_ctaid_y", + "llvm.nvvm.read.ptx.sreg.ctaid.z" => "__nvvm_read_ptx_sreg_ctaid_z", + "llvm.nvvm.read.ptx.sreg.envreg0" => "__nvvm_read_ptx_sreg_envreg0", + "llvm.nvvm.read.ptx.sreg.envreg1" => "__nvvm_read_ptx_sreg_envreg1", + "llvm.nvvm.read.ptx.sreg.envreg10" => "__nvvm_read_ptx_sreg_envreg10", + "llvm.nvvm.read.ptx.sreg.envreg11" => "__nvvm_read_ptx_sreg_envreg11", + "llvm.nvvm.read.ptx.sreg.envreg12" => "__nvvm_read_ptx_sreg_envreg12", + "llvm.nvvm.read.ptx.sreg.envreg13" => "__nvvm_read_ptx_sreg_envreg13", + "llvm.nvvm.read.ptx.sreg.envreg14" => "__nvvm_read_ptx_sreg_envreg14", + "llvm.nvvm.read.ptx.sreg.envreg15" => "__nvvm_read_ptx_sreg_envreg15", + "llvm.nvvm.read.ptx.sreg.envreg16" => "__nvvm_read_ptx_sreg_envreg16", + "llvm.nvvm.read.ptx.sreg.envreg17" => "__nvvm_read_ptx_sreg_envreg17", + "llvm.nvvm.read.ptx.sreg.envreg18" => "__nvvm_read_ptx_sreg_envreg18", + "llvm.nvvm.read.ptx.sreg.envreg19" => "__nvvm_read_ptx_sreg_envreg19", + "llvm.nvvm.read.ptx.sreg.envreg2" => "__nvvm_read_ptx_sreg_envreg2", + "llvm.nvvm.read.ptx.sreg.envreg20" => "__nvvm_read_ptx_sreg_envreg20", + "llvm.nvvm.read.ptx.sreg.envreg21" => "__nvvm_read_ptx_sreg_envreg21", + "llvm.nvvm.read.ptx.sreg.envreg22" => "__nvvm_read_ptx_sreg_envreg22", + "llvm.nvvm.read.ptx.sreg.envreg23" => "__nvvm_read_ptx_sreg_envreg23", + "llvm.nvvm.read.ptx.sreg.envreg24" => "__nvvm_read_ptx_sreg_envreg24", + "llvm.nvvm.read.ptx.sreg.envreg25" => "__nvvm_read_ptx_sreg_envreg25", + "llvm.nvvm.read.ptx.sreg.envreg26" => "__nvvm_read_ptx_sreg_envreg26", + "llvm.nvvm.read.ptx.sreg.envreg27" => "__nvvm_read_ptx_sreg_envreg27", + "llvm.nvvm.read.ptx.sreg.envreg28" => "__nvvm_read_ptx_sreg_envreg28", + "llvm.nvvm.read.ptx.sreg.envreg29" => "__nvvm_read_ptx_sreg_envreg29", + "llvm.nvvm.read.ptx.sreg.envreg3" => "__nvvm_read_ptx_sreg_envreg3", + "llvm.nvvm.read.ptx.sreg.envreg30" => "__nvvm_read_ptx_sreg_envreg30", + "llvm.nvvm.read.ptx.sreg.envreg31" => "__nvvm_read_ptx_sreg_envreg31", + "llvm.nvvm.read.ptx.sreg.envreg4" => "__nvvm_read_ptx_sreg_envreg4", + "llvm.nvvm.read.ptx.sreg.envreg5" => "__nvvm_read_ptx_sreg_envreg5", + "llvm.nvvm.read.ptx.sreg.envreg6" => "__nvvm_read_ptx_sreg_envreg6", + "llvm.nvvm.read.ptx.sreg.envreg7" => "__nvvm_read_ptx_sreg_envreg7", + "llvm.nvvm.read.ptx.sreg.envreg8" => "__nvvm_read_ptx_sreg_envreg8", + "llvm.nvvm.read.ptx.sreg.envreg9" => "__nvvm_read_ptx_sreg_envreg9", + "llvm.nvvm.read.ptx.sreg.gridid" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.laneid" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.lanemask.eq" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.lanemask.ge" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.lanemask.gt" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.lanemask.le" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.lanemask.lt" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.nctaid.x" => "__nvvm_read_ptx_sreg_nctaid_x", + "llvm.nvvm.read.ptx.sreg.nctaid.y" => "__nvvm_read_ptx_sreg_nctaid_y", + "llvm.nvvm.read.ptx.sreg.nctaid.z" => "__nvvm_read_ptx_sreg_nctaid_z", + "llvm.nvvm.read.ptx.sreg.nsmid" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.ntid.x" => "__nvvm_read_ptx_sreg_ntid_x", + "llvm.nvvm.read.ptx.sreg.ntid.y" => "__nvvm_read_ptx_sreg_ntid_y", + "llvm.nvvm.read.ptx.sreg.ntid.z" => "__nvvm_read_ptx_sreg_ntid_z", + "llvm.nvvm.read.ptx.sreg.nwarpid" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.pm0" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.pm1" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.pm2" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.pm3" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.smid" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.tid.x" => "__nvvm_read_ptx_sreg_tid_x", + "llvm.nvvm.read.ptx.sreg.tid.y" => "__nvvm_read_ptx_sreg_tid_y", + "llvm.nvvm.read.ptx.sreg.tid.z" => "__nvvm_read_ptx_sreg_tid_z", + "llvm.nvvm.read.ptx.sreg.warpid" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.read.ptx.sreg.warpsize" => "__nvvm_read_ptx_sreg_warpsize", + // [DUPLICATE]: "llvm.nvvm.read.ptx.sreg.warpsize" => "__nvvm_read_ptx_sreg_", + "llvm.nvvm.rotate.b32" => "__nvvm_rotate_b32", + "llvm.nvvm.rotate.b64" => "__nvvm_rotate_b64", + "llvm.nvvm.rotate.right.b64" => "__nvvm_rotate_right_b64", + "llvm.nvvm.round.d" => "__nvvm_round_d", + "llvm.nvvm.round.f" => "__nvvm_round_f", + "llvm.nvvm.round.ftz.f" => "__nvvm_round_ftz_f", + "llvm.nvvm.rsqrt.approx.d" => "__nvvm_rsqrt_approx_d", + "llvm.nvvm.rsqrt.approx.f" => "__nvvm_rsqrt_approx_f", + "llvm.nvvm.rsqrt.approx.ftz.f" => "__nvvm_rsqrt_approx_ftz_f", + "llvm.nvvm.sad.i" => "__nvvm_sad_i", + "llvm.nvvm.sad.ui" => "__nvvm_sad_ui", + "llvm.nvvm.saturate.d" => "__nvvm_saturate_d", + "llvm.nvvm.saturate.f" => "__nvvm_saturate_f", + "llvm.nvvm.saturate.ftz.f" => "__nvvm_saturate_ftz_f", + "llvm.nvvm.shfl.bfly.f32" => "__nvvm_shfl_bfly_f32", + "llvm.nvvm.shfl.bfly.i32" => "__nvvm_shfl_bfly_i32", + "llvm.nvvm.shfl.down.f32" => "__nvvm_shfl_down_f32", + "llvm.nvvm.shfl.down.i32" => "__nvvm_shfl_down_i32", + "llvm.nvvm.shfl.idx.f32" => "__nvvm_shfl_idx_f32", + "llvm.nvvm.shfl.idx.i32" => "__nvvm_shfl_idx_i32", + "llvm.nvvm.shfl.up.f32" => "__nvvm_shfl_up_f32", + "llvm.nvvm.shfl.up.i32" => "__nvvm_shfl_up_i32", + "llvm.nvvm.sin.approx.f" => "__nvvm_sin_approx_f", + "llvm.nvvm.sin.approx.ftz.f" => "__nvvm_sin_approx_ftz_f", + "llvm.nvvm.sqrt.approx.f" => "__nvvm_sqrt_approx_f", + "llvm.nvvm.sqrt.approx.ftz.f" => "__nvvm_sqrt_approx_ftz_f", + "llvm.nvvm.sqrt.f" => "__nvvm_sqrt_f", + "llvm.nvvm.sqrt.rm.d" => "__nvvm_sqrt_rm_d", + "llvm.nvvm.sqrt.rm.f" => "__nvvm_sqrt_rm_f", + "llvm.nvvm.sqrt.rm.ftz.f" => "__nvvm_sqrt_rm_ftz_f", + "llvm.nvvm.sqrt.rn.d" => "__nvvm_sqrt_rn_d", + "llvm.nvvm.sqrt.rn.f" => "__nvvm_sqrt_rn_f", + "llvm.nvvm.sqrt.rn.ftz.f" => "__nvvm_sqrt_rn_ftz_f", + "llvm.nvvm.sqrt.rp.d" => "__nvvm_sqrt_rp_d", + "llvm.nvvm.sqrt.rp.f" => "__nvvm_sqrt_rp_f", + "llvm.nvvm.sqrt.rp.ftz.f" => "__nvvm_sqrt_rp_ftz_f", + "llvm.nvvm.sqrt.rz.d" => "__nvvm_sqrt_rz_d", + "llvm.nvvm.sqrt.rz.f" => "__nvvm_sqrt_rz_f", + "llvm.nvvm.sqrt.rz.ftz.f" => "__nvvm_sqrt_rz_ftz_f", + "llvm.nvvm.suq.array.size" => "__nvvm_suq_array_size", + "llvm.nvvm.suq.channel.data.type" => "__nvvm_suq_channel_data_type", + "llvm.nvvm.suq.channel.order" => "__nvvm_suq_channel_order", + "llvm.nvvm.suq.depth" => "__nvvm_suq_depth", + "llvm.nvvm.suq.height" => "__nvvm_suq_height", + "llvm.nvvm.suq.width" => "__nvvm_suq_width", + "llvm.nvvm.sust.b.1d.array.i16.clamp" => "__nvvm_sust_b_1d_array_i16_clamp", + "llvm.nvvm.sust.b.1d.array.i16.trap" => "__nvvm_sust_b_1d_array_i16_trap", + "llvm.nvvm.sust.b.1d.array.i16.zero" => "__nvvm_sust_b_1d_array_i16_zero", + "llvm.nvvm.sust.b.1d.array.i32.clamp" => "__nvvm_sust_b_1d_array_i32_clamp", + "llvm.nvvm.sust.b.1d.array.i32.trap" => "__nvvm_sust_b_1d_array_i32_trap", + "llvm.nvvm.sust.b.1d.array.i32.zero" => "__nvvm_sust_b_1d_array_i32_zero", + "llvm.nvvm.sust.b.1d.array.i64.clamp" => "__nvvm_sust_b_1d_array_i64_clamp", + "llvm.nvvm.sust.b.1d.array.i64.trap" => "__nvvm_sust_b_1d_array_i64_trap", + "llvm.nvvm.sust.b.1d.array.i64.zero" => "__nvvm_sust_b_1d_array_i64_zero", + "llvm.nvvm.sust.b.1d.array.i8.clamp" => "__nvvm_sust_b_1d_array_i8_clamp", + "llvm.nvvm.sust.b.1d.array.i8.trap" => "__nvvm_sust_b_1d_array_i8_trap", + "llvm.nvvm.sust.b.1d.array.i8.zero" => "__nvvm_sust_b_1d_array_i8_zero", + "llvm.nvvm.sust.b.1d.array.v2i16.clamp" => "__nvvm_sust_b_1d_array_v2i16_clamp", + "llvm.nvvm.sust.b.1d.array.v2i16.trap" => "__nvvm_sust_b_1d_array_v2i16_trap", + "llvm.nvvm.sust.b.1d.array.v2i16.zero" => "__nvvm_sust_b_1d_array_v2i16_zero", + "llvm.nvvm.sust.b.1d.array.v2i32.clamp" => "__nvvm_sust_b_1d_array_v2i32_clamp", + "llvm.nvvm.sust.b.1d.array.v2i32.trap" => "__nvvm_sust_b_1d_array_v2i32_trap", + "llvm.nvvm.sust.b.1d.array.v2i32.zero" => "__nvvm_sust_b_1d_array_v2i32_zero", + "llvm.nvvm.sust.b.1d.array.v2i64.clamp" => "__nvvm_sust_b_1d_array_v2i64_clamp", + "llvm.nvvm.sust.b.1d.array.v2i64.trap" => "__nvvm_sust_b_1d_array_v2i64_trap", + "llvm.nvvm.sust.b.1d.array.v2i64.zero" => "__nvvm_sust_b_1d_array_v2i64_zero", + "llvm.nvvm.sust.b.1d.array.v2i8.clamp" => "__nvvm_sust_b_1d_array_v2i8_clamp", + "llvm.nvvm.sust.b.1d.array.v2i8.trap" => "__nvvm_sust_b_1d_array_v2i8_trap", + "llvm.nvvm.sust.b.1d.array.v2i8.zero" => "__nvvm_sust_b_1d_array_v2i8_zero", + "llvm.nvvm.sust.b.1d.array.v4i16.clamp" => "__nvvm_sust_b_1d_array_v4i16_clamp", + "llvm.nvvm.sust.b.1d.array.v4i16.trap" => "__nvvm_sust_b_1d_array_v4i16_trap", + "llvm.nvvm.sust.b.1d.array.v4i16.zero" => "__nvvm_sust_b_1d_array_v4i16_zero", + "llvm.nvvm.sust.b.1d.array.v4i32.clamp" => "__nvvm_sust_b_1d_array_v4i32_clamp", + "llvm.nvvm.sust.b.1d.array.v4i32.trap" => "__nvvm_sust_b_1d_array_v4i32_trap", + "llvm.nvvm.sust.b.1d.array.v4i32.zero" => "__nvvm_sust_b_1d_array_v4i32_zero", + "llvm.nvvm.sust.b.1d.array.v4i8.clamp" => "__nvvm_sust_b_1d_array_v4i8_clamp", + "llvm.nvvm.sust.b.1d.array.v4i8.trap" => "__nvvm_sust_b_1d_array_v4i8_trap", + "llvm.nvvm.sust.b.1d.array.v4i8.zero" => "__nvvm_sust_b_1d_array_v4i8_zero", + "llvm.nvvm.sust.b.1d.i16.clamp" => "__nvvm_sust_b_1d_i16_clamp", + "llvm.nvvm.sust.b.1d.i16.trap" => "__nvvm_sust_b_1d_i16_trap", + "llvm.nvvm.sust.b.1d.i16.zero" => "__nvvm_sust_b_1d_i16_zero", + "llvm.nvvm.sust.b.1d.i32.clamp" => "__nvvm_sust_b_1d_i32_clamp", + "llvm.nvvm.sust.b.1d.i32.trap" => "__nvvm_sust_b_1d_i32_trap", + "llvm.nvvm.sust.b.1d.i32.zero" => "__nvvm_sust_b_1d_i32_zero", + "llvm.nvvm.sust.b.1d.i64.clamp" => "__nvvm_sust_b_1d_i64_clamp", + "llvm.nvvm.sust.b.1d.i64.trap" => "__nvvm_sust_b_1d_i64_trap", + "llvm.nvvm.sust.b.1d.i64.zero" => "__nvvm_sust_b_1d_i64_zero", + "llvm.nvvm.sust.b.1d.i8.clamp" => "__nvvm_sust_b_1d_i8_clamp", + "llvm.nvvm.sust.b.1d.i8.trap" => "__nvvm_sust_b_1d_i8_trap", + "llvm.nvvm.sust.b.1d.i8.zero" => "__nvvm_sust_b_1d_i8_zero", + "llvm.nvvm.sust.b.1d.v2i16.clamp" => "__nvvm_sust_b_1d_v2i16_clamp", + "llvm.nvvm.sust.b.1d.v2i16.trap" => "__nvvm_sust_b_1d_v2i16_trap", + "llvm.nvvm.sust.b.1d.v2i16.zero" => "__nvvm_sust_b_1d_v2i16_zero", + "llvm.nvvm.sust.b.1d.v2i32.clamp" => "__nvvm_sust_b_1d_v2i32_clamp", + "llvm.nvvm.sust.b.1d.v2i32.trap" => "__nvvm_sust_b_1d_v2i32_trap", + "llvm.nvvm.sust.b.1d.v2i32.zero" => "__nvvm_sust_b_1d_v2i32_zero", + "llvm.nvvm.sust.b.1d.v2i64.clamp" => "__nvvm_sust_b_1d_v2i64_clamp", + "llvm.nvvm.sust.b.1d.v2i64.trap" => "__nvvm_sust_b_1d_v2i64_trap", + "llvm.nvvm.sust.b.1d.v2i64.zero" => "__nvvm_sust_b_1d_v2i64_zero", + "llvm.nvvm.sust.b.1d.v2i8.clamp" => "__nvvm_sust_b_1d_v2i8_clamp", + "llvm.nvvm.sust.b.1d.v2i8.trap" => "__nvvm_sust_b_1d_v2i8_trap", + "llvm.nvvm.sust.b.1d.v2i8.zero" => "__nvvm_sust_b_1d_v2i8_zero", + "llvm.nvvm.sust.b.1d.v4i16.clamp" => "__nvvm_sust_b_1d_v4i16_clamp", + "llvm.nvvm.sust.b.1d.v4i16.trap" => "__nvvm_sust_b_1d_v4i16_trap", + "llvm.nvvm.sust.b.1d.v4i16.zero" => "__nvvm_sust_b_1d_v4i16_zero", + "llvm.nvvm.sust.b.1d.v4i32.clamp" => "__nvvm_sust_b_1d_v4i32_clamp", + "llvm.nvvm.sust.b.1d.v4i32.trap" => "__nvvm_sust_b_1d_v4i32_trap", + "llvm.nvvm.sust.b.1d.v4i32.zero" => "__nvvm_sust_b_1d_v4i32_zero", + "llvm.nvvm.sust.b.1d.v4i8.clamp" => "__nvvm_sust_b_1d_v4i8_clamp", + "llvm.nvvm.sust.b.1d.v4i8.trap" => "__nvvm_sust_b_1d_v4i8_trap", + "llvm.nvvm.sust.b.1d.v4i8.zero" => "__nvvm_sust_b_1d_v4i8_zero", + "llvm.nvvm.sust.b.2d.array.i16.clamp" => "__nvvm_sust_b_2d_array_i16_clamp", + "llvm.nvvm.sust.b.2d.array.i16.trap" => "__nvvm_sust_b_2d_array_i16_trap", + "llvm.nvvm.sust.b.2d.array.i16.zero" => "__nvvm_sust_b_2d_array_i16_zero", + "llvm.nvvm.sust.b.2d.array.i32.clamp" => "__nvvm_sust_b_2d_array_i32_clamp", + "llvm.nvvm.sust.b.2d.array.i32.trap" => "__nvvm_sust_b_2d_array_i32_trap", + "llvm.nvvm.sust.b.2d.array.i32.zero" => "__nvvm_sust_b_2d_array_i32_zero", + "llvm.nvvm.sust.b.2d.array.i64.clamp" => "__nvvm_sust_b_2d_array_i64_clamp", + "llvm.nvvm.sust.b.2d.array.i64.trap" => "__nvvm_sust_b_2d_array_i64_trap", + "llvm.nvvm.sust.b.2d.array.i64.zero" => "__nvvm_sust_b_2d_array_i64_zero", + "llvm.nvvm.sust.b.2d.array.i8.clamp" => "__nvvm_sust_b_2d_array_i8_clamp", + "llvm.nvvm.sust.b.2d.array.i8.trap" => "__nvvm_sust_b_2d_array_i8_trap", + "llvm.nvvm.sust.b.2d.array.i8.zero" => "__nvvm_sust_b_2d_array_i8_zero", + "llvm.nvvm.sust.b.2d.array.v2i16.clamp" => "__nvvm_sust_b_2d_array_v2i16_clamp", + "llvm.nvvm.sust.b.2d.array.v2i16.trap" => "__nvvm_sust_b_2d_array_v2i16_trap", + "llvm.nvvm.sust.b.2d.array.v2i16.zero" => "__nvvm_sust_b_2d_array_v2i16_zero", + "llvm.nvvm.sust.b.2d.array.v2i32.clamp" => "__nvvm_sust_b_2d_array_v2i32_clamp", + "llvm.nvvm.sust.b.2d.array.v2i32.trap" => "__nvvm_sust_b_2d_array_v2i32_trap", + "llvm.nvvm.sust.b.2d.array.v2i32.zero" => "__nvvm_sust_b_2d_array_v2i32_zero", + "llvm.nvvm.sust.b.2d.array.v2i64.clamp" => "__nvvm_sust_b_2d_array_v2i64_clamp", + "llvm.nvvm.sust.b.2d.array.v2i64.trap" => "__nvvm_sust_b_2d_array_v2i64_trap", + "llvm.nvvm.sust.b.2d.array.v2i64.zero" => "__nvvm_sust_b_2d_array_v2i64_zero", + "llvm.nvvm.sust.b.2d.array.v2i8.clamp" => "__nvvm_sust_b_2d_array_v2i8_clamp", + "llvm.nvvm.sust.b.2d.array.v2i8.trap" => "__nvvm_sust_b_2d_array_v2i8_trap", + "llvm.nvvm.sust.b.2d.array.v2i8.zero" => "__nvvm_sust_b_2d_array_v2i8_zero", + "llvm.nvvm.sust.b.2d.array.v4i16.clamp" => "__nvvm_sust_b_2d_array_v4i16_clamp", + "llvm.nvvm.sust.b.2d.array.v4i16.trap" => "__nvvm_sust_b_2d_array_v4i16_trap", + "llvm.nvvm.sust.b.2d.array.v4i16.zero" => "__nvvm_sust_b_2d_array_v4i16_zero", + "llvm.nvvm.sust.b.2d.array.v4i32.clamp" => "__nvvm_sust_b_2d_array_v4i32_clamp", + "llvm.nvvm.sust.b.2d.array.v4i32.trap" => "__nvvm_sust_b_2d_array_v4i32_trap", + "llvm.nvvm.sust.b.2d.array.v4i32.zero" => "__nvvm_sust_b_2d_array_v4i32_zero", + "llvm.nvvm.sust.b.2d.array.v4i8.clamp" => "__nvvm_sust_b_2d_array_v4i8_clamp", + "llvm.nvvm.sust.b.2d.array.v4i8.trap" => "__nvvm_sust_b_2d_array_v4i8_trap", + "llvm.nvvm.sust.b.2d.array.v4i8.zero" => "__nvvm_sust_b_2d_array_v4i8_zero", + "llvm.nvvm.sust.b.2d.i16.clamp" => "__nvvm_sust_b_2d_i16_clamp", + "llvm.nvvm.sust.b.2d.i16.trap" => "__nvvm_sust_b_2d_i16_trap", + "llvm.nvvm.sust.b.2d.i16.zero" => "__nvvm_sust_b_2d_i16_zero", + "llvm.nvvm.sust.b.2d.i32.clamp" => "__nvvm_sust_b_2d_i32_clamp", + "llvm.nvvm.sust.b.2d.i32.trap" => "__nvvm_sust_b_2d_i32_trap", + "llvm.nvvm.sust.b.2d.i32.zero" => "__nvvm_sust_b_2d_i32_zero", + "llvm.nvvm.sust.b.2d.i64.clamp" => "__nvvm_sust_b_2d_i64_clamp", + "llvm.nvvm.sust.b.2d.i64.trap" => "__nvvm_sust_b_2d_i64_trap", + "llvm.nvvm.sust.b.2d.i64.zero" => "__nvvm_sust_b_2d_i64_zero", + "llvm.nvvm.sust.b.2d.i8.clamp" => "__nvvm_sust_b_2d_i8_clamp", + "llvm.nvvm.sust.b.2d.i8.trap" => "__nvvm_sust_b_2d_i8_trap", + "llvm.nvvm.sust.b.2d.i8.zero" => "__nvvm_sust_b_2d_i8_zero", + "llvm.nvvm.sust.b.2d.v2i16.clamp" => "__nvvm_sust_b_2d_v2i16_clamp", + "llvm.nvvm.sust.b.2d.v2i16.trap" => "__nvvm_sust_b_2d_v2i16_trap", + "llvm.nvvm.sust.b.2d.v2i16.zero" => "__nvvm_sust_b_2d_v2i16_zero", + "llvm.nvvm.sust.b.2d.v2i32.clamp" => "__nvvm_sust_b_2d_v2i32_clamp", + "llvm.nvvm.sust.b.2d.v2i32.trap" => "__nvvm_sust_b_2d_v2i32_trap", + "llvm.nvvm.sust.b.2d.v2i32.zero" => "__nvvm_sust_b_2d_v2i32_zero", + "llvm.nvvm.sust.b.2d.v2i64.clamp" => "__nvvm_sust_b_2d_v2i64_clamp", + "llvm.nvvm.sust.b.2d.v2i64.trap" => "__nvvm_sust_b_2d_v2i64_trap", + "llvm.nvvm.sust.b.2d.v2i64.zero" => "__nvvm_sust_b_2d_v2i64_zero", + "llvm.nvvm.sust.b.2d.v2i8.clamp" => "__nvvm_sust_b_2d_v2i8_clamp", + "llvm.nvvm.sust.b.2d.v2i8.trap" => "__nvvm_sust_b_2d_v2i8_trap", + "llvm.nvvm.sust.b.2d.v2i8.zero" => "__nvvm_sust_b_2d_v2i8_zero", + "llvm.nvvm.sust.b.2d.v4i16.clamp" => "__nvvm_sust_b_2d_v4i16_clamp", + "llvm.nvvm.sust.b.2d.v4i16.trap" => "__nvvm_sust_b_2d_v4i16_trap", + "llvm.nvvm.sust.b.2d.v4i16.zero" => "__nvvm_sust_b_2d_v4i16_zero", + "llvm.nvvm.sust.b.2d.v4i32.clamp" => "__nvvm_sust_b_2d_v4i32_clamp", + "llvm.nvvm.sust.b.2d.v4i32.trap" => "__nvvm_sust_b_2d_v4i32_trap", + "llvm.nvvm.sust.b.2d.v4i32.zero" => "__nvvm_sust_b_2d_v4i32_zero", + "llvm.nvvm.sust.b.2d.v4i8.clamp" => "__nvvm_sust_b_2d_v4i8_clamp", + "llvm.nvvm.sust.b.2d.v4i8.trap" => "__nvvm_sust_b_2d_v4i8_trap", + "llvm.nvvm.sust.b.2d.v4i8.zero" => "__nvvm_sust_b_2d_v4i8_zero", + "llvm.nvvm.sust.b.3d.i16.clamp" => "__nvvm_sust_b_3d_i16_clamp", + "llvm.nvvm.sust.b.3d.i16.trap" => "__nvvm_sust_b_3d_i16_trap", + "llvm.nvvm.sust.b.3d.i16.zero" => "__nvvm_sust_b_3d_i16_zero", + "llvm.nvvm.sust.b.3d.i32.clamp" => "__nvvm_sust_b_3d_i32_clamp", + "llvm.nvvm.sust.b.3d.i32.trap" => "__nvvm_sust_b_3d_i32_trap", + "llvm.nvvm.sust.b.3d.i32.zero" => "__nvvm_sust_b_3d_i32_zero", + "llvm.nvvm.sust.b.3d.i64.clamp" => "__nvvm_sust_b_3d_i64_clamp", + "llvm.nvvm.sust.b.3d.i64.trap" => "__nvvm_sust_b_3d_i64_trap", + "llvm.nvvm.sust.b.3d.i64.zero" => "__nvvm_sust_b_3d_i64_zero", + "llvm.nvvm.sust.b.3d.i8.clamp" => "__nvvm_sust_b_3d_i8_clamp", + "llvm.nvvm.sust.b.3d.i8.trap" => "__nvvm_sust_b_3d_i8_trap", + "llvm.nvvm.sust.b.3d.i8.zero" => "__nvvm_sust_b_3d_i8_zero", + "llvm.nvvm.sust.b.3d.v2i16.clamp" => "__nvvm_sust_b_3d_v2i16_clamp", + "llvm.nvvm.sust.b.3d.v2i16.trap" => "__nvvm_sust_b_3d_v2i16_trap", + "llvm.nvvm.sust.b.3d.v2i16.zero" => "__nvvm_sust_b_3d_v2i16_zero", + "llvm.nvvm.sust.b.3d.v2i32.clamp" => "__nvvm_sust_b_3d_v2i32_clamp", + "llvm.nvvm.sust.b.3d.v2i32.trap" => "__nvvm_sust_b_3d_v2i32_trap", + "llvm.nvvm.sust.b.3d.v2i32.zero" => "__nvvm_sust_b_3d_v2i32_zero", + "llvm.nvvm.sust.b.3d.v2i64.clamp" => "__nvvm_sust_b_3d_v2i64_clamp", + "llvm.nvvm.sust.b.3d.v2i64.trap" => "__nvvm_sust_b_3d_v2i64_trap", + "llvm.nvvm.sust.b.3d.v2i64.zero" => "__nvvm_sust_b_3d_v2i64_zero", + "llvm.nvvm.sust.b.3d.v2i8.clamp" => "__nvvm_sust_b_3d_v2i8_clamp", + "llvm.nvvm.sust.b.3d.v2i8.trap" => "__nvvm_sust_b_3d_v2i8_trap", + "llvm.nvvm.sust.b.3d.v2i8.zero" => "__nvvm_sust_b_3d_v2i8_zero", + "llvm.nvvm.sust.b.3d.v4i16.clamp" => "__nvvm_sust_b_3d_v4i16_clamp", + "llvm.nvvm.sust.b.3d.v4i16.trap" => "__nvvm_sust_b_3d_v4i16_trap", + "llvm.nvvm.sust.b.3d.v4i16.zero" => "__nvvm_sust_b_3d_v4i16_zero", + "llvm.nvvm.sust.b.3d.v4i32.clamp" => "__nvvm_sust_b_3d_v4i32_clamp", + "llvm.nvvm.sust.b.3d.v4i32.trap" => "__nvvm_sust_b_3d_v4i32_trap", + "llvm.nvvm.sust.b.3d.v4i32.zero" => "__nvvm_sust_b_3d_v4i32_zero", + "llvm.nvvm.sust.b.3d.v4i8.clamp" => "__nvvm_sust_b_3d_v4i8_clamp", + "llvm.nvvm.sust.b.3d.v4i8.trap" => "__nvvm_sust_b_3d_v4i8_trap", + "llvm.nvvm.sust.b.3d.v4i8.zero" => "__nvvm_sust_b_3d_v4i8_zero", + "llvm.nvvm.sust.p.1d.array.i16.trap" => "__nvvm_sust_p_1d_array_i16_trap", + "llvm.nvvm.sust.p.1d.array.i32.trap" => "__nvvm_sust_p_1d_array_i32_trap", + "llvm.nvvm.sust.p.1d.array.i8.trap" => "__nvvm_sust_p_1d_array_i8_trap", + "llvm.nvvm.sust.p.1d.array.v2i16.trap" => "__nvvm_sust_p_1d_array_v2i16_trap", + "llvm.nvvm.sust.p.1d.array.v2i32.trap" => "__nvvm_sust_p_1d_array_v2i32_trap", + "llvm.nvvm.sust.p.1d.array.v2i8.trap" => "__nvvm_sust_p_1d_array_v2i8_trap", + "llvm.nvvm.sust.p.1d.array.v4i16.trap" => "__nvvm_sust_p_1d_array_v4i16_trap", + "llvm.nvvm.sust.p.1d.array.v4i32.trap" => "__nvvm_sust_p_1d_array_v4i32_trap", + "llvm.nvvm.sust.p.1d.array.v4i8.trap" => "__nvvm_sust_p_1d_array_v4i8_trap", + "llvm.nvvm.sust.p.1d.i16.trap" => "__nvvm_sust_p_1d_i16_trap", + "llvm.nvvm.sust.p.1d.i32.trap" => "__nvvm_sust_p_1d_i32_trap", + "llvm.nvvm.sust.p.1d.i8.trap" => "__nvvm_sust_p_1d_i8_trap", + "llvm.nvvm.sust.p.1d.v2i16.trap" => "__nvvm_sust_p_1d_v2i16_trap", + "llvm.nvvm.sust.p.1d.v2i32.trap" => "__nvvm_sust_p_1d_v2i32_trap", + "llvm.nvvm.sust.p.1d.v2i8.trap" => "__nvvm_sust_p_1d_v2i8_trap", + "llvm.nvvm.sust.p.1d.v4i16.trap" => "__nvvm_sust_p_1d_v4i16_trap", + "llvm.nvvm.sust.p.1d.v4i32.trap" => "__nvvm_sust_p_1d_v4i32_trap", + "llvm.nvvm.sust.p.1d.v4i8.trap" => "__nvvm_sust_p_1d_v4i8_trap", + "llvm.nvvm.sust.p.2d.array.i16.trap" => "__nvvm_sust_p_2d_array_i16_trap", + "llvm.nvvm.sust.p.2d.array.i32.trap" => "__nvvm_sust_p_2d_array_i32_trap", + "llvm.nvvm.sust.p.2d.array.i8.trap" => "__nvvm_sust_p_2d_array_i8_trap", + "llvm.nvvm.sust.p.2d.array.v2i16.trap" => "__nvvm_sust_p_2d_array_v2i16_trap", + "llvm.nvvm.sust.p.2d.array.v2i32.trap" => "__nvvm_sust_p_2d_array_v2i32_trap", + "llvm.nvvm.sust.p.2d.array.v2i8.trap" => "__nvvm_sust_p_2d_array_v2i8_trap", + "llvm.nvvm.sust.p.2d.array.v4i16.trap" => "__nvvm_sust_p_2d_array_v4i16_trap", + "llvm.nvvm.sust.p.2d.array.v4i32.trap" => "__nvvm_sust_p_2d_array_v4i32_trap", + "llvm.nvvm.sust.p.2d.array.v4i8.trap" => "__nvvm_sust_p_2d_array_v4i8_trap", + "llvm.nvvm.sust.p.2d.i16.trap" => "__nvvm_sust_p_2d_i16_trap", + "llvm.nvvm.sust.p.2d.i32.trap" => "__nvvm_sust_p_2d_i32_trap", + "llvm.nvvm.sust.p.2d.i8.trap" => "__nvvm_sust_p_2d_i8_trap", + "llvm.nvvm.sust.p.2d.v2i16.trap" => "__nvvm_sust_p_2d_v2i16_trap", + "llvm.nvvm.sust.p.2d.v2i32.trap" => "__nvvm_sust_p_2d_v2i32_trap", + "llvm.nvvm.sust.p.2d.v2i8.trap" => "__nvvm_sust_p_2d_v2i8_trap", + "llvm.nvvm.sust.p.2d.v4i16.trap" => "__nvvm_sust_p_2d_v4i16_trap", + "llvm.nvvm.sust.p.2d.v4i32.trap" => "__nvvm_sust_p_2d_v4i32_trap", + "llvm.nvvm.sust.p.2d.v4i8.trap" => "__nvvm_sust_p_2d_v4i8_trap", + "llvm.nvvm.sust.p.3d.i16.trap" => "__nvvm_sust_p_3d_i16_trap", + "llvm.nvvm.sust.p.3d.i32.trap" => "__nvvm_sust_p_3d_i32_trap", + "llvm.nvvm.sust.p.3d.i8.trap" => "__nvvm_sust_p_3d_i8_trap", + "llvm.nvvm.sust.p.3d.v2i16.trap" => "__nvvm_sust_p_3d_v2i16_trap", + "llvm.nvvm.sust.p.3d.v2i32.trap" => "__nvvm_sust_p_3d_v2i32_trap", + "llvm.nvvm.sust.p.3d.v2i8.trap" => "__nvvm_sust_p_3d_v2i8_trap", + "llvm.nvvm.sust.p.3d.v4i16.trap" => "__nvvm_sust_p_3d_v4i16_trap", + "llvm.nvvm.sust.p.3d.v4i32.trap" => "__nvvm_sust_p_3d_v4i32_trap", + "llvm.nvvm.sust.p.3d.v4i8.trap" => "__nvvm_sust_p_3d_v4i8_trap", + "llvm.nvvm.swap.lo.hi.b64" => "__nvvm_swap_lo_hi_b64", + "llvm.nvvm.trunc.d" => "__nvvm_trunc_d", + "llvm.nvvm.trunc.f" => "__nvvm_trunc_f", + "llvm.nvvm.trunc.ftz.f" => "__nvvm_trunc_ftz_f", + "llvm.nvvm.txq.array.size" => "__nvvm_txq_array_size", + "llvm.nvvm.txq.channel.data.type" => "__nvvm_txq_channel_data_type", + "llvm.nvvm.txq.channel.order" => "__nvvm_txq_channel_order", + "llvm.nvvm.txq.depth" => "__nvvm_txq_depth", + "llvm.nvvm.txq.height" => "__nvvm_txq_height", + "llvm.nvvm.txq.num.mipmap.levels" => "__nvvm_txq_num_mipmap_levels", + "llvm.nvvm.txq.num.samples" => "__nvvm_txq_num_samples", + "llvm.nvvm.txq.width" => "__nvvm_txq_width", + "llvm.nvvm.ui2d.rm" => "__nvvm_ui2d_rm", + "llvm.nvvm.ui2d.rn" => "__nvvm_ui2d_rn", + "llvm.nvvm.ui2d.rp" => "__nvvm_ui2d_rp", + "llvm.nvvm.ui2d.rz" => "__nvvm_ui2d_rz", + "llvm.nvvm.ui2f.rm" => "__nvvm_ui2f_rm", + "llvm.nvvm.ui2f.rn" => "__nvvm_ui2f_rn", + "llvm.nvvm.ui2f.rp" => "__nvvm_ui2f_rp", + "llvm.nvvm.ui2f.rz" => "__nvvm_ui2f_rz", + "llvm.nvvm.ull2d.rm" => "__nvvm_ull2d_rm", + "llvm.nvvm.ull2d.rn" => "__nvvm_ull2d_rn", + "llvm.nvvm.ull2d.rp" => "__nvvm_ull2d_rp", + "llvm.nvvm.ull2d.rz" => "__nvvm_ull2d_rz", + "llvm.nvvm.ull2f.rm" => "__nvvm_ull2f_rm", + "llvm.nvvm.ull2f.rn" => "__nvvm_ull2f_rn", + "llvm.nvvm.ull2f.rp" => "__nvvm_ull2f_rp", + "llvm.nvvm.ull2f.rz" => "__nvvm_ull2f_rz", + // ppc + "llvm.ppc.addex" => "__builtin_ppc_addex", + "llvm.ppc.addf128.round.to.odd" => "__builtin_addf128_round_to_odd", + "llvm.ppc.altivec.crypto.vcipher" => "__builtin_altivec_crypto_vcipher", + "llvm.ppc.altivec.crypto.vcipherlast" => "__builtin_altivec_crypto_vcipherlast", + "llvm.ppc.altivec.crypto.vncipher" => "__builtin_altivec_crypto_vncipher", + "llvm.ppc.altivec.crypto.vncipherlast" => "__builtin_altivec_crypto_vncipherlast", + "llvm.ppc.altivec.crypto.vpermxor" => "__builtin_altivec_crypto_vpermxor", + "llvm.ppc.altivec.crypto.vpermxor.be" => "__builtin_altivec_crypto_vpermxor_be", + "llvm.ppc.altivec.crypto.vpmsumb" => "__builtin_altivec_crypto_vpmsumb", + "llvm.ppc.altivec.crypto.vpmsumd" => "__builtin_altivec_crypto_vpmsumd", + "llvm.ppc.altivec.crypto.vpmsumh" => "__builtin_altivec_crypto_vpmsumh", + "llvm.ppc.altivec.crypto.vpmsumw" => "__builtin_altivec_crypto_vpmsumw", + "llvm.ppc.altivec.crypto.vsbox" => "__builtin_altivec_crypto_vsbox", + "llvm.ppc.altivec.crypto.vshasigmad" => "__builtin_altivec_crypto_vshasigmad", + "llvm.ppc.altivec.crypto.vshasigmaw" => "__builtin_altivec_crypto_vshasigmaw", + "llvm.ppc.altivec.dss" => "__builtin_altivec_dss", + "llvm.ppc.altivec.dssall" => "__builtin_altivec_dssall", + "llvm.ppc.altivec.dst" => "__builtin_altivec_dst", + "llvm.ppc.altivec.dstst" => "__builtin_altivec_dstst", + "llvm.ppc.altivec.dststt" => "__builtin_altivec_dststt", + "llvm.ppc.altivec.dstt" => "__builtin_altivec_dstt", + "llvm.ppc.altivec.mfvscr" => "__builtin_altivec_mfvscr", + "llvm.ppc.altivec.mtvscr" => "__builtin_altivec_mtvscr", + "llvm.ppc.altivec.mtvsrbm" => "__builtin_altivec_mtvsrbm", + "llvm.ppc.altivec.mtvsrdm" => "__builtin_altivec_mtvsrdm", + "llvm.ppc.altivec.mtvsrhm" => "__builtin_altivec_mtvsrhm", + "llvm.ppc.altivec.mtvsrqm" => "__builtin_altivec_mtvsrqm", + "llvm.ppc.altivec.mtvsrwm" => "__builtin_altivec_mtvsrwm", + "llvm.ppc.altivec.vaddcuw" => "__builtin_altivec_vaddcuw", + "llvm.ppc.altivec.vaddecuq" => "__builtin_altivec_vaddecuq", + "llvm.ppc.altivec.vaddeuqm" => "__builtin_altivec_vaddeuqm", + "llvm.ppc.altivec.vaddsbs" => "__builtin_altivec_vaddsbs", + "llvm.ppc.altivec.vaddshs" => "__builtin_altivec_vaddshs", + "llvm.ppc.altivec.vaddsws" => "__builtin_altivec_vaddsws", + "llvm.ppc.altivec.vaddubs" => "__builtin_altivec_vaddubs", + "llvm.ppc.altivec.vadduhs" => "__builtin_altivec_vadduhs", + "llvm.ppc.altivec.vadduws" => "__builtin_altivec_vadduws", + "llvm.ppc.altivec.vavgsb" => "__builtin_altivec_vavgsb", + "llvm.ppc.altivec.vavgsh" => "__builtin_altivec_vavgsh", + "llvm.ppc.altivec.vavgsw" => "__builtin_altivec_vavgsw", + "llvm.ppc.altivec.vavgub" => "__builtin_altivec_vavgub", + "llvm.ppc.altivec.vavguh" => "__builtin_altivec_vavguh", + "llvm.ppc.altivec.vavguw" => "__builtin_altivec_vavguw", + "llvm.ppc.altivec.vbpermd" => "__builtin_altivec_vbpermd", + "llvm.ppc.altivec.vbpermq" => "__builtin_altivec_vbpermq", + "llvm.ppc.altivec.vcfsx" => "__builtin_altivec_vcfsx", + "llvm.ppc.altivec.vcfuged" => "__builtin_altivec_vcfuged", + "llvm.ppc.altivec.vcfux" => "__builtin_altivec_vcfux", + "llvm.ppc.altivec.vclrlb" => "__builtin_altivec_vclrlb", + "llvm.ppc.altivec.vclrrb" => "__builtin_altivec_vclrrb", + "llvm.ppc.altivec.vclzdm" => "__builtin_altivec_vclzdm", + "llvm.ppc.altivec.vclzlsbb" => "__builtin_altivec_vclzlsbb", + "llvm.ppc.altivec.vcmpbfp" => "__builtin_altivec_vcmpbfp", + "llvm.ppc.altivec.vcmpbfp.p" => "__builtin_altivec_vcmpbfp_p", + "llvm.ppc.altivec.vcmpeqfp" => "__builtin_altivec_vcmpeqfp", + "llvm.ppc.altivec.vcmpeqfp.p" => "__builtin_altivec_vcmpeqfp_p", + "llvm.ppc.altivec.vcmpequb" => "__builtin_altivec_vcmpequb", + "llvm.ppc.altivec.vcmpequb.p" => "__builtin_altivec_vcmpequb_p", + "llvm.ppc.altivec.vcmpequd" => "__builtin_altivec_vcmpequd", + "llvm.ppc.altivec.vcmpequd.p" => "__builtin_altivec_vcmpequd_p", + "llvm.ppc.altivec.vcmpequh" => "__builtin_altivec_vcmpequh", + "llvm.ppc.altivec.vcmpequh.p" => "__builtin_altivec_vcmpequh_p", + "llvm.ppc.altivec.vcmpequq" => "__builtin_altivec_vcmpequq", + "llvm.ppc.altivec.vcmpequq.p" => "__builtin_altivec_vcmpequq_p", + "llvm.ppc.altivec.vcmpequw" => "__builtin_altivec_vcmpequw", + "llvm.ppc.altivec.vcmpequw.p" => "__builtin_altivec_vcmpequw_p", + "llvm.ppc.altivec.vcmpgefp" => "__builtin_altivec_vcmpgefp", + "llvm.ppc.altivec.vcmpgefp.p" => "__builtin_altivec_vcmpgefp_p", + "llvm.ppc.altivec.vcmpgtfp" => "__builtin_altivec_vcmpgtfp", + "llvm.ppc.altivec.vcmpgtfp.p" => "__builtin_altivec_vcmpgtfp_p", + "llvm.ppc.altivec.vcmpgtsb" => "__builtin_altivec_vcmpgtsb", + "llvm.ppc.altivec.vcmpgtsb.p" => "__builtin_altivec_vcmpgtsb_p", + "llvm.ppc.altivec.vcmpgtsd" => "__builtin_altivec_vcmpgtsd", + "llvm.ppc.altivec.vcmpgtsd.p" => "__builtin_altivec_vcmpgtsd_p", + "llvm.ppc.altivec.vcmpgtsh" => "__builtin_altivec_vcmpgtsh", + "llvm.ppc.altivec.vcmpgtsh.p" => "__builtin_altivec_vcmpgtsh_p", + "llvm.ppc.altivec.vcmpgtsq" => "__builtin_altivec_vcmpgtsq", + "llvm.ppc.altivec.vcmpgtsq.p" => "__builtin_altivec_vcmpgtsq_p", + "llvm.ppc.altivec.vcmpgtsw" => "__builtin_altivec_vcmpgtsw", + "llvm.ppc.altivec.vcmpgtsw.p" => "__builtin_altivec_vcmpgtsw_p", + "llvm.ppc.altivec.vcmpgtub" => "__builtin_altivec_vcmpgtub", + "llvm.ppc.altivec.vcmpgtub.p" => "__builtin_altivec_vcmpgtub_p", + "llvm.ppc.altivec.vcmpgtud" => "__builtin_altivec_vcmpgtud", + "llvm.ppc.altivec.vcmpgtud.p" => "__builtin_altivec_vcmpgtud_p", + "llvm.ppc.altivec.vcmpgtuh" => "__builtin_altivec_vcmpgtuh", + "llvm.ppc.altivec.vcmpgtuh.p" => "__builtin_altivec_vcmpgtuh_p", + "llvm.ppc.altivec.vcmpgtuq" => "__builtin_altivec_vcmpgtuq", + "llvm.ppc.altivec.vcmpgtuq.p" => "__builtin_altivec_vcmpgtuq_p", + "llvm.ppc.altivec.vcmpgtuw" => "__builtin_altivec_vcmpgtuw", + "llvm.ppc.altivec.vcmpgtuw.p" => "__builtin_altivec_vcmpgtuw_p", + "llvm.ppc.altivec.vcmpneb" => "__builtin_altivec_vcmpneb", + "llvm.ppc.altivec.vcmpneb.p" => "__builtin_altivec_vcmpneb_p", + "llvm.ppc.altivec.vcmpneh" => "__builtin_altivec_vcmpneh", + "llvm.ppc.altivec.vcmpneh.p" => "__builtin_altivec_vcmpneh_p", + "llvm.ppc.altivec.vcmpnew" => "__builtin_altivec_vcmpnew", + "llvm.ppc.altivec.vcmpnew.p" => "__builtin_altivec_vcmpnew_p", + "llvm.ppc.altivec.vcmpnezb" => "__builtin_altivec_vcmpnezb", + "llvm.ppc.altivec.vcmpnezb.p" => "__builtin_altivec_vcmpnezb_p", + "llvm.ppc.altivec.vcmpnezh" => "__builtin_altivec_vcmpnezh", + "llvm.ppc.altivec.vcmpnezh.p" => "__builtin_altivec_vcmpnezh_p", + "llvm.ppc.altivec.vcmpnezw" => "__builtin_altivec_vcmpnezw", + "llvm.ppc.altivec.vcmpnezw.p" => "__builtin_altivec_vcmpnezw_p", + "llvm.ppc.altivec.vcntmbb" => "__builtin_altivec_vcntmbb", + "llvm.ppc.altivec.vcntmbd" => "__builtin_altivec_vcntmbd", + "llvm.ppc.altivec.vcntmbh" => "__builtin_altivec_vcntmbh", + "llvm.ppc.altivec.vcntmbw" => "__builtin_altivec_vcntmbw", + "llvm.ppc.altivec.vctsxs" => "__builtin_altivec_vctsxs", + "llvm.ppc.altivec.vctuxs" => "__builtin_altivec_vctuxs", + "llvm.ppc.altivec.vctzdm" => "__builtin_altivec_vctzdm", + "llvm.ppc.altivec.vctzlsbb" => "__builtin_altivec_vctzlsbb", + "llvm.ppc.altivec.vexpandbm" => "__builtin_altivec_vexpandbm", + "llvm.ppc.altivec.vexpanddm" => "__builtin_altivec_vexpanddm", + "llvm.ppc.altivec.vexpandhm" => "__builtin_altivec_vexpandhm", + "llvm.ppc.altivec.vexpandqm" => "__builtin_altivec_vexpandqm", + "llvm.ppc.altivec.vexpandwm" => "__builtin_altivec_vexpandwm", + "llvm.ppc.altivec.vexptefp" => "__builtin_altivec_vexptefp", + "llvm.ppc.altivec.vextddvlx" => "__builtin_altivec_vextddvlx", + "llvm.ppc.altivec.vextddvrx" => "__builtin_altivec_vextddvrx", + "llvm.ppc.altivec.vextdubvlx" => "__builtin_altivec_vextdubvlx", + "llvm.ppc.altivec.vextdubvrx" => "__builtin_altivec_vextdubvrx", + "llvm.ppc.altivec.vextduhvlx" => "__builtin_altivec_vextduhvlx", + "llvm.ppc.altivec.vextduhvrx" => "__builtin_altivec_vextduhvrx", + "llvm.ppc.altivec.vextduwvlx" => "__builtin_altivec_vextduwvlx", + "llvm.ppc.altivec.vextduwvrx" => "__builtin_altivec_vextduwvrx", + "llvm.ppc.altivec.vextractbm" => "__builtin_altivec_vextractbm", + "llvm.ppc.altivec.vextractdm" => "__builtin_altivec_vextractdm", + "llvm.ppc.altivec.vextracthm" => "__builtin_altivec_vextracthm", + "llvm.ppc.altivec.vextractqm" => "__builtin_altivec_vextractqm", + "llvm.ppc.altivec.vextractwm" => "__builtin_altivec_vextractwm", + "llvm.ppc.altivec.vextsb2d" => "__builtin_altivec_vextsb2d", + "llvm.ppc.altivec.vextsb2w" => "__builtin_altivec_vextsb2w", + "llvm.ppc.altivec.vextsd2q" => "__builtin_altivec_vextsd2q", + "llvm.ppc.altivec.vextsh2d" => "__builtin_altivec_vextsh2d", + "llvm.ppc.altivec.vextsh2w" => "__builtin_altivec_vextsh2w", + "llvm.ppc.altivec.vextsw2d" => "__builtin_altivec_vextsw2d", + "llvm.ppc.altivec.vgbbd" => "__builtin_altivec_vgbbd", + "llvm.ppc.altivec.vgnb" => "__builtin_altivec_vgnb", + "llvm.ppc.altivec.vinsblx" => "__builtin_altivec_vinsblx", + "llvm.ppc.altivec.vinsbrx" => "__builtin_altivec_vinsbrx", + "llvm.ppc.altivec.vinsbvlx" => "__builtin_altivec_vinsbvlx", + "llvm.ppc.altivec.vinsbvrx" => "__builtin_altivec_vinsbvrx", + "llvm.ppc.altivec.vinsdlx" => "__builtin_altivec_vinsdlx", + "llvm.ppc.altivec.vinsdrx" => "__builtin_altivec_vinsdrx", + "llvm.ppc.altivec.vinshlx" => "__builtin_altivec_vinshlx", + "llvm.ppc.altivec.vinshrx" => "__builtin_altivec_vinshrx", + "llvm.ppc.altivec.vinshvlx" => "__builtin_altivec_vinshvlx", + "llvm.ppc.altivec.vinshvrx" => "__builtin_altivec_vinshvrx", + "llvm.ppc.altivec.vinswlx" => "__builtin_altivec_vinswlx", + "llvm.ppc.altivec.vinswrx" => "__builtin_altivec_vinswrx", + "llvm.ppc.altivec.vinswvlx" => "__builtin_altivec_vinswvlx", + "llvm.ppc.altivec.vinswvrx" => "__builtin_altivec_vinswvrx", + "llvm.ppc.altivec.vlogefp" => "__builtin_altivec_vlogefp", + "llvm.ppc.altivec.vmaddfp" => "__builtin_altivec_vmaddfp", + "llvm.ppc.altivec.vmaxfp" => "__builtin_altivec_vmaxfp", + "llvm.ppc.altivec.vmaxsb" => "__builtin_altivec_vmaxsb", + "llvm.ppc.altivec.vmaxsd" => "__builtin_altivec_vmaxsd", + "llvm.ppc.altivec.vmaxsh" => "__builtin_altivec_vmaxsh", + "llvm.ppc.altivec.vmaxsw" => "__builtin_altivec_vmaxsw", + "llvm.ppc.altivec.vmaxub" => "__builtin_altivec_vmaxub", + "llvm.ppc.altivec.vmaxud" => "__builtin_altivec_vmaxud", + "llvm.ppc.altivec.vmaxuh" => "__builtin_altivec_vmaxuh", + "llvm.ppc.altivec.vmaxuw" => "__builtin_altivec_vmaxuw", + "llvm.ppc.altivec.vmhaddshs" => "__builtin_altivec_vmhaddshs", + "llvm.ppc.altivec.vmhraddshs" => "__builtin_altivec_vmhraddshs", + "llvm.ppc.altivec.vminfp" => "__builtin_altivec_vminfp", + "llvm.ppc.altivec.vminsb" => "__builtin_altivec_vminsb", + "llvm.ppc.altivec.vminsd" => "__builtin_altivec_vminsd", + "llvm.ppc.altivec.vminsh" => "__builtin_altivec_vminsh", + "llvm.ppc.altivec.vminsw" => "__builtin_altivec_vminsw", + "llvm.ppc.altivec.vminub" => "__builtin_altivec_vminub", + "llvm.ppc.altivec.vminud" => "__builtin_altivec_vminud", + "llvm.ppc.altivec.vminuh" => "__builtin_altivec_vminuh", + "llvm.ppc.altivec.vminuw" => "__builtin_altivec_vminuw", + "llvm.ppc.altivec.vmladduhm" => "__builtin_altivec_vmladduhm", + "llvm.ppc.altivec.vmsumcud" => "__builtin_altivec_vmsumcud", + "llvm.ppc.altivec.vmsummbm" => "__builtin_altivec_vmsummbm", + "llvm.ppc.altivec.vmsumshm" => "__builtin_altivec_vmsumshm", + "llvm.ppc.altivec.vmsumshs" => "__builtin_altivec_vmsumshs", + "llvm.ppc.altivec.vmsumubm" => "__builtin_altivec_vmsumubm", + "llvm.ppc.altivec.vmsumudm" => "__builtin_altivec_vmsumudm", + "llvm.ppc.altivec.vmsumuhm" => "__builtin_altivec_vmsumuhm", + "llvm.ppc.altivec.vmsumuhs" => "__builtin_altivec_vmsumuhs", + "llvm.ppc.altivec.vmulesb" => "__builtin_altivec_vmulesb", + "llvm.ppc.altivec.vmulesh" => "__builtin_altivec_vmulesh", + "llvm.ppc.altivec.vmulesw" => "__builtin_altivec_vmulesw", + "llvm.ppc.altivec.vmuleub" => "__builtin_altivec_vmuleub", + "llvm.ppc.altivec.vmuleuh" => "__builtin_altivec_vmuleuh", + "llvm.ppc.altivec.vmuleuw" => "__builtin_altivec_vmuleuw", + "llvm.ppc.altivec.vmulosb" => "__builtin_altivec_vmulosb", + "llvm.ppc.altivec.vmulosh" => "__builtin_altivec_vmulosh", + "llvm.ppc.altivec.vmulosw" => "__builtin_altivec_vmulosw", + "llvm.ppc.altivec.vmuloub" => "__builtin_altivec_vmuloub", + "llvm.ppc.altivec.vmulouh" => "__builtin_altivec_vmulouh", + "llvm.ppc.altivec.vmulouw" => "__builtin_altivec_vmulouw", + "llvm.ppc.altivec.vnmsubfp" => "__builtin_altivec_vnmsubfp", + "llvm.ppc.altivec.vpdepd" => "__builtin_altivec_vpdepd", + "llvm.ppc.altivec.vperm" => "__builtin_altivec_vperm_4si", + "llvm.ppc.altivec.vpextd" => "__builtin_altivec_vpextd", + "llvm.ppc.altivec.vpkpx" => "__builtin_altivec_vpkpx", + "llvm.ppc.altivec.vpksdss" => "__builtin_altivec_vpksdss", + "llvm.ppc.altivec.vpksdus" => "__builtin_altivec_vpksdus", + "llvm.ppc.altivec.vpkshss" => "__builtin_altivec_vpkshss", + "llvm.ppc.altivec.vpkshus" => "__builtin_altivec_vpkshus", + "llvm.ppc.altivec.vpkswss" => "__builtin_altivec_vpkswss", + "llvm.ppc.altivec.vpkswus" => "__builtin_altivec_vpkswus", + "llvm.ppc.altivec.vpkudus" => "__builtin_altivec_vpkudus", + "llvm.ppc.altivec.vpkuhus" => "__builtin_altivec_vpkuhus", + "llvm.ppc.altivec.vpkuwus" => "__builtin_altivec_vpkuwus", + "llvm.ppc.altivec.vprtybd" => "__builtin_altivec_vprtybd", + "llvm.ppc.altivec.vprtybq" => "__builtin_altivec_vprtybq", + "llvm.ppc.altivec.vprtybw" => "__builtin_altivec_vprtybw", + "llvm.ppc.altivec.vrefp" => "__builtin_altivec_vrefp", + "llvm.ppc.altivec.vrfim" => "__builtin_altivec_vrfim", + "llvm.ppc.altivec.vrfin" => "__builtin_altivec_vrfin", + "llvm.ppc.altivec.vrfip" => "__builtin_altivec_vrfip", + "llvm.ppc.altivec.vrfiz" => "__builtin_altivec_vrfiz", + "llvm.ppc.altivec.vrlb" => "__builtin_altivec_vrlb", + "llvm.ppc.altivec.vrld" => "__builtin_altivec_vrld", + "llvm.ppc.altivec.vrlh" => "__builtin_altivec_vrlh", + "llvm.ppc.altivec.vrlw" => "__builtin_altivec_vrlw", + "llvm.ppc.altivec.vrsqrtefp" => "__builtin_altivec_vrsqrtefp", + "llvm.ppc.altivec.vsel" => "__builtin_altivec_vsel_4si", + "llvm.ppc.altivec.vsl" => "__builtin_altivec_vsl", + "llvm.ppc.altivec.vslb" => "__builtin_altivec_vslb", + "llvm.ppc.altivec.vsldbi" => "__builtin_altivec_vsldbi", + "llvm.ppc.altivec.vslh" => "__builtin_altivec_vslh", + "llvm.ppc.altivec.vslo" => "__builtin_altivec_vslo", + "llvm.ppc.altivec.vslw" => "__builtin_altivec_vslw", + "llvm.ppc.altivec.vsr" => "__builtin_altivec_vsr", + "llvm.ppc.altivec.vsrab" => "__builtin_altivec_vsrab", + "llvm.ppc.altivec.vsrah" => "__builtin_altivec_vsrah", + "llvm.ppc.altivec.vsraw" => "__builtin_altivec_vsraw", + "llvm.ppc.altivec.vsrb" => "__builtin_altivec_vsrb", + "llvm.ppc.altivec.vsrdbi" => "__builtin_altivec_vsrdbi", + "llvm.ppc.altivec.vsrh" => "__builtin_altivec_vsrh", + "llvm.ppc.altivec.vsro" => "__builtin_altivec_vsro", + "llvm.ppc.altivec.vsrw" => "__builtin_altivec_vsrw", + "llvm.ppc.altivec.vstribl" => "__builtin_altivec_vstribl", + "llvm.ppc.altivec.vstribl.p" => "__builtin_altivec_vstribl_p", + "llvm.ppc.altivec.vstribr" => "__builtin_altivec_vstribr", + "llvm.ppc.altivec.vstribr.p" => "__builtin_altivec_vstribr_p", + "llvm.ppc.altivec.vstrihl" => "__builtin_altivec_vstrihl", + "llvm.ppc.altivec.vstrihl.p" => "__builtin_altivec_vstrihl_p", + "llvm.ppc.altivec.vstrihr" => "__builtin_altivec_vstrihr", + "llvm.ppc.altivec.vstrihr.p" => "__builtin_altivec_vstrihr_p", + "llvm.ppc.altivec.vsubcuw" => "__builtin_altivec_vsubcuw", + "llvm.ppc.altivec.vsubecuq" => "__builtin_altivec_vsubecuq", + "llvm.ppc.altivec.vsubeuqm" => "__builtin_altivec_vsubeuqm", + "llvm.ppc.altivec.vsubsbs" => "__builtin_altivec_vsubsbs", + "llvm.ppc.altivec.vsubshs" => "__builtin_altivec_vsubshs", + "llvm.ppc.altivec.vsubsws" => "__builtin_altivec_vsubsws", + "llvm.ppc.altivec.vsububs" => "__builtin_altivec_vsububs", + "llvm.ppc.altivec.vsubuhs" => "__builtin_altivec_vsubuhs", + "llvm.ppc.altivec.vsubuws" => "__builtin_altivec_vsubuws", + "llvm.ppc.altivec.vsum2sws" => "__builtin_altivec_vsum2sws", + "llvm.ppc.altivec.vsum4sbs" => "__builtin_altivec_vsum4sbs", + "llvm.ppc.altivec.vsum4shs" => "__builtin_altivec_vsum4shs", + "llvm.ppc.altivec.vsum4ubs" => "__builtin_altivec_vsum4ubs", + "llvm.ppc.altivec.vsumsws" => "__builtin_altivec_vsumsws", + "llvm.ppc.altivec.vupkhpx" => "__builtin_altivec_vupkhpx", + "llvm.ppc.altivec.vupkhsb" => "__builtin_altivec_vupkhsb", + "llvm.ppc.altivec.vupkhsh" => "__builtin_altivec_vupkhsh", + "llvm.ppc.altivec.vupkhsw" => "__builtin_altivec_vupkhsw", + "llvm.ppc.altivec.vupklpx" => "__builtin_altivec_vupklpx", + "llvm.ppc.altivec.vupklsb" => "__builtin_altivec_vupklsb", + "llvm.ppc.altivec.vupklsh" => "__builtin_altivec_vupklsh", + "llvm.ppc.altivec.vupklsw" => "__builtin_altivec_vupklsw", + "llvm.ppc.bcdadd" => "__builtin_ppc_bcdadd", + "llvm.ppc.bcdadd.p" => "__builtin_ppc_bcdadd_p", + "llvm.ppc.bcdsub" => "__builtin_ppc_bcdsub", + "llvm.ppc.bcdsub.p" => "__builtin_ppc_bcdsub_p", + "llvm.ppc.bpermd" => "__builtin_bpermd", + "llvm.ppc.cfuged" => "__builtin_cfuged", + "llvm.ppc.cmpeqb" => "__builtin_ppc_cmpeqb", + "llvm.ppc.cmprb" => "__builtin_ppc_cmprb", + "llvm.ppc.cntlzdm" => "__builtin_cntlzdm", + "llvm.ppc.cnttzdm" => "__builtin_cnttzdm", + "llvm.ppc.compare.exp.eq" => "__builtin_ppc_compare_exp_eq", + "llvm.ppc.compare.exp.gt" => "__builtin_ppc_compare_exp_gt", + "llvm.ppc.compare.exp.lt" => "__builtin_ppc_compare_exp_lt", + "llvm.ppc.compare.exp.uo" => "__builtin_ppc_compare_exp_uo", + "llvm.ppc.darn" => "__builtin_darn", + "llvm.ppc.darn32" => "__builtin_darn_32", + "llvm.ppc.darnraw" => "__builtin_darn_raw", + "llvm.ppc.dcbf" => "__builtin_dcbf", + "llvm.ppc.dcbfl" => "__builtin_ppc_dcbfl", + "llvm.ppc.dcbflp" => "__builtin_ppc_dcbflp", + "llvm.ppc.dcbst" => "__builtin_ppc_dcbst", + "llvm.ppc.dcbt" => "__builtin_ppc_dcbt", + "llvm.ppc.dcbtst" => "__builtin_ppc_dcbtst", + "llvm.ppc.dcbtstt" => "__builtin_ppc_dcbtstt", + "llvm.ppc.dcbtt" => "__builtin_ppc_dcbtt", + "llvm.ppc.dcbz" => "__builtin_ppc_dcbz", + "llvm.ppc.divde" => "__builtin_divde", + "llvm.ppc.divdeu" => "__builtin_divdeu", + "llvm.ppc.divf128.round.to.odd" => "__builtin_divf128_round_to_odd", + "llvm.ppc.divwe" => "__builtin_divwe", + "llvm.ppc.divweu" => "__builtin_divweu", + "llvm.ppc.eieio" => "__builtin_ppc_eieio", + "llvm.ppc.extract.exp" => "__builtin_ppc_extract_exp", + "llvm.ppc.extract.sig" => "__builtin_ppc_extract_sig", + "llvm.ppc.fcfid" => "__builtin_ppc_fcfid", + "llvm.ppc.fcfud" => "__builtin_ppc_fcfud", + "llvm.ppc.fctid" => "__builtin_ppc_fctid", + "llvm.ppc.fctidz" => "__builtin_ppc_fctidz", + "llvm.ppc.fctiw" => "__builtin_ppc_fctiw", + "llvm.ppc.fctiwz" => "__builtin_ppc_fctiwz", + "llvm.ppc.fctudz" => "__builtin_ppc_fctudz", + "llvm.ppc.fctuwz" => "__builtin_ppc_fctuwz", + "llvm.ppc.fmaf128.round.to.odd" => "__builtin_fmaf128_round_to_odd", + "llvm.ppc.fmsub" => "__builtin_ppc_fmsub", + "llvm.ppc.fmsubs" => "__builtin_ppc_fmsubs", + "llvm.ppc.fnmadd" => "__builtin_ppc_fnmadd", + "llvm.ppc.fnmadds" => "__builtin_ppc_fnmadds", + "llvm.ppc.fre" => "__builtin_ppc_fre", + "llvm.ppc.fres" => "__builtin_ppc_fres", + "llvm.ppc.frsqrte" => "__builtin_ppc_frsqrte", + "llvm.ppc.frsqrtes" => "__builtin_ppc_frsqrtes", + "llvm.ppc.fsel" => "__builtin_ppc_fsel", + "llvm.ppc.fsels" => "__builtin_ppc_fsels", + "llvm.ppc.get.texasr" => "__builtin_get_texasr", + "llvm.ppc.get.texasru" => "__builtin_get_texasru", + "llvm.ppc.get.tfhar" => "__builtin_get_tfhar", + "llvm.ppc.get.tfiar" => "__builtin_get_tfiar", + "llvm.ppc.icbt" => "__builtin_ppc_icbt", + "llvm.ppc.insert.exp" => "__builtin_ppc_insert_exp", + "llvm.ppc.iospace.eieio" => "__builtin_ppc_iospace_eieio", + "llvm.ppc.iospace.lwsync" => "__builtin_ppc_iospace_lwsync", + "llvm.ppc.iospace.sync" => "__builtin_ppc_iospace_sync", + "llvm.ppc.isync" => "__builtin_ppc_isync", + "llvm.ppc.load4r" => "__builtin_ppc_load4r", + "llvm.ppc.load8r" => "__builtin_ppc_load8r", + "llvm.ppc.lwsync" => "__builtin_ppc_lwsync", + "llvm.ppc.maddhd" => "__builtin_ppc_maddhd", + "llvm.ppc.maddhdu" => "__builtin_ppc_maddhdu", + "llvm.ppc.maddld" => "__builtin_ppc_maddld", + "llvm.ppc.mfmsr" => "__builtin_ppc_mfmsr", + "llvm.ppc.mftbu" => "__builtin_ppc_mftbu", + "llvm.ppc.mtfsb0" => "__builtin_ppc_mtfsb0", + "llvm.ppc.mtfsb1" => "__builtin_ppc_mtfsb1", + "llvm.ppc.mtfsfi" => "__builtin_ppc_mtfsfi", + "llvm.ppc.mtmsr" => "__builtin_ppc_mtmsr", + "llvm.ppc.mulf128.round.to.odd" => "__builtin_mulf128_round_to_odd", + "llvm.ppc.mulhd" => "__builtin_ppc_mulhd", + "llvm.ppc.mulhdu" => "__builtin_ppc_mulhdu", + "llvm.ppc.mulhw" => "__builtin_ppc_mulhw", + "llvm.ppc.mulhwu" => "__builtin_ppc_mulhwu", + "llvm.ppc.pack.longdouble" => "__builtin_pack_longdouble", + "llvm.ppc.pdepd" => "__builtin_pdepd", + "llvm.ppc.pextd" => "__builtin_pextd", + "llvm.ppc.qpx.qvfabs" => "__builtin_qpx_qvfabs", + "llvm.ppc.qpx.qvfadd" => "__builtin_qpx_qvfadd", + "llvm.ppc.qpx.qvfadds" => "__builtin_qpx_qvfadds", + "llvm.ppc.qpx.qvfcfid" => "__builtin_qpx_qvfcfid", + "llvm.ppc.qpx.qvfcfids" => "__builtin_qpx_qvfcfids", + "llvm.ppc.qpx.qvfcfidu" => "__builtin_qpx_qvfcfidu", + "llvm.ppc.qpx.qvfcfidus" => "__builtin_qpx_qvfcfidus", + "llvm.ppc.qpx.qvfcmpeq" => "__builtin_qpx_qvfcmpeq", + "llvm.ppc.qpx.qvfcmpgt" => "__builtin_qpx_qvfcmpgt", + "llvm.ppc.qpx.qvfcmplt" => "__builtin_qpx_qvfcmplt", + "llvm.ppc.qpx.qvfcpsgn" => "__builtin_qpx_qvfcpsgn", + "llvm.ppc.qpx.qvfctid" => "__builtin_qpx_qvfctid", + "llvm.ppc.qpx.qvfctidu" => "__builtin_qpx_qvfctidu", + "llvm.ppc.qpx.qvfctiduz" => "__builtin_qpx_qvfctiduz", + "llvm.ppc.qpx.qvfctidz" => "__builtin_qpx_qvfctidz", + "llvm.ppc.qpx.qvfctiw" => "__builtin_qpx_qvfctiw", + "llvm.ppc.qpx.qvfctiwu" => "__builtin_qpx_qvfctiwu", + "llvm.ppc.qpx.qvfctiwuz" => "__builtin_qpx_qvfctiwuz", + "llvm.ppc.qpx.qvfctiwz" => "__builtin_qpx_qvfctiwz", + "llvm.ppc.qpx.qvflogical" => "__builtin_qpx_qvflogical", + "llvm.ppc.qpx.qvfmadd" => "__builtin_qpx_qvfmadd", + "llvm.ppc.qpx.qvfmadds" => "__builtin_qpx_qvfmadds", + "llvm.ppc.qpx.qvfmsub" => "__builtin_qpx_qvfmsub", + "llvm.ppc.qpx.qvfmsubs" => "__builtin_qpx_qvfmsubs", + "llvm.ppc.qpx.qvfmul" => "__builtin_qpx_qvfmul", + "llvm.ppc.qpx.qvfmuls" => "__builtin_qpx_qvfmuls", + "llvm.ppc.qpx.qvfnabs" => "__builtin_qpx_qvfnabs", + "llvm.ppc.qpx.qvfneg" => "__builtin_qpx_qvfneg", + "llvm.ppc.qpx.qvfnmadd" => "__builtin_qpx_qvfnmadd", + "llvm.ppc.qpx.qvfnmadds" => "__builtin_qpx_qvfnmadds", + "llvm.ppc.qpx.qvfnmsub" => "__builtin_qpx_qvfnmsub", + "llvm.ppc.qpx.qvfnmsubs" => "__builtin_qpx_qvfnmsubs", + "llvm.ppc.qpx.qvfperm" => "__builtin_qpx_qvfperm", + "llvm.ppc.qpx.qvfre" => "__builtin_qpx_qvfre", + "llvm.ppc.qpx.qvfres" => "__builtin_qpx_qvfres", + "llvm.ppc.qpx.qvfrim" => "__builtin_qpx_qvfrim", + "llvm.ppc.qpx.qvfrin" => "__builtin_qpx_qvfrin", + "llvm.ppc.qpx.qvfrip" => "__builtin_qpx_qvfrip", + "llvm.ppc.qpx.qvfriz" => "__builtin_qpx_qvfriz", + "llvm.ppc.qpx.qvfrsp" => "__builtin_qpx_qvfrsp", + "llvm.ppc.qpx.qvfrsqrte" => "__builtin_qpx_qvfrsqrte", + "llvm.ppc.qpx.qvfrsqrtes" => "__builtin_qpx_qvfrsqrtes", + "llvm.ppc.qpx.qvfsel" => "__builtin_qpx_qvfsel", + "llvm.ppc.qpx.qvfsub" => "__builtin_qpx_qvfsub", + "llvm.ppc.qpx.qvfsubs" => "__builtin_qpx_qvfsubs", + "llvm.ppc.qpx.qvftstnan" => "__builtin_qpx_qvftstnan", + "llvm.ppc.qpx.qvfxmadd" => "__builtin_qpx_qvfxmadd", + "llvm.ppc.qpx.qvfxmadds" => "__builtin_qpx_qvfxmadds", + "llvm.ppc.qpx.qvfxmul" => "__builtin_qpx_qvfxmul", + "llvm.ppc.qpx.qvfxmuls" => "__builtin_qpx_qvfxmuls", + "llvm.ppc.qpx.qvfxxcpnmadd" => "__builtin_qpx_qvfxxcpnmadd", + "llvm.ppc.qpx.qvfxxcpnmadds" => "__builtin_qpx_qvfxxcpnmadds", + "llvm.ppc.qpx.qvfxxmadd" => "__builtin_qpx_qvfxxmadd", + "llvm.ppc.qpx.qvfxxmadds" => "__builtin_qpx_qvfxxmadds", + "llvm.ppc.qpx.qvfxxnpmadd" => "__builtin_qpx_qvfxxnpmadd", + "llvm.ppc.qpx.qvfxxnpmadds" => "__builtin_qpx_qvfxxnpmadds", + "llvm.ppc.qpx.qvgpci" => "__builtin_qpx_qvgpci", + "llvm.ppc.qpx.qvlfcd" => "__builtin_qpx_qvlfcd", + "llvm.ppc.qpx.qvlfcda" => "__builtin_qpx_qvlfcda", + "llvm.ppc.qpx.qvlfcs" => "__builtin_qpx_qvlfcs", + "llvm.ppc.qpx.qvlfcsa" => "__builtin_qpx_qvlfcsa", + "llvm.ppc.qpx.qvlfd" => "__builtin_qpx_qvlfd", + "llvm.ppc.qpx.qvlfda" => "__builtin_qpx_qvlfda", + "llvm.ppc.qpx.qvlfiwa" => "__builtin_qpx_qvlfiwa", + "llvm.ppc.qpx.qvlfiwaa" => "__builtin_qpx_qvlfiwaa", + "llvm.ppc.qpx.qvlfiwz" => "__builtin_qpx_qvlfiwz", + "llvm.ppc.qpx.qvlfiwza" => "__builtin_qpx_qvlfiwza", + "llvm.ppc.qpx.qvlfs" => "__builtin_qpx_qvlfs", + "llvm.ppc.qpx.qvlfsa" => "__builtin_qpx_qvlfsa", + "llvm.ppc.qpx.qvlpcld" => "__builtin_qpx_qvlpcld", + "llvm.ppc.qpx.qvlpcls" => "__builtin_qpx_qvlpcls", + "llvm.ppc.qpx.qvlpcrd" => "__builtin_qpx_qvlpcrd", + "llvm.ppc.qpx.qvlpcrs" => "__builtin_qpx_qvlpcrs", + "llvm.ppc.qpx.qvstfcd" => "__builtin_qpx_qvstfcd", + "llvm.ppc.qpx.qvstfcda" => "__builtin_qpx_qvstfcda", + "llvm.ppc.qpx.qvstfcs" => "__builtin_qpx_qvstfcs", + "llvm.ppc.qpx.qvstfcsa" => "__builtin_qpx_qvstfcsa", + "llvm.ppc.qpx.qvstfd" => "__builtin_qpx_qvstfd", + "llvm.ppc.qpx.qvstfda" => "__builtin_qpx_qvstfda", + "llvm.ppc.qpx.qvstfiw" => "__builtin_qpx_qvstfiw", + "llvm.ppc.qpx.qvstfiwa" => "__builtin_qpx_qvstfiwa", + "llvm.ppc.qpx.qvstfs" => "__builtin_qpx_qvstfs", + "llvm.ppc.qpx.qvstfsa" => "__builtin_qpx_qvstfsa", + "llvm.ppc.readflm" => "__builtin_readflm", + "llvm.ppc.scalar.extract.expq" => "__builtin_vsx_scalar_extract_expq", + "llvm.ppc.scalar.insert.exp.qp" => "__builtin_vsx_scalar_insert_exp_qp", + "llvm.ppc.set.texasr" => "__builtin_set_texasr", + "llvm.ppc.set.texasru" => "__builtin_set_texasru", + "llvm.ppc.set.tfhar" => "__builtin_set_tfhar", + "llvm.ppc.set.tfiar" => "__builtin_set_tfiar", + "llvm.ppc.setb" => "__builtin_ppc_setb", + "llvm.ppc.setflm" => "__builtin_setflm", + "llvm.ppc.setrnd" => "__builtin_setrnd", + "llvm.ppc.sqrtf128.round.to.odd" => "__builtin_sqrtf128_round_to_odd", + "llvm.ppc.stbcx" => "__builtin_ppc_stbcx", + "llvm.ppc.stdcx" => "__builtin_ppc_stdcx", + "llvm.ppc.stfiw" => "__builtin_ppc_stfiw", + "llvm.ppc.store2r" => "__builtin_ppc_store2r", + "llvm.ppc.store4r" => "__builtin_ppc_store4r", + "llvm.ppc.store8r" => "__builtin_ppc_store8r", + "llvm.ppc.stwcx" => "__builtin_ppc_stwcx", + "llvm.ppc.subf128.round.to.odd" => "__builtin_subf128_round_to_odd", + "llvm.ppc.sync" => "__builtin_ppc_sync", + "llvm.ppc.tabort" => "__builtin_tabort", + "llvm.ppc.tabortdc" => "__builtin_tabortdc", + "llvm.ppc.tabortdci" => "__builtin_tabortdci", + "llvm.ppc.tabortwc" => "__builtin_tabortwc", + "llvm.ppc.tabortwci" => "__builtin_tabortwci", + "llvm.ppc.tbegin" => "__builtin_tbegin", + "llvm.ppc.tcheck" => "__builtin_tcheck", + "llvm.ppc.tdw" => "__builtin_ppc_tdw", + "llvm.ppc.tend" => "__builtin_tend", + "llvm.ppc.tendall" => "__builtin_tendall", + "llvm.ppc.trap" => "__builtin_ppc_trap", + "llvm.ppc.trapd" => "__builtin_ppc_trapd", + "llvm.ppc.trechkpt" => "__builtin_trechkpt", + "llvm.ppc.treclaim" => "__builtin_treclaim", + "llvm.ppc.tresume" => "__builtin_tresume", + "llvm.ppc.truncf128.round.to.odd" => "__builtin_truncf128_round_to_odd", + "llvm.ppc.tsr" => "__builtin_tsr", + "llvm.ppc.tsuspend" => "__builtin_tsuspend", + "llvm.ppc.ttest" => "__builtin_ttest", + "llvm.ppc.tw" => "__builtin_ppc_tw", + "llvm.ppc.unpack.longdouble" => "__builtin_unpack_longdouble", + "llvm.ppc.vsx.xsmaxdp" => "__builtin_vsx_xsmaxdp", + "llvm.ppc.vsx.xsmindp" => "__builtin_vsx_xsmindp", + "llvm.ppc.vsx.xvcmpeqdp" => "__builtin_vsx_xvcmpeqdp", + "llvm.ppc.vsx.xvcmpeqdp.p" => "__builtin_vsx_xvcmpeqdp_p", + "llvm.ppc.vsx.xvcmpeqsp" => "__builtin_vsx_xvcmpeqsp", + "llvm.ppc.vsx.xvcmpeqsp.p" => "__builtin_vsx_xvcmpeqsp_p", + "llvm.ppc.vsx.xvcmpgedp" => "__builtin_vsx_xvcmpgedp", + "llvm.ppc.vsx.xvcmpgedp.p" => "__builtin_vsx_xvcmpgedp_p", + "llvm.ppc.vsx.xvcmpgesp" => "__builtin_vsx_xvcmpgesp", + "llvm.ppc.vsx.xvcmpgesp.p" => "__builtin_vsx_xvcmpgesp_p", + "llvm.ppc.vsx.xvcmpgtdp" => "__builtin_vsx_xvcmpgtdp", + "llvm.ppc.vsx.xvcmpgtdp.p" => "__builtin_vsx_xvcmpgtdp_p", + "llvm.ppc.vsx.xvcmpgtsp" => "__builtin_vsx_xvcmpgtsp", + "llvm.ppc.vsx.xvcmpgtsp.p" => "__builtin_vsx_xvcmpgtsp_p", + "llvm.ppc.vsx.xvdivdp" => "__builtin_vsx_xvdivdp", + "llvm.ppc.vsx.xvdivsp" => "__builtin_vsx_xvdivsp", + "llvm.ppc.vsx.xvmaxdp" => "__builtin_vsx_xvmaxdp", + "llvm.ppc.vsx.xvmaxsp" => "__builtin_vsx_xvmaxsp", + "llvm.ppc.vsx.xvmindp" => "__builtin_vsx_xvmindp", + "llvm.ppc.vsx.xvminsp" => "__builtin_vsx_xvminsp", + "llvm.ppc.vsx.xvredp" => "__builtin_vsx_xvredp", + "llvm.ppc.vsx.xvresp" => "__builtin_vsx_xvresp", + "llvm.ppc.vsx.xvrsqrtedp" => "__builtin_vsx_xvrsqrtedp", + "llvm.ppc.vsx.xvrsqrtesp" => "__builtin_vsx_xvrsqrtesp", + "llvm.ppc.vsx.xxblendvb" => "__builtin_vsx_xxblendvb", + "llvm.ppc.vsx.xxblendvd" => "__builtin_vsx_xxblendvd", + "llvm.ppc.vsx.xxblendvh" => "__builtin_vsx_xxblendvh", + "llvm.ppc.vsx.xxblendvw" => "__builtin_vsx_xxblendvw", + "llvm.ppc.vsx.xxleqv" => "__builtin_vsx_xxleqv", + "llvm.ppc.vsx.xxpermx" => "__builtin_vsx_xxpermx", + // ptx + "llvm.ptx.bar.sync" => "__builtin_ptx_bar_sync", + "llvm.ptx.read.clock" => "__builtin_ptx_read_clock", + "llvm.ptx.read.clock64" => "__builtin_ptx_read_clock64", + "llvm.ptx.read.gridid" => "__builtin_ptx_read_gridid", + "llvm.ptx.read.laneid" => "__builtin_ptx_read_laneid", + "llvm.ptx.read.lanemask.eq" => "__builtin_ptx_read_lanemask_eq", + "llvm.ptx.read.lanemask.ge" => "__builtin_ptx_read_lanemask_ge", + "llvm.ptx.read.lanemask.gt" => "__builtin_ptx_read_lanemask_gt", + "llvm.ptx.read.lanemask.le" => "__builtin_ptx_read_lanemask_le", + "llvm.ptx.read.lanemask.lt" => "__builtin_ptx_read_lanemask_lt", + "llvm.ptx.read.nsmid" => "__builtin_ptx_read_nsmid", + "llvm.ptx.read.nwarpid" => "__builtin_ptx_read_nwarpid", + "llvm.ptx.read.pm0" => "__builtin_ptx_read_pm0", + "llvm.ptx.read.pm1" => "__builtin_ptx_read_pm1", + "llvm.ptx.read.pm2" => "__builtin_ptx_read_pm2", + "llvm.ptx.read.pm3" => "__builtin_ptx_read_pm3", + "llvm.ptx.read.smid" => "__builtin_ptx_read_smid", + "llvm.ptx.read.warpid" => "__builtin_ptx_read_warpid", + // s390 + "llvm.s390.efpc" => "__builtin_s390_efpc", + "llvm.s390.etnd" => "__builtin_tx_nesting_depth", + "llvm.s390.lcbb" => "__builtin_s390_lcbb", + "llvm.s390.ppa.txassist" => "__builtin_tx_assist", + "llvm.s390.sfpc" => "__builtin_s390_sfpc", + "llvm.s390.tend" => "__builtin_tend", + "llvm.s390.vcfn" => "__builtin_s390_vcfn", + "llvm.s390.vclfnhs" => "__builtin_s390_vclfnhs", + "llvm.s390.vclfnls" => "__builtin_s390_vclfnls", + "llvm.s390.vcnf" => "__builtin_s390_vcnf", + "llvm.s390.vcrnfs" => "__builtin_s390_vcrnfs", + "llvm.s390.vlbb" => "__builtin_s390_vlbb", + "llvm.s390.vll" => "__builtin_s390_vll", + "llvm.s390.vlrl" => "__builtin_s390_vlrl", + "llvm.s390.vmslg" => "__builtin_s390_vmslg", + "llvm.s390.vpdi" => "__builtin_s390_vpdi", + "llvm.s390.vperm" => "__builtin_s390_vperm", + "llvm.s390.vsld" => "__builtin_s390_vsld", + "llvm.s390.vsldb" => "__builtin_s390_vsldb", + "llvm.s390.vsrd" => "__builtin_s390_vsrd", + "llvm.s390.vstl" => "__builtin_s390_vstl", + "llvm.s390.vstrl" => "__builtin_s390_vstrl", + // ve + "llvm.ve.vl.extract.vm512l" => "__builtin_ve_vl_extract_vm512l", + "llvm.ve.vl.extract.vm512u" => "__builtin_ve_vl_extract_vm512u", + "llvm.ve.vl.insert.vm512l" => "__builtin_ve_vl_insert_vm512l", + "llvm.ve.vl.insert.vm512u" => "__builtin_ve_vl_insert_vm512u", + "llvm.ve.vl.pack.f32a" => "__builtin_ve_vl_pack_f32a", + "llvm.ve.vl.pack.f32p" => "__builtin_ve_vl_pack_f32p", + // x86 + "llvm.x86.3dnow.pavgusb" => "__builtin_ia32_pavgusb", + "llvm.x86.3dnow.pf2id" => "__builtin_ia32_pf2id", + "llvm.x86.3dnow.pfacc" => "__builtin_ia32_pfacc", + "llvm.x86.3dnow.pfadd" => "__builtin_ia32_pfadd", + "llvm.x86.3dnow.pfcmpeq" => "__builtin_ia32_pfcmpeq", + "llvm.x86.3dnow.pfcmpge" => "__builtin_ia32_pfcmpge", + "llvm.x86.3dnow.pfcmpgt" => "__builtin_ia32_pfcmpgt", + "llvm.x86.3dnow.pfmax" => "__builtin_ia32_pfmax", + "llvm.x86.3dnow.pfmin" => "__builtin_ia32_pfmin", + "llvm.x86.3dnow.pfmul" => "__builtin_ia32_pfmul", + "llvm.x86.3dnow.pfrcp" => "__builtin_ia32_pfrcp", + "llvm.x86.3dnow.pfrcpit1" => "__builtin_ia32_pfrcpit1", + "llvm.x86.3dnow.pfrcpit2" => "__builtin_ia32_pfrcpit2", + "llvm.x86.3dnow.pfrsqit1" => "__builtin_ia32_pfrsqit1", + "llvm.x86.3dnow.pfrsqrt" => "__builtin_ia32_pfrsqrt", + "llvm.x86.3dnow.pfsub" => "__builtin_ia32_pfsub", + "llvm.x86.3dnow.pfsubr" => "__builtin_ia32_pfsubr", + "llvm.x86.3dnow.pi2fd" => "__builtin_ia32_pi2fd", + "llvm.x86.3dnow.pmulhrw" => "__builtin_ia32_pmulhrw", + "llvm.x86.3dnowa.pf2iw" => "__builtin_ia32_pf2iw", + "llvm.x86.3dnowa.pfnacc" => "__builtin_ia32_pfnacc", + "llvm.x86.3dnowa.pfpnacc" => "__builtin_ia32_pfpnacc", + "llvm.x86.3dnowa.pi2fw" => "__builtin_ia32_pi2fw", + "llvm.x86.addcarry.u32" => "__builtin_ia32_addcarry_u32", + "llvm.x86.addcarry.u64" => "__builtin_ia32_addcarry_u64", + "llvm.x86.addcarryx.u32" => "__builtin_ia32_addcarryx_u32", + "llvm.x86.addcarryx.u64" => "__builtin_ia32_addcarryx_u64", + "llvm.x86.aesni.aesdec" => "__builtin_ia32_aesdec128", + "llvm.x86.aesni.aesdec.256" => "__builtin_ia32_aesdec256", + "llvm.x86.aesni.aesdec.512" => "__builtin_ia32_aesdec512", + "llvm.x86.aesni.aesdeclast" => "__builtin_ia32_aesdeclast128", + "llvm.x86.aesni.aesdeclast.256" => "__builtin_ia32_aesdeclast256", + "llvm.x86.aesni.aesdeclast.512" => "__builtin_ia32_aesdeclast512", + "llvm.x86.aesni.aesenc" => "__builtin_ia32_aesenc128", + "llvm.x86.aesni.aesenc.256" => "__builtin_ia32_aesenc256", + "llvm.x86.aesni.aesenc.512" => "__builtin_ia32_aesenc512", + "llvm.x86.aesni.aesenclast" => "__builtin_ia32_aesenclast128", + "llvm.x86.aesni.aesenclast.256" => "__builtin_ia32_aesenclast256", + "llvm.x86.aesni.aesenclast.512" => "__builtin_ia32_aesenclast512", + "llvm.x86.aesni.aesimc" => "__builtin_ia32_aesimc128", + "llvm.x86.aesni.aeskeygenassist" => "__builtin_ia32_aeskeygenassist128", + "llvm.x86.avx.addsub.pd.256" => "__builtin_ia32_addsubpd256", + "llvm.x86.avx.addsub.ps.256" => "__builtin_ia32_addsubps256", + "llvm.x86.avx.blend.pd.256" => "__builtin_ia32_blendpd256", + "llvm.x86.avx.blend.ps.256" => "__builtin_ia32_blendps256", + "llvm.x86.avx.blendv.pd.256" => "__builtin_ia32_blendvpd256", + "llvm.x86.avx.blendv.ps.256" => "__builtin_ia32_blendvps256", + "llvm.x86.avx.cmp.pd.256" => "__builtin_ia32_cmppd256", + "llvm.x86.avx.cmp.ps.256" => "__builtin_ia32_cmpps256", + "llvm.x86.avx.cvt.pd2.ps.256" => "__builtin_ia32_cvtpd2ps256", + "llvm.x86.avx.cvt.pd2dq.256" => "__builtin_ia32_cvtpd2dq256", + "llvm.x86.avx.cvt.ps2.pd.256" => "__builtin_ia32_cvtps2pd256", + "llvm.x86.avx.cvt.ps2dq.256" => "__builtin_ia32_cvtps2dq256", + "llvm.x86.avx.cvtdq2.pd.256" => "__builtin_ia32_cvtdq2pd256", + "llvm.x86.avx.cvtdq2.ps.256" => "__builtin_ia32_cvtdq2ps256", + "llvm.x86.avx.cvtt.pd2dq.256" => "__builtin_ia32_cvttpd2dq256", + "llvm.x86.avx.cvtt.ps2dq.256" => "__builtin_ia32_cvttps2dq256", + "llvm.x86.avx.dp.ps.256" => "__builtin_ia32_dpps256", + "llvm.x86.avx.hadd.pd.256" => "__builtin_ia32_haddpd256", + "llvm.x86.avx.hadd.ps.256" => "__builtin_ia32_haddps256", + "llvm.x86.avx.hsub.pd.256" => "__builtin_ia32_hsubpd256", + "llvm.x86.avx.hsub.ps.256" => "__builtin_ia32_hsubps256", + "llvm.x86.avx.ldu.dq.256" => "__builtin_ia32_lddqu256", + "llvm.x86.avx.maskload.pd" => "__builtin_ia32_maskloadpd", + "llvm.x86.avx.maskload.pd.256" => "__builtin_ia32_maskloadpd256", + "llvm.x86.avx.maskload.ps" => "__builtin_ia32_maskloadps", + "llvm.x86.avx.maskload.ps.256" => "__builtin_ia32_maskloadps256", + "llvm.x86.avx.maskstore.pd" => "__builtin_ia32_maskstorepd", + "llvm.x86.avx.maskstore.pd.256" => "__builtin_ia32_maskstorepd256", + "llvm.x86.avx.maskstore.ps" => "__builtin_ia32_maskstoreps", + "llvm.x86.avx.maskstore.ps.256" => "__builtin_ia32_maskstoreps256", + "llvm.x86.avx.max.pd.256" => "__builtin_ia32_maxpd256", + "llvm.x86.avx.max.ps.256" => "__builtin_ia32_maxps256", + "llvm.x86.avx.min.pd.256" => "__builtin_ia32_minpd256", + "llvm.x86.avx.min.ps.256" => "__builtin_ia32_minps256", + "llvm.x86.avx.movmsk.pd.256" => "__builtin_ia32_movmskpd256", + "llvm.x86.avx.movmsk.ps.256" => "__builtin_ia32_movmskps256", + "llvm.x86.avx.ptestc.256" => "__builtin_ia32_ptestc256", + "llvm.x86.avx.ptestnzc.256" => "__builtin_ia32_ptestnzc256", + "llvm.x86.avx.ptestz.256" => "__builtin_ia32_ptestz256", + "llvm.x86.avx.rcp.ps.256" => "__builtin_ia32_rcpps256", + "llvm.x86.avx.round.pd.256" => "__builtin_ia32_roundpd256", + "llvm.x86.avx.round.ps.256" => "__builtin_ia32_roundps256", + "llvm.x86.avx.rsqrt.ps.256" => "__builtin_ia32_rsqrtps256", + "llvm.x86.avx.sqrt.pd.256" => "__builtin_ia32_sqrtpd256", + "llvm.x86.avx.sqrt.ps.256" => "__builtin_ia32_sqrtps256", + "llvm.x86.avx.storeu.dq.256" => "__builtin_ia32_storedqu256", + "llvm.x86.avx.storeu.pd.256" => "__builtin_ia32_storeupd256", + "llvm.x86.avx.storeu.ps.256" => "__builtin_ia32_storeups256", + "llvm.x86.avx.vbroadcastf128.pd.256" => "__builtin_ia32_vbroadcastf128_pd256", + "llvm.x86.avx.vbroadcastf128.ps.256" => "__builtin_ia32_vbroadcastf128_ps256", + "llvm.x86.avx.vextractf128.pd.256" => "__builtin_ia32_vextractf128_pd256", + "llvm.x86.avx.vextractf128.ps.256" => "__builtin_ia32_vextractf128_ps256", + "llvm.x86.avx.vextractf128.si.256" => "__builtin_ia32_vextractf128_si256", + "llvm.x86.avx.vinsertf128.pd.256" => "__builtin_ia32_vinsertf128_pd256", + "llvm.x86.avx.vinsertf128.ps.256" => "__builtin_ia32_vinsertf128_ps256", + "llvm.x86.avx.vinsertf128.si.256" => "__builtin_ia32_vinsertf128_si256", + "llvm.x86.avx.vperm2f128.pd.256" => "__builtin_ia32_vperm2f128_pd256", + "llvm.x86.avx.vperm2f128.ps.256" => "__builtin_ia32_vperm2f128_ps256", + "llvm.x86.avx.vperm2f128.si.256" => "__builtin_ia32_vperm2f128_si256", + "llvm.x86.avx.vpermilvar.pd" => "__builtin_ia32_vpermilvarpd", + "llvm.x86.avx.vpermilvar.pd.256" => "__builtin_ia32_vpermilvarpd256", + "llvm.x86.avx.vpermilvar.ps" => "__builtin_ia32_vpermilvarps", + "llvm.x86.avx.vpermilvar.ps.256" => "__builtin_ia32_vpermilvarps256", + "llvm.x86.avx.vtestc.pd" => "__builtin_ia32_vtestcpd", + "llvm.x86.avx.vtestc.pd.256" => "__builtin_ia32_vtestcpd256", + "llvm.x86.avx.vtestc.ps" => "__builtin_ia32_vtestcps", + "llvm.x86.avx.vtestc.ps.256" => "__builtin_ia32_vtestcps256", + "llvm.x86.avx.vtestnzc.pd" => "__builtin_ia32_vtestnzcpd", + "llvm.x86.avx.vtestnzc.pd.256" => "__builtin_ia32_vtestnzcpd256", + "llvm.x86.avx.vtestnzc.ps" => "__builtin_ia32_vtestnzcps", + "llvm.x86.avx.vtestnzc.ps.256" => "__builtin_ia32_vtestnzcps256", + "llvm.x86.avx.vtestz.pd" => "__builtin_ia32_vtestzpd", + "llvm.x86.avx.vtestz.pd.256" => "__builtin_ia32_vtestzpd256", + "llvm.x86.avx.vtestz.ps" => "__builtin_ia32_vtestzps", + "llvm.x86.avx.vtestz.ps.256" => "__builtin_ia32_vtestzps256", + "llvm.x86.avx.vzeroall" => "__builtin_ia32_vzeroall", + "llvm.x86.avx.vzeroupper" => "__builtin_ia32_vzeroupper", + "llvm.x86.avx2.gather.d.d" => "__builtin_ia32_gatherd_d", + "llvm.x86.avx2.gather.d.d.256" => "__builtin_ia32_gatherd_d256", + "llvm.x86.avx2.gather.d.pd" => "__builtin_ia32_gatherd_pd", + "llvm.x86.avx2.gather.d.pd.256" => "__builtin_ia32_gatherd_pd256", + "llvm.x86.avx2.gather.d.ps" => "__builtin_ia32_gatherd_ps", + "llvm.x86.avx2.gather.d.ps.256" => "__builtin_ia32_gatherd_ps256", + "llvm.x86.avx2.gather.d.q" => "__builtin_ia32_gatherd_q", + "llvm.x86.avx2.gather.d.q.256" => "__builtin_ia32_gatherd_q256", + "llvm.x86.avx2.gather.q.d" => "__builtin_ia32_gatherq_d", + "llvm.x86.avx2.gather.q.d.256" => "__builtin_ia32_gatherq_d256", + "llvm.x86.avx2.gather.q.pd" => "__builtin_ia32_gatherq_pd", + "llvm.x86.avx2.gather.q.pd.256" => "__builtin_ia32_gatherq_pd256", + "llvm.x86.avx2.gather.q.ps" => "__builtin_ia32_gatherq_ps", + "llvm.x86.avx2.gather.q.ps.256" => "__builtin_ia32_gatherq_ps256", + "llvm.x86.avx2.gather.q.q" => "__builtin_ia32_gatherq_q", + "llvm.x86.avx2.gather.q.q.256" => "__builtin_ia32_gatherq_q256", + "llvm.x86.avx2.maskload.d" => "__builtin_ia32_maskloadd", + "llvm.x86.avx2.maskload.d.256" => "__builtin_ia32_maskloadd256", + "llvm.x86.avx2.maskload.q" => "__builtin_ia32_maskloadq", + "llvm.x86.avx2.maskload.q.256" => "__builtin_ia32_maskloadq256", + "llvm.x86.avx2.maskstore.d" => "__builtin_ia32_maskstored", + "llvm.x86.avx2.maskstore.d.256" => "__builtin_ia32_maskstored256", + "llvm.x86.avx2.maskstore.q" => "__builtin_ia32_maskstoreq", + "llvm.x86.avx2.maskstore.q.256" => "__builtin_ia32_maskstoreq256", + "llvm.x86.avx2.movntdqa" => "__builtin_ia32_movntdqa256", + "llvm.x86.avx2.mpsadbw" => "__builtin_ia32_mpsadbw256", + "llvm.x86.avx2.pabs.b" => "__builtin_ia32_pabsb256", + "llvm.x86.avx2.pabs.d" => "__builtin_ia32_pabsd256", + "llvm.x86.avx2.pabs.w" => "__builtin_ia32_pabsw256", + "llvm.x86.avx2.packssdw" => "__builtin_ia32_packssdw256", + "llvm.x86.avx2.packsswb" => "__builtin_ia32_packsswb256", + "llvm.x86.avx2.packusdw" => "__builtin_ia32_packusdw256", + "llvm.x86.avx2.packuswb" => "__builtin_ia32_packuswb256", + "llvm.x86.avx2.padds.b" => "__builtin_ia32_paddsb256", + "llvm.x86.avx2.padds.w" => "__builtin_ia32_paddsw256", + "llvm.x86.avx2.paddus.b" => "__builtin_ia32_paddusb256", + "llvm.x86.avx2.paddus.w" => "__builtin_ia32_paddusw256", + "llvm.x86.avx2.pavg.b" => "__builtin_ia32_pavgb256", + "llvm.x86.avx2.pavg.w" => "__builtin_ia32_pavgw256", + "llvm.x86.avx2.pblendd.128" => "__builtin_ia32_pblendd128", + "llvm.x86.avx2.pblendd.256" => "__builtin_ia32_pblendd256", + "llvm.x86.avx2.pblendvb" => "__builtin_ia32_pblendvb256", + "llvm.x86.avx2.pblendw" => "__builtin_ia32_pblendw256", + "llvm.x86.avx2.pbroadcastb.128" => "__builtin_ia32_pbroadcastb128", + "llvm.x86.avx2.pbroadcastb.256" => "__builtin_ia32_pbroadcastb256", + "llvm.x86.avx2.pbroadcastd.128" => "__builtin_ia32_pbroadcastd128", + "llvm.x86.avx2.pbroadcastd.256" => "__builtin_ia32_pbroadcastd256", + "llvm.x86.avx2.pbroadcastq.128" => "__builtin_ia32_pbroadcastq128", + "llvm.x86.avx2.pbroadcastq.256" => "__builtin_ia32_pbroadcastq256", + "llvm.x86.avx2.pbroadcastw.128" => "__builtin_ia32_pbroadcastw128", + "llvm.x86.avx2.pbroadcastw.256" => "__builtin_ia32_pbroadcastw256", + "llvm.x86.avx2.permd" => "__builtin_ia32_permvarsi256", + "llvm.x86.avx2.permps" => "__builtin_ia32_permvarsf256", + "llvm.x86.avx2.phadd.d" => "__builtin_ia32_phaddd256", + "llvm.x86.avx2.phadd.sw" => "__builtin_ia32_phaddsw256", + "llvm.x86.avx2.phadd.w" => "__builtin_ia32_phaddw256", + "llvm.x86.avx2.phsub.d" => "__builtin_ia32_phsubd256", + "llvm.x86.avx2.phsub.sw" => "__builtin_ia32_phsubsw256", + "llvm.x86.avx2.phsub.w" => "__builtin_ia32_phsubw256", + "llvm.x86.avx2.pmadd.ub.sw" => "__builtin_ia32_pmaddubsw256", + "llvm.x86.avx2.pmadd.wd" => "__builtin_ia32_pmaddwd256", + "llvm.x86.avx2.pmaxs.b" => "__builtin_ia32_pmaxsb256", + "llvm.x86.avx2.pmaxs.d" => "__builtin_ia32_pmaxsd256", + "llvm.x86.avx2.pmaxs.w" => "__builtin_ia32_pmaxsw256", + "llvm.x86.avx2.pmaxu.b" => "__builtin_ia32_pmaxub256", + "llvm.x86.avx2.pmaxu.d" => "__builtin_ia32_pmaxud256", + "llvm.x86.avx2.pmaxu.w" => "__builtin_ia32_pmaxuw256", + "llvm.x86.avx2.pmins.b" => "__builtin_ia32_pminsb256", + "llvm.x86.avx2.pmins.d" => "__builtin_ia32_pminsd256", + "llvm.x86.avx2.pmins.w" => "__builtin_ia32_pminsw256", + "llvm.x86.avx2.pminu.b" => "__builtin_ia32_pminub256", + "llvm.x86.avx2.pminu.d" => "__builtin_ia32_pminud256", + "llvm.x86.avx2.pminu.w" => "__builtin_ia32_pminuw256", + "llvm.x86.avx2.pmovmskb" => "__builtin_ia32_pmovmskb256", + "llvm.x86.avx2.pmovsxbd" => "__builtin_ia32_pmovsxbd256", + "llvm.x86.avx2.pmovsxbq" => "__builtin_ia32_pmovsxbq256", + "llvm.x86.avx2.pmovsxbw" => "__builtin_ia32_pmovsxbw256", + "llvm.x86.avx2.pmovsxdq" => "__builtin_ia32_pmovsxdq256", + "llvm.x86.avx2.pmovsxwd" => "__builtin_ia32_pmovsxwd256", + "llvm.x86.avx2.pmovsxwq" => "__builtin_ia32_pmovsxwq256", + "llvm.x86.avx2.pmovzxbd" => "__builtin_ia32_pmovzxbd256", + "llvm.x86.avx2.pmovzxbq" => "__builtin_ia32_pmovzxbq256", + "llvm.x86.avx2.pmovzxbw" => "__builtin_ia32_pmovzxbw256", + "llvm.x86.avx2.pmovzxdq" => "__builtin_ia32_pmovzxdq256", + "llvm.x86.avx2.pmovzxwd" => "__builtin_ia32_pmovzxwd256", + "llvm.x86.avx2.pmovzxwq" => "__builtin_ia32_pmovzxwq256", + "llvm.x86.avx2.pmul.dq" => "__builtin_ia32_pmuldq256", + "llvm.x86.avx2.pmul.hr.sw" => "__builtin_ia32_pmulhrsw256", + "llvm.x86.avx2.pmulh.w" => "__builtin_ia32_pmulhw256", + "llvm.x86.avx2.pmulhu.w" => "__builtin_ia32_pmulhuw256", + "llvm.x86.avx2.pmulu.dq" => "__builtin_ia32_pmuludq256", + "llvm.x86.avx2.psad.bw" => "__builtin_ia32_psadbw256", + "llvm.x86.avx2.pshuf.b" => "__builtin_ia32_pshufb256", + "llvm.x86.avx2.psign.b" => "__builtin_ia32_psignb256", + "llvm.x86.avx2.psign.d" => "__builtin_ia32_psignd256", + "llvm.x86.avx2.psign.w" => "__builtin_ia32_psignw256", + "llvm.x86.avx2.psll.d" => "__builtin_ia32_pslld256", + "llvm.x86.avx2.psll.dq" => "__builtin_ia32_pslldqi256", + "llvm.x86.avx2.psll.dq.bs" => "__builtin_ia32_pslldqi256_byteshift", + "llvm.x86.avx2.psll.q" => "__builtin_ia32_psllq256", + "llvm.x86.avx2.psll.w" => "__builtin_ia32_psllw256", + "llvm.x86.avx2.pslli.d" => "__builtin_ia32_pslldi256", + "llvm.x86.avx2.pslli.q" => "__builtin_ia32_psllqi256", + "llvm.x86.avx2.pslli.w" => "__builtin_ia32_psllwi256", + "llvm.x86.avx2.psllv.d" => "__builtin_ia32_psllv4si", + "llvm.x86.avx2.psllv.d.256" => "__builtin_ia32_psllv8si", + "llvm.x86.avx2.psllv.q" => "__builtin_ia32_psllv2di", + "llvm.x86.avx2.psllv.q.256" => "__builtin_ia32_psllv4di", + "llvm.x86.avx2.psra.d" => "__builtin_ia32_psrad256", + "llvm.x86.avx2.psra.w" => "__builtin_ia32_psraw256", + "llvm.x86.avx2.psrai.d" => "__builtin_ia32_psradi256", + "llvm.x86.avx2.psrai.w" => "__builtin_ia32_psrawi256", + "llvm.x86.avx2.psrav.d" => "__builtin_ia32_psrav4si", + "llvm.x86.avx2.psrav.d.256" => "__builtin_ia32_psrav8si", + "llvm.x86.avx2.psrl.d" => "__builtin_ia32_psrld256", + "llvm.x86.avx2.psrl.dq" => "__builtin_ia32_psrldqi256", + "llvm.x86.avx2.psrl.dq.bs" => "__builtin_ia32_psrldqi256_byteshift", + "llvm.x86.avx2.psrl.q" => "__builtin_ia32_psrlq256", + "llvm.x86.avx2.psrl.w" => "__builtin_ia32_psrlw256", + "llvm.x86.avx2.psrli.d" => "__builtin_ia32_psrldi256", + "llvm.x86.avx2.psrli.q" => "__builtin_ia32_psrlqi256", + "llvm.x86.avx2.psrli.w" => "__builtin_ia32_psrlwi256", + "llvm.x86.avx2.psrlv.d" => "__builtin_ia32_psrlv4si", + "llvm.x86.avx2.psrlv.d.256" => "__builtin_ia32_psrlv8si", + "llvm.x86.avx2.psrlv.q" => "__builtin_ia32_psrlv2di", + "llvm.x86.avx2.psrlv.q.256" => "__builtin_ia32_psrlv4di", + "llvm.x86.avx2.psubs.b" => "__builtin_ia32_psubsb256", + "llvm.x86.avx2.psubs.w" => "__builtin_ia32_psubsw256", + "llvm.x86.avx2.psubus.b" => "__builtin_ia32_psubusb256", + "llvm.x86.avx2.psubus.w" => "__builtin_ia32_psubusw256", + "llvm.x86.avx2.vbroadcast.sd.pd.256" => "__builtin_ia32_vbroadcastsd_pd256", + "llvm.x86.avx2.vbroadcast.ss.ps" => "__builtin_ia32_vbroadcastss_ps", + "llvm.x86.avx2.vbroadcast.ss.ps.256" => "__builtin_ia32_vbroadcastss_ps256", + "llvm.x86.avx2.vextracti128" => "__builtin_ia32_extract128i256", + "llvm.x86.avx2.vinserti128" => "__builtin_ia32_insert128i256", + "llvm.x86.avx2.vperm2i128" => "__builtin_ia32_permti256", + "llvm.x86.avx512.add.pd.512" => "__builtin_ia32_addpd512", + "llvm.x86.avx512.add.ps.512" => "__builtin_ia32_addps512", + "llvm.x86.avx512.broadcastmb.128" => "__builtin_ia32_broadcastmb128", + "llvm.x86.avx512.broadcastmb.256" => "__builtin_ia32_broadcastmb256", + "llvm.x86.avx512.broadcastmb.512" => "__builtin_ia32_broadcastmb512", + "llvm.x86.avx512.broadcastmw.128" => "__builtin_ia32_broadcastmw128", + "llvm.x86.avx512.broadcastmw.256" => "__builtin_ia32_broadcastmw256", + "llvm.x86.avx512.broadcastmw.512" => "__builtin_ia32_broadcastmw512", + "llvm.x86.avx512.conflict.d.128" => "__builtin_ia32_vpconflictsi_128", + "llvm.x86.avx512.conflict.d.256" => "__builtin_ia32_vpconflictsi_256", + "llvm.x86.avx512.conflict.d.512" => "__builtin_ia32_vpconflictsi_512", + "llvm.x86.avx512.conflict.q.128" => "__builtin_ia32_vpconflictdi_128", + "llvm.x86.avx512.conflict.q.256" => "__builtin_ia32_vpconflictdi_256", + "llvm.x86.avx512.conflict.q.512" => "__builtin_ia32_vpconflictdi_512", + "llvm.x86.avx512.cvtb2mask.128" => "__builtin_ia32_cvtb2mask128", + "llvm.x86.avx512.cvtb2mask.256" => "__builtin_ia32_cvtb2mask256", + "llvm.x86.avx512.cvtb2mask.512" => "__builtin_ia32_cvtb2mask512", + "llvm.x86.avx512.cvtd2mask.128" => "__builtin_ia32_cvtd2mask128", + "llvm.x86.avx512.cvtd2mask.256" => "__builtin_ia32_cvtd2mask256", + "llvm.x86.avx512.cvtd2mask.512" => "__builtin_ia32_cvtd2mask512", + "llvm.x86.avx512.cvtmask2b.128" => "__builtin_ia32_cvtmask2b128", + "llvm.x86.avx512.cvtmask2b.256" => "__builtin_ia32_cvtmask2b256", + "llvm.x86.avx512.cvtmask2b.512" => "__builtin_ia32_cvtmask2b512", + "llvm.x86.avx512.cvtmask2d.128" => "__builtin_ia32_cvtmask2d128", + "llvm.x86.avx512.cvtmask2d.256" => "__builtin_ia32_cvtmask2d256", + "llvm.x86.avx512.cvtmask2d.512" => "__builtin_ia32_cvtmask2d512", + "llvm.x86.avx512.cvtmask2q.128" => "__builtin_ia32_cvtmask2q128", + "llvm.x86.avx512.cvtmask2q.256" => "__builtin_ia32_cvtmask2q256", + "llvm.x86.avx512.cvtmask2q.512" => "__builtin_ia32_cvtmask2q512", + "llvm.x86.avx512.cvtmask2w.128" => "__builtin_ia32_cvtmask2w128", + "llvm.x86.avx512.cvtmask2w.256" => "__builtin_ia32_cvtmask2w256", + "llvm.x86.avx512.cvtmask2w.512" => "__builtin_ia32_cvtmask2w512", + "llvm.x86.avx512.cvtq2mask.128" => "__builtin_ia32_cvtq2mask128", + "llvm.x86.avx512.cvtq2mask.256" => "__builtin_ia32_cvtq2mask256", + "llvm.x86.avx512.cvtq2mask.512" => "__builtin_ia32_cvtq2mask512", + "llvm.x86.avx512.cvtsd2usi" => "__builtin_ia32_cvtsd2usi", + "llvm.x86.avx512.cvtsd2usi64" => "__builtin_ia32_cvtsd2usi64", + "llvm.x86.avx512.cvtsi2sd32" => "__builtin_ia32_cvtsi2sd32", + "llvm.x86.avx512.cvtsi2sd64" => "__builtin_ia32_cvtsi2sd64", + "llvm.x86.avx512.cvtsi2ss32" => "__builtin_ia32_cvtsi2ss32", + "llvm.x86.avx512.cvtsi2ss64" => "__builtin_ia32_cvtsi2ss64", + "llvm.x86.avx512.cvtss2usi" => "__builtin_ia32_cvtss2usi", + "llvm.x86.avx512.cvtss2usi64" => "__builtin_ia32_cvtss2usi64", + "llvm.x86.avx512.cvttsd2si" => "__builtin_ia32_vcvttsd2si32", + "llvm.x86.avx512.cvttsd2si64" => "__builtin_ia32_vcvttsd2si64", + "llvm.x86.avx512.cvttsd2usi" => "__builtin_ia32_vcvttsd2usi32", + // [DUPLICATE]: "llvm.x86.avx512.cvttsd2usi" => "__builtin_ia32_cvttsd2usi", + "llvm.x86.avx512.cvttsd2usi64" => "__builtin_ia32_vcvttsd2usi64", + // [DUPLICATE]: "llvm.x86.avx512.cvttsd2usi64" => "__builtin_ia32_cvttsd2usi64", + "llvm.x86.avx512.cvttss2si" => "__builtin_ia32_vcvttss2si32", + "llvm.x86.avx512.cvttss2si64" => "__builtin_ia32_vcvttss2si64", + "llvm.x86.avx512.cvttss2usi" => "__builtin_ia32_vcvttss2usi32", + // [DUPLICATE]: "llvm.x86.avx512.cvttss2usi" => "__builtin_ia32_cvttss2usi", + "llvm.x86.avx512.cvttss2usi64" => "__builtin_ia32_vcvttss2usi64", + // [DUPLICATE]: "llvm.x86.avx512.cvttss2usi64" => "__builtin_ia32_cvttss2usi64", + "llvm.x86.avx512.cvtusi2sd" => "__builtin_ia32_cvtusi2sd", + // [DUPLICATE]: "llvm.x86.avx512.cvtusi2sd" => "__builtin_ia32_cvtusi2sd32", + "llvm.x86.avx512.cvtusi2ss" => "__builtin_ia32_cvtusi2ss32", + // [DUPLICATE]: "llvm.x86.avx512.cvtusi2ss" => "__builtin_ia32_cvtusi2ss", + "llvm.x86.avx512.cvtusi642sd" => "__builtin_ia32_cvtusi2sd64", + // [DUPLICATE]: "llvm.x86.avx512.cvtusi642sd" => "__builtin_ia32_cvtusi642sd", + "llvm.x86.avx512.cvtusi642ss" => "__builtin_ia32_cvtusi2ss64", + // [DUPLICATE]: "llvm.x86.avx512.cvtusi642ss" => "__builtin_ia32_cvtusi642ss", + "llvm.x86.avx512.cvtw2mask.128" => "__builtin_ia32_cvtw2mask128", + "llvm.x86.avx512.cvtw2mask.256" => "__builtin_ia32_cvtw2mask256", + "llvm.x86.avx512.cvtw2mask.512" => "__builtin_ia32_cvtw2mask512", + "llvm.x86.avx512.dbpsadbw.128" => "__builtin_ia32_dbpsadbw128", + "llvm.x86.avx512.dbpsadbw.256" => "__builtin_ia32_dbpsadbw256", + "llvm.x86.avx512.dbpsadbw.512" => "__builtin_ia32_dbpsadbw512", + "llvm.x86.avx512.div.pd.512" => "__builtin_ia32_divpd512", + "llvm.x86.avx512.div.ps.512" => "__builtin_ia32_divps512", + "llvm.x86.avx512.exp2.pd" => "__builtin_ia32_exp2pd_mask", + "llvm.x86.avx512.exp2.ps" => "__builtin_ia32_exp2ps_mask", + "llvm.x86.avx512.gather.dpd.512" => "__builtin_ia32_gathersiv8df", + "llvm.x86.avx512.gather.dpi.512" => "__builtin_ia32_gathersiv16si", + "llvm.x86.avx512.gather.dpq.512" => "__builtin_ia32_gathersiv8di", + "llvm.x86.avx512.gather.dps.512" => "__builtin_ia32_gathersiv16sf", + "llvm.x86.avx512.gather.qpd.512" => "__builtin_ia32_gatherdiv8df", + "llvm.x86.avx512.gather.qpi.512" => "__builtin_ia32_gatherdiv16si", + "llvm.x86.avx512.gather.qpq.512" => "__builtin_ia32_gatherdiv8di", + "llvm.x86.avx512.gather.qps.512" => "__builtin_ia32_gatherdiv16sf", + "llvm.x86.avx512.gather3div2.df" => "__builtin_ia32_gather3div2df", + "llvm.x86.avx512.gather3div2.di" => "__builtin_ia32_gather3div2di", + "llvm.x86.avx512.gather3div4.df" => "__builtin_ia32_gather3div4df", + "llvm.x86.avx512.gather3div4.di" => "__builtin_ia32_gather3div4di", + "llvm.x86.avx512.gather3div4.sf" => "__builtin_ia32_gather3div4sf", + "llvm.x86.avx512.gather3div4.si" => "__builtin_ia32_gather3div4si", + "llvm.x86.avx512.gather3div8.sf" => "__builtin_ia32_gather3div8sf", + "llvm.x86.avx512.gather3div8.si" => "__builtin_ia32_gather3div8si", + "llvm.x86.avx512.gather3siv2.df" => "__builtin_ia32_gather3siv2df", + "llvm.x86.avx512.gather3siv2.di" => "__builtin_ia32_gather3siv2di", + "llvm.x86.avx512.gather3siv4.df" => "__builtin_ia32_gather3siv4df", + "llvm.x86.avx512.gather3siv4.di" => "__builtin_ia32_gather3siv4di", + "llvm.x86.avx512.gather3siv4.sf" => "__builtin_ia32_gather3siv4sf", + "llvm.x86.avx512.gather3siv4.si" => "__builtin_ia32_gather3siv4si", + "llvm.x86.avx512.gather3siv8.sf" => "__builtin_ia32_gather3siv8sf", + "llvm.x86.avx512.gather3siv8.si" => "__builtin_ia32_gather3siv8si", + "llvm.x86.avx512.gatherpf.dpd.512" => "__builtin_ia32_gatherpfdpd", + "llvm.x86.avx512.gatherpf.dps.512" => "__builtin_ia32_gatherpfdps", + "llvm.x86.avx512.gatherpf.qpd.512" => "__builtin_ia32_gatherpfqpd", + "llvm.x86.avx512.gatherpf.qps.512" => "__builtin_ia32_gatherpfqps", + "llvm.x86.avx512.kand.w" => "__builtin_ia32_kandhi", + "llvm.x86.avx512.kandn.w" => "__builtin_ia32_kandnhi", + "llvm.x86.avx512.knot.w" => "__builtin_ia32_knothi", + "llvm.x86.avx512.kor.w" => "__builtin_ia32_korhi", + "llvm.x86.avx512.kortestc.w" => "__builtin_ia32_kortestchi", + "llvm.x86.avx512.kortestz.w" => "__builtin_ia32_kortestzhi", + "llvm.x86.avx512.kunpck.bw" => "__builtin_ia32_kunpckhi", + "llvm.x86.avx512.kunpck.dq" => "__builtin_ia32_kunpckdi", + "llvm.x86.avx512.kunpck.wd" => "__builtin_ia32_kunpcksi", + "llvm.x86.avx512.kxnor.w" => "__builtin_ia32_kxnorhi", + "llvm.x86.avx512.kxor.w" => "__builtin_ia32_kxorhi", + "llvm.x86.avx512.mask.add.pd.128" => "__builtin_ia32_addpd128_mask", + "llvm.x86.avx512.mask.add.pd.256" => "__builtin_ia32_addpd256_mask", + "llvm.x86.avx512.mask.add.pd.512" => "__builtin_ia32_addpd512_mask", + "llvm.x86.avx512.mask.add.ps.128" => "__builtin_ia32_addps128_mask", + "llvm.x86.avx512.mask.add.ps.256" => "__builtin_ia32_addps256_mask", + "llvm.x86.avx512.mask.add.ps.512" => "__builtin_ia32_addps512_mask", + "llvm.x86.avx512.mask.add.sd.round" => "__builtin_ia32_addsd_round_mask", + "llvm.x86.avx512.mask.add.ss.round" => "__builtin_ia32_addss_round_mask", + "llvm.x86.avx512.mask.and.pd.128" => "__builtin_ia32_andpd128_mask", + "llvm.x86.avx512.mask.and.pd.256" => "__builtin_ia32_andpd256_mask", + "llvm.x86.avx512.mask.and.pd.512" => "__builtin_ia32_andpd512_mask", + "llvm.x86.avx512.mask.and.ps.128" => "__builtin_ia32_andps128_mask", + "llvm.x86.avx512.mask.and.ps.256" => "__builtin_ia32_andps256_mask", + "llvm.x86.avx512.mask.and.ps.512" => "__builtin_ia32_andps512_mask", + "llvm.x86.avx512.mask.andn.pd.128" => "__builtin_ia32_andnpd128_mask", + "llvm.x86.avx512.mask.andn.pd.256" => "__builtin_ia32_andnpd256_mask", + "llvm.x86.avx512.mask.andn.pd.512" => "__builtin_ia32_andnpd512_mask", + "llvm.x86.avx512.mask.andn.ps.128" => "__builtin_ia32_andnps128_mask", + "llvm.x86.avx512.mask.andn.ps.256" => "__builtin_ia32_andnps256_mask", + "llvm.x86.avx512.mask.andn.ps.512" => "__builtin_ia32_andnps512_mask", + "llvm.x86.avx512.mask.blend.d.512" => "__builtin_ia32_blendmd_512_mask", + "llvm.x86.avx512.mask.blend.pd.512" => "__builtin_ia32_blendmpd_512_mask", + "llvm.x86.avx512.mask.blend.ps.512" => "__builtin_ia32_blendmps_512_mask", + "llvm.x86.avx512.mask.blend.q.512" => "__builtin_ia32_blendmq_512_mask", + "llvm.x86.avx512.mask.broadcastf32x2.256" => "__builtin_ia32_broadcastf32x2_256_mask", + "llvm.x86.avx512.mask.broadcastf32x2.512" => "__builtin_ia32_broadcastf32x2_512_mask", + "llvm.x86.avx512.mask.broadcastf32x4.256" => "__builtin_ia32_broadcastf32x4_256_mask", + "llvm.x86.avx512.mask.broadcastf32x4.512" => "__builtin_ia32_broadcastf32x4_512", + "llvm.x86.avx512.mask.broadcastf32x8.512" => "__builtin_ia32_broadcastf32x8_512_mask", + "llvm.x86.avx512.mask.broadcastf64x2.256" => "__builtin_ia32_broadcastf64x2_256_mask", + "llvm.x86.avx512.mask.broadcastf64x2.512" => "__builtin_ia32_broadcastf64x2_512_mask", + "llvm.x86.avx512.mask.broadcastf64x4.512" => "__builtin_ia32_broadcastf64x4_512", + "llvm.x86.avx512.mask.broadcasti32x2.128" => "__builtin_ia32_broadcasti32x2_128_mask", + "llvm.x86.avx512.mask.broadcasti32x2.256" => "__builtin_ia32_broadcasti32x2_256_mask", + "llvm.x86.avx512.mask.broadcasti32x2.512" => "__builtin_ia32_broadcasti32x2_512_mask", + "llvm.x86.avx512.mask.broadcasti32x4.256" => "__builtin_ia32_broadcasti32x4_256_mask", + "llvm.x86.avx512.mask.broadcasti32x4.512" => "__builtin_ia32_broadcasti32x4_512", + "llvm.x86.avx512.mask.broadcasti32x8.512" => "__builtin_ia32_broadcasti32x8_512_mask", + "llvm.x86.avx512.mask.broadcasti64x2.256" => "__builtin_ia32_broadcasti64x2_256_mask", + "llvm.x86.avx512.mask.broadcasti64x2.512" => "__builtin_ia32_broadcasti64x2_512_mask", + "llvm.x86.avx512.mask.broadcasti64x4.512" => "__builtin_ia32_broadcasti64x4_512", + "llvm.x86.avx512.mask.cmp.pd.128" => "__builtin_ia32_cmppd128_mask", + "llvm.x86.avx512.mask.cmp.pd.256" => "__builtin_ia32_cmppd256_mask", + "llvm.x86.avx512.mask.cmp.pd.512" => "__builtin_ia32_cmppd512_mask", + "llvm.x86.avx512.mask.cmp.ps.128" => "__builtin_ia32_cmpps128_mask", + "llvm.x86.avx512.mask.cmp.ps.256" => "__builtin_ia32_cmpps256_mask", + "llvm.x86.avx512.mask.cmp.ps.512" => "__builtin_ia32_cmpps512_mask", + "llvm.x86.avx512.mask.cmp.sd" => "__builtin_ia32_cmpsd_mask", + "llvm.x86.avx512.mask.cmp.ss" => "__builtin_ia32_cmpss_mask", + "llvm.x86.avx512.mask.compress.d.128" => "__builtin_ia32_compresssi128_mask", + "llvm.x86.avx512.mask.compress.d.256" => "__builtin_ia32_compresssi256_mask", + "llvm.x86.avx512.mask.compress.d.512" => "__builtin_ia32_compresssi512_mask", + "llvm.x86.avx512.mask.compress.pd.128" => "__builtin_ia32_compressdf128_mask", + "llvm.x86.avx512.mask.compress.pd.256" => "__builtin_ia32_compressdf256_mask", + "llvm.x86.avx512.mask.compress.pd.512" => "__builtin_ia32_compressdf512_mask", + "llvm.x86.avx512.mask.compress.ps.128" => "__builtin_ia32_compresssf128_mask", + "llvm.x86.avx512.mask.compress.ps.256" => "__builtin_ia32_compresssf256_mask", + "llvm.x86.avx512.mask.compress.ps.512" => "__builtin_ia32_compresssf512_mask", + "llvm.x86.avx512.mask.compress.q.128" => "__builtin_ia32_compressdi128_mask", + "llvm.x86.avx512.mask.compress.q.256" => "__builtin_ia32_compressdi256_mask", + "llvm.x86.avx512.mask.compress.q.512" => "__builtin_ia32_compressdi512_mask", + "llvm.x86.avx512.mask.compress.store.d.128" => "__builtin_ia32_compressstoresi128_mask", + "llvm.x86.avx512.mask.compress.store.d.256" => "__builtin_ia32_compressstoresi256_mask", + "llvm.x86.avx512.mask.compress.store.d.512" => "__builtin_ia32_compressstoresi512_mask", + "llvm.x86.avx512.mask.compress.store.pd.128" => "__builtin_ia32_compressstoredf128_mask", + "llvm.x86.avx512.mask.compress.store.pd.256" => "__builtin_ia32_compressstoredf256_mask", + "llvm.x86.avx512.mask.compress.store.pd.512" => "__builtin_ia32_compressstoredf512_mask", + "llvm.x86.avx512.mask.compress.store.ps.128" => "__builtin_ia32_compressstoresf128_mask", + "llvm.x86.avx512.mask.compress.store.ps.256" => "__builtin_ia32_compressstoresf256_mask", + "llvm.x86.avx512.mask.compress.store.ps.512" => "__builtin_ia32_compressstoresf512_mask", + "llvm.x86.avx512.mask.compress.store.q.128" => "__builtin_ia32_compressstoredi128_mask", + "llvm.x86.avx512.mask.compress.store.q.256" => "__builtin_ia32_compressstoredi256_mask", + "llvm.x86.avx512.mask.compress.store.q.512" => "__builtin_ia32_compressstoredi512_mask", + "llvm.x86.avx512.mask.conflict.d.128" => "__builtin_ia32_vpconflictsi_128_mask", + "llvm.x86.avx512.mask.conflict.d.256" => "__builtin_ia32_vpconflictsi_256_mask", + "llvm.x86.avx512.mask.conflict.d.512" => "__builtin_ia32_vpconflictsi_512_mask", + "llvm.x86.avx512.mask.conflict.q.128" => "__builtin_ia32_vpconflictdi_128_mask", + "llvm.x86.avx512.mask.conflict.q.256" => "__builtin_ia32_vpconflictdi_256_mask", + "llvm.x86.avx512.mask.conflict.q.512" => "__builtin_ia32_vpconflictdi_512_mask", + "llvm.x86.avx512.mask.cvtdq2pd.128" => "__builtin_ia32_cvtdq2pd128_mask", + "llvm.x86.avx512.mask.cvtdq2pd.256" => "__builtin_ia32_cvtdq2pd256_mask", + "llvm.x86.avx512.mask.cvtdq2pd.512" => "__builtin_ia32_cvtdq2pd512_mask", + "llvm.x86.avx512.mask.cvtdq2ps.128" => "__builtin_ia32_cvtdq2ps128_mask", + "llvm.x86.avx512.mask.cvtdq2ps.256" => "__builtin_ia32_cvtdq2ps256_mask", + "llvm.x86.avx512.mask.cvtdq2ps.512" => "__builtin_ia32_cvtdq2ps512_mask", + "llvm.x86.avx512.mask.cvtpd2dq.128" => "__builtin_ia32_cvtpd2dq128_mask", + "llvm.x86.avx512.mask.cvtpd2dq.256" => "__builtin_ia32_cvtpd2dq256_mask", + "llvm.x86.avx512.mask.cvtpd2dq.512" => "__builtin_ia32_cvtpd2dq512_mask", + "llvm.x86.avx512.mask.cvtpd2ps" => "__builtin_ia32_cvtpd2ps_mask", + "llvm.x86.avx512.mask.cvtpd2ps.256" => "__builtin_ia32_cvtpd2ps256_mask", + "llvm.x86.avx512.mask.cvtpd2ps.512" => "__builtin_ia32_cvtpd2ps512_mask", + "llvm.x86.avx512.mask.cvtpd2qq.128" => "__builtin_ia32_cvtpd2qq128_mask", + "llvm.x86.avx512.mask.cvtpd2qq.256" => "__builtin_ia32_cvtpd2qq256_mask", + "llvm.x86.avx512.mask.cvtpd2qq.512" => "__builtin_ia32_cvtpd2qq512_mask", + "llvm.x86.avx512.mask.cvtpd2udq.128" => "__builtin_ia32_cvtpd2udq128_mask", + "llvm.x86.avx512.mask.cvtpd2udq.256" => "__builtin_ia32_cvtpd2udq256_mask", + "llvm.x86.avx512.mask.cvtpd2udq.512" => "__builtin_ia32_cvtpd2udq512_mask", + "llvm.x86.avx512.mask.cvtpd2uqq.128" => "__builtin_ia32_cvtpd2uqq128_mask", + "llvm.x86.avx512.mask.cvtpd2uqq.256" => "__builtin_ia32_cvtpd2uqq256_mask", + "llvm.x86.avx512.mask.cvtpd2uqq.512" => "__builtin_ia32_cvtpd2uqq512_mask", + "llvm.x86.avx512.mask.cvtps2dq.128" => "__builtin_ia32_cvtps2dq128_mask", + "llvm.x86.avx512.mask.cvtps2dq.256" => "__builtin_ia32_cvtps2dq256_mask", + "llvm.x86.avx512.mask.cvtps2dq.512" => "__builtin_ia32_cvtps2dq512_mask", + "llvm.x86.avx512.mask.cvtps2pd.128" => "__builtin_ia32_cvtps2pd128_mask", + "llvm.x86.avx512.mask.cvtps2pd.256" => "__builtin_ia32_cvtps2pd256_mask", + "llvm.x86.avx512.mask.cvtps2pd.512" => "__builtin_ia32_cvtps2pd512_mask", + "llvm.x86.avx512.mask.cvtps2qq.128" => "__builtin_ia32_cvtps2qq128_mask", + "llvm.x86.avx512.mask.cvtps2qq.256" => "__builtin_ia32_cvtps2qq256_mask", + "llvm.x86.avx512.mask.cvtps2qq.512" => "__builtin_ia32_cvtps2qq512_mask", + "llvm.x86.avx512.mask.cvtps2udq.128" => "__builtin_ia32_cvtps2udq128_mask", + "llvm.x86.avx512.mask.cvtps2udq.256" => "__builtin_ia32_cvtps2udq256_mask", + "llvm.x86.avx512.mask.cvtps2udq.512" => "__builtin_ia32_cvtps2udq512_mask", + "llvm.x86.avx512.mask.cvtps2uqq.128" => "__builtin_ia32_cvtps2uqq128_mask", + "llvm.x86.avx512.mask.cvtps2uqq.256" => "__builtin_ia32_cvtps2uqq256_mask", + "llvm.x86.avx512.mask.cvtps2uqq.512" => "__builtin_ia32_cvtps2uqq512_mask", + "llvm.x86.avx512.mask.cvtqq2pd.128" => "__builtin_ia32_cvtqq2pd128_mask", + "llvm.x86.avx512.mask.cvtqq2pd.256" => "__builtin_ia32_cvtqq2pd256_mask", + "llvm.x86.avx512.mask.cvtqq2pd.512" => "__builtin_ia32_cvtqq2pd512_mask", + "llvm.x86.avx512.mask.cvtqq2ps.128" => "__builtin_ia32_cvtqq2ps128_mask", + "llvm.x86.avx512.mask.cvtqq2ps.256" => "__builtin_ia32_cvtqq2ps256_mask", + "llvm.x86.avx512.mask.cvtqq2ps.512" => "__builtin_ia32_cvtqq2ps512_mask", + "llvm.x86.avx512.mask.cvtsd2ss.round" => "__builtin_ia32_cvtsd2ss_round_mask", + "llvm.x86.avx512.mask.cvtss2sd.round" => "__builtin_ia32_cvtss2sd_round_mask", + "llvm.x86.avx512.mask.cvttpd2dq.128" => "__builtin_ia32_cvttpd2dq128_mask", + "llvm.x86.avx512.mask.cvttpd2dq.256" => "__builtin_ia32_cvttpd2dq256_mask", + "llvm.x86.avx512.mask.cvttpd2dq.512" => "__builtin_ia32_cvttpd2dq512_mask", + "llvm.x86.avx512.mask.cvttpd2qq.128" => "__builtin_ia32_cvttpd2qq128_mask", + "llvm.x86.avx512.mask.cvttpd2qq.256" => "__builtin_ia32_cvttpd2qq256_mask", + "llvm.x86.avx512.mask.cvttpd2qq.512" => "__builtin_ia32_cvttpd2qq512_mask", + "llvm.x86.avx512.mask.cvttpd2udq.128" => "__builtin_ia32_cvttpd2udq128_mask", + "llvm.x86.avx512.mask.cvttpd2udq.256" => "__builtin_ia32_cvttpd2udq256_mask", + "llvm.x86.avx512.mask.cvttpd2udq.512" => "__builtin_ia32_cvttpd2udq512_mask", + "llvm.x86.avx512.mask.cvttpd2uqq.128" => "__builtin_ia32_cvttpd2uqq128_mask", + "llvm.x86.avx512.mask.cvttpd2uqq.256" => "__builtin_ia32_cvttpd2uqq256_mask", + "llvm.x86.avx512.mask.cvttpd2uqq.512" => "__builtin_ia32_cvttpd2uqq512_mask", + "llvm.x86.avx512.mask.cvttps2dq.128" => "__builtin_ia32_cvttps2dq128_mask", + "llvm.x86.avx512.mask.cvttps2dq.256" => "__builtin_ia32_cvttps2dq256_mask", + "llvm.x86.avx512.mask.cvttps2dq.512" => "__builtin_ia32_cvttps2dq512_mask", + "llvm.x86.avx512.mask.cvttps2qq.128" => "__builtin_ia32_cvttps2qq128_mask", + "llvm.x86.avx512.mask.cvttps2qq.256" => "__builtin_ia32_cvttps2qq256_mask", + "llvm.x86.avx512.mask.cvttps2qq.512" => "__builtin_ia32_cvttps2qq512_mask", + "llvm.x86.avx512.mask.cvttps2udq.128" => "__builtin_ia32_cvttps2udq128_mask", + "llvm.x86.avx512.mask.cvttps2udq.256" => "__builtin_ia32_cvttps2udq256_mask", + "llvm.x86.avx512.mask.cvttps2udq.512" => "__builtin_ia32_cvttps2udq512_mask", + "llvm.x86.avx512.mask.cvttps2uqq.128" => "__builtin_ia32_cvttps2uqq128_mask", + "llvm.x86.avx512.mask.cvttps2uqq.256" => "__builtin_ia32_cvttps2uqq256_mask", + "llvm.x86.avx512.mask.cvttps2uqq.512" => "__builtin_ia32_cvttps2uqq512_mask", + "llvm.x86.avx512.mask.cvtudq2pd.128" => "__builtin_ia32_cvtudq2pd128_mask", + "llvm.x86.avx512.mask.cvtudq2pd.256" => "__builtin_ia32_cvtudq2pd256_mask", + "llvm.x86.avx512.mask.cvtudq2pd.512" => "__builtin_ia32_cvtudq2pd512_mask", + "llvm.x86.avx512.mask.cvtudq2ps.128" => "__builtin_ia32_cvtudq2ps128_mask", + "llvm.x86.avx512.mask.cvtudq2ps.256" => "__builtin_ia32_cvtudq2ps256_mask", + "llvm.x86.avx512.mask.cvtudq2ps.512" => "__builtin_ia32_cvtudq2ps512_mask", + "llvm.x86.avx512.mask.cvtuqq2pd.128" => "__builtin_ia32_cvtuqq2pd128_mask", + "llvm.x86.avx512.mask.cvtuqq2pd.256" => "__builtin_ia32_cvtuqq2pd256_mask", + "llvm.x86.avx512.mask.cvtuqq2pd.512" => "__builtin_ia32_cvtuqq2pd512_mask", + "llvm.x86.avx512.mask.cvtuqq2ps.128" => "__builtin_ia32_cvtuqq2ps128_mask", + "llvm.x86.avx512.mask.cvtuqq2ps.256" => "__builtin_ia32_cvtuqq2ps256_mask", + "llvm.x86.avx512.mask.cvtuqq2ps.512" => "__builtin_ia32_cvtuqq2ps512_mask", + "llvm.x86.avx512.mask.dbpsadbw.128" => "__builtin_ia32_dbpsadbw128_mask", + "llvm.x86.avx512.mask.dbpsadbw.256" => "__builtin_ia32_dbpsadbw256_mask", + "llvm.x86.avx512.mask.dbpsadbw.512" => "__builtin_ia32_dbpsadbw512_mask", + "llvm.x86.avx512.mask.div.pd.128" => "__builtin_ia32_divpd_mask", + "llvm.x86.avx512.mask.div.pd.256" => "__builtin_ia32_divpd256_mask", + "llvm.x86.avx512.mask.div.pd.512" => "__builtin_ia32_divpd512_mask", + "llvm.x86.avx512.mask.div.ps.128" => "__builtin_ia32_divps_mask", + "llvm.x86.avx512.mask.div.ps.256" => "__builtin_ia32_divps256_mask", + "llvm.x86.avx512.mask.div.ps.512" => "__builtin_ia32_divps512_mask", + "llvm.x86.avx512.mask.div.sd.round" => "__builtin_ia32_divsd_round_mask", + "llvm.x86.avx512.mask.div.ss.round" => "__builtin_ia32_divss_round_mask", + "llvm.x86.avx512.mask.expand.d.128" => "__builtin_ia32_expandsi128_mask", + "llvm.x86.avx512.mask.expand.d.256" => "__builtin_ia32_expandsi256_mask", + "llvm.x86.avx512.mask.expand.d.512" => "__builtin_ia32_expandsi512_mask", + "llvm.x86.avx512.mask.expand.load.d.128" => "__builtin_ia32_expandloadsi128_mask", + "llvm.x86.avx512.mask.expand.load.d.256" => "__builtin_ia32_expandloadsi256_mask", + "llvm.x86.avx512.mask.expand.load.d.512" => "__builtin_ia32_expandloadsi512_mask", + "llvm.x86.avx512.mask.expand.load.pd.128" => "__builtin_ia32_expandloaddf128_mask", + "llvm.x86.avx512.mask.expand.load.pd.256" => "__builtin_ia32_expandloaddf256_mask", + "llvm.x86.avx512.mask.expand.load.pd.512" => "__builtin_ia32_expandloaddf512_mask", + "llvm.x86.avx512.mask.expand.load.ps.128" => "__builtin_ia32_expandloadsf128_mask", + "llvm.x86.avx512.mask.expand.load.ps.256" => "__builtin_ia32_expandloadsf256_mask", + "llvm.x86.avx512.mask.expand.load.ps.512" => "__builtin_ia32_expandloadsf512_mask", + "llvm.x86.avx512.mask.expand.load.q.128" => "__builtin_ia32_expandloaddi128_mask", + "llvm.x86.avx512.mask.expand.load.q.256" => "__builtin_ia32_expandloaddi256_mask", + "llvm.x86.avx512.mask.expand.load.q.512" => "__builtin_ia32_expandloaddi512_mask", + "llvm.x86.avx512.mask.expand.pd.128" => "__builtin_ia32_expanddf128_mask", + "llvm.x86.avx512.mask.expand.pd.256" => "__builtin_ia32_expanddf256_mask", + "llvm.x86.avx512.mask.expand.pd.512" => "__builtin_ia32_expanddf512_mask", + "llvm.x86.avx512.mask.expand.ps.128" => "__builtin_ia32_expandsf128_mask", + "llvm.x86.avx512.mask.expand.ps.256" => "__builtin_ia32_expandsf256_mask", + "llvm.x86.avx512.mask.expand.ps.512" => "__builtin_ia32_expandsf512_mask", + "llvm.x86.avx512.mask.expand.q.128" => "__builtin_ia32_expanddi128_mask", + "llvm.x86.avx512.mask.expand.q.256" => "__builtin_ia32_expanddi256_mask", + "llvm.x86.avx512.mask.expand.q.512" => "__builtin_ia32_expanddi512_mask", + "llvm.x86.avx512.mask.fixupimm.pd.128" => "__builtin_ia32_fixupimmpd128_mask", + "llvm.x86.avx512.mask.fixupimm.pd.256" => "__builtin_ia32_fixupimmpd256_mask", + "llvm.x86.avx512.mask.fixupimm.pd.512" => "__builtin_ia32_fixupimmpd512_mask", + "llvm.x86.avx512.mask.fixupimm.ps.128" => "__builtin_ia32_fixupimmps128_mask", + "llvm.x86.avx512.mask.fixupimm.ps.256" => "__builtin_ia32_fixupimmps256_mask", + "llvm.x86.avx512.mask.fixupimm.ps.512" => "__builtin_ia32_fixupimmps512_mask", + "llvm.x86.avx512.mask.fixupimm.sd" => "__builtin_ia32_fixupimmsd_mask", + "llvm.x86.avx512.mask.fixupimm.ss" => "__builtin_ia32_fixupimmss_mask", + "llvm.x86.avx512.mask.fpclass.pd.128" => "__builtin_ia32_fpclasspd128_mask", + "llvm.x86.avx512.mask.fpclass.pd.256" => "__builtin_ia32_fpclasspd256_mask", + "llvm.x86.avx512.mask.fpclass.pd.512" => "__builtin_ia32_fpclasspd512_mask", + "llvm.x86.avx512.mask.fpclass.ps.128" => "__builtin_ia32_fpclassps128_mask", + "llvm.x86.avx512.mask.fpclass.ps.256" => "__builtin_ia32_fpclassps256_mask", + "llvm.x86.avx512.mask.fpclass.ps.512" => "__builtin_ia32_fpclassps512_mask", + "llvm.x86.avx512.mask.fpclass.sd" => "__builtin_ia32_fpclasssd_mask", + "llvm.x86.avx512.mask.fpclass.ss" => "__builtin_ia32_fpclassss_mask", + "llvm.x86.avx512.mask.getexp.pd.128" => "__builtin_ia32_getexppd128_mask", + "llvm.x86.avx512.mask.getexp.pd.256" => "__builtin_ia32_getexppd256_mask", + "llvm.x86.avx512.mask.getexp.pd.512" => "__builtin_ia32_getexppd512_mask", + "llvm.x86.avx512.mask.getexp.ps.128" => "__builtin_ia32_getexpps128_mask", + "llvm.x86.avx512.mask.getexp.ps.256" => "__builtin_ia32_getexpps256_mask", + "llvm.x86.avx512.mask.getexp.ps.512" => "__builtin_ia32_getexpps512_mask", + "llvm.x86.avx512.mask.getexp.sd" => "__builtin_ia32_getexpsd128_round_mask", + "llvm.x86.avx512.mask.getexp.ss" => "__builtin_ia32_getexpss128_round_mask", + "llvm.x86.avx512.mask.getmant.pd.128" => "__builtin_ia32_getmantpd128_mask", + "llvm.x86.avx512.mask.getmant.pd.256" => "__builtin_ia32_getmantpd256_mask", + "llvm.x86.avx512.mask.getmant.pd.512" => "__builtin_ia32_getmantpd512_mask", + "llvm.x86.avx512.mask.getmant.ps.128" => "__builtin_ia32_getmantps128_mask", + "llvm.x86.avx512.mask.getmant.ps.256" => "__builtin_ia32_getmantps256_mask", + "llvm.x86.avx512.mask.getmant.ps.512" => "__builtin_ia32_getmantps512_mask", + "llvm.x86.avx512.mask.getmant.sd" => "__builtin_ia32_getmantsd_round_mask", + "llvm.x86.avx512.mask.getmant.ss" => "__builtin_ia32_getmantss_round_mask", + "llvm.x86.avx512.mask.insertf32x4.256" => "__builtin_ia32_insertf32x4_256_mask", + "llvm.x86.avx512.mask.insertf32x4.512" => "__builtin_ia32_insertf32x4_mask", + "llvm.x86.avx512.mask.insertf32x8.512" => "__builtin_ia32_insertf32x8_mask", + "llvm.x86.avx512.mask.insertf64x2.256" => "__builtin_ia32_insertf64x2_256_mask", + "llvm.x86.avx512.mask.insertf64x2.512" => "__builtin_ia32_insertf64x2_512_mask", + "llvm.x86.avx512.mask.insertf64x4.512" => "__builtin_ia32_insertf64x4_mask", + "llvm.x86.avx512.mask.inserti32x4.256" => "__builtin_ia32_inserti32x4_256_mask", + "llvm.x86.avx512.mask.inserti32x4.512" => "__builtin_ia32_inserti32x4_mask", + "llvm.x86.avx512.mask.inserti32x8.512" => "__builtin_ia32_inserti32x8_mask", + "llvm.x86.avx512.mask.inserti64x2.256" => "__builtin_ia32_inserti64x2_256_mask", + "llvm.x86.avx512.mask.inserti64x2.512" => "__builtin_ia32_inserti64x2_512_mask", + "llvm.x86.avx512.mask.inserti64x4.512" => "__builtin_ia32_inserti64x4_mask", + "llvm.x86.avx512.mask.loadu.d.512" => "__builtin_ia32_loaddqusi512_mask", + "llvm.x86.avx512.mask.loadu.pd.512" => "__builtin_ia32_loadupd512_mask", + "llvm.x86.avx512.mask.loadu.ps.512" => "__builtin_ia32_loadups512_mask", + "llvm.x86.avx512.mask.loadu.q.512" => "__builtin_ia32_loaddqudi512_mask", + "llvm.x86.avx512.mask.lzcnt.d.512" => "__builtin_ia32_vplzcntd_512_mask", + "llvm.x86.avx512.mask.lzcnt.q.512" => "__builtin_ia32_vplzcntq_512_mask", + "llvm.x86.avx512.mask.max.pd.128" => "__builtin_ia32_maxpd_mask", + "llvm.x86.avx512.mask.max.pd.256" => "__builtin_ia32_maxpd256_mask", + "llvm.x86.avx512.mask.max.pd.512" => "__builtin_ia32_maxpd512_mask", + "llvm.x86.avx512.mask.max.ps.128" => "__builtin_ia32_maxps_mask", + "llvm.x86.avx512.mask.max.ps.256" => "__builtin_ia32_maxps256_mask", + "llvm.x86.avx512.mask.max.ps.512" => "__builtin_ia32_maxps512_mask", + "llvm.x86.avx512.mask.max.sd.round" => "__builtin_ia32_maxsd_round_mask", + "llvm.x86.avx512.mask.max.ss.round" => "__builtin_ia32_maxss_round_mask", + "llvm.x86.avx512.mask.min.pd.128" => "__builtin_ia32_minpd_mask", + "llvm.x86.avx512.mask.min.pd.256" => "__builtin_ia32_minpd256_mask", + "llvm.x86.avx512.mask.min.pd.512" => "__builtin_ia32_minpd512_mask", + "llvm.x86.avx512.mask.min.ps.128" => "__builtin_ia32_minps_mask", + "llvm.x86.avx512.mask.min.ps.256" => "__builtin_ia32_minps256_mask", + "llvm.x86.avx512.mask.min.ps.512" => "__builtin_ia32_minps512_mask", + "llvm.x86.avx512.mask.min.sd.round" => "__builtin_ia32_minsd_round_mask", + "llvm.x86.avx512.mask.min.ss.round" => "__builtin_ia32_minss_round_mask", + "llvm.x86.avx512.mask.move.sd" => "__builtin_ia32_movsd_mask", + "llvm.x86.avx512.mask.move.ss" => "__builtin_ia32_movss_mask", + "llvm.x86.avx512.mask.mul.pd.128" => "__builtin_ia32_mulpd_mask", + "llvm.x86.avx512.mask.mul.pd.256" => "__builtin_ia32_mulpd256_mask", + "llvm.x86.avx512.mask.mul.pd.512" => "__builtin_ia32_mulpd512_mask", + "llvm.x86.avx512.mask.mul.ps.128" => "__builtin_ia32_mulps_mask", + "llvm.x86.avx512.mask.mul.ps.256" => "__builtin_ia32_mulps256_mask", + "llvm.x86.avx512.mask.mul.ps.512" => "__builtin_ia32_mulps512_mask", + "llvm.x86.avx512.mask.mul.sd.round" => "__builtin_ia32_mulsd_round_mask", + "llvm.x86.avx512.mask.mul.ss.round" => "__builtin_ia32_mulss_round_mask", + "llvm.x86.avx512.mask.or.pd.128" => "__builtin_ia32_orpd128_mask", + "llvm.x86.avx512.mask.or.pd.256" => "__builtin_ia32_orpd256_mask", + "llvm.x86.avx512.mask.or.pd.512" => "__builtin_ia32_orpd512_mask", + "llvm.x86.avx512.mask.or.ps.128" => "__builtin_ia32_orps128_mask", + "llvm.x86.avx512.mask.or.ps.256" => "__builtin_ia32_orps256_mask", + "llvm.x86.avx512.mask.or.ps.512" => "__builtin_ia32_orps512_mask", + "llvm.x86.avx512.mask.pabs.b.128" => "__builtin_ia32_pabsb128_mask", + "llvm.x86.avx512.mask.pabs.b.256" => "__builtin_ia32_pabsb256_mask", + "llvm.x86.avx512.mask.pabs.b.512" => "__builtin_ia32_pabsb512_mask", + "llvm.x86.avx512.mask.pabs.d.128" => "__builtin_ia32_pabsd128_mask", + "llvm.x86.avx512.mask.pabs.d.256" => "__builtin_ia32_pabsd256_mask", + "llvm.x86.avx512.mask.pabs.d.512" => "__builtin_ia32_pabsd512_mask", + "llvm.x86.avx512.mask.pabs.q.128" => "__builtin_ia32_pabsq128_mask", + "llvm.x86.avx512.mask.pabs.q.256" => "__builtin_ia32_pabsq256_mask", + "llvm.x86.avx512.mask.pabs.q.512" => "__builtin_ia32_pabsq512_mask", + "llvm.x86.avx512.mask.pabs.w.128" => "__builtin_ia32_pabsw128_mask", + "llvm.x86.avx512.mask.pabs.w.256" => "__builtin_ia32_pabsw256_mask", + "llvm.x86.avx512.mask.pabs.w.512" => "__builtin_ia32_pabsw512_mask", + "llvm.x86.avx512.mask.packssdw.128" => "__builtin_ia32_packssdw128_mask", + "llvm.x86.avx512.mask.packssdw.256" => "__builtin_ia32_packssdw256_mask", + "llvm.x86.avx512.mask.packssdw.512" => "__builtin_ia32_packssdw512_mask", + "llvm.x86.avx512.mask.packsswb.128" => "__builtin_ia32_packsswb128_mask", + "llvm.x86.avx512.mask.packsswb.256" => "__builtin_ia32_packsswb256_mask", + "llvm.x86.avx512.mask.packsswb.512" => "__builtin_ia32_packsswb512_mask", + "llvm.x86.avx512.mask.packusdw.128" => "__builtin_ia32_packusdw128_mask", + "llvm.x86.avx512.mask.packusdw.256" => "__builtin_ia32_packusdw256_mask", + "llvm.x86.avx512.mask.packusdw.512" => "__builtin_ia32_packusdw512_mask", + "llvm.x86.avx512.mask.packuswb.128" => "__builtin_ia32_packuswb128_mask", + "llvm.x86.avx512.mask.packuswb.256" => "__builtin_ia32_packuswb256_mask", + "llvm.x86.avx512.mask.packuswb.512" => "__builtin_ia32_packuswb512_mask", + "llvm.x86.avx512.mask.padd.b.128" => "__builtin_ia32_paddb128_mask", + "llvm.x86.avx512.mask.padd.b.256" => "__builtin_ia32_paddb256_mask", + "llvm.x86.avx512.mask.padd.b.512" => "__builtin_ia32_paddb512_mask", + "llvm.x86.avx512.mask.padd.d.128" => "__builtin_ia32_paddd128_mask", + "llvm.x86.avx512.mask.padd.d.256" => "__builtin_ia32_paddd256_mask", + "llvm.x86.avx512.mask.padd.d.512" => "__builtin_ia32_paddd512_mask", + "llvm.x86.avx512.mask.padd.q.128" => "__builtin_ia32_paddq128_mask", + "llvm.x86.avx512.mask.padd.q.256" => "__builtin_ia32_paddq256_mask", + "llvm.x86.avx512.mask.padd.q.512" => "__builtin_ia32_paddq512_mask", + "llvm.x86.avx512.mask.padd.w.128" => "__builtin_ia32_paddw128_mask", + "llvm.x86.avx512.mask.padd.w.256" => "__builtin_ia32_paddw256_mask", + "llvm.x86.avx512.mask.padd.w.512" => "__builtin_ia32_paddw512_mask", + "llvm.x86.avx512.mask.padds.b.128" => "__builtin_ia32_paddsb128_mask", + "llvm.x86.avx512.mask.padds.b.256" => "__builtin_ia32_paddsb256_mask", + "llvm.x86.avx512.mask.padds.b.512" => "__builtin_ia32_paddsb512_mask", + "llvm.x86.avx512.mask.padds.w.128" => "__builtin_ia32_paddsw128_mask", + "llvm.x86.avx512.mask.padds.w.256" => "__builtin_ia32_paddsw256_mask", + "llvm.x86.avx512.mask.padds.w.512" => "__builtin_ia32_paddsw512_mask", + "llvm.x86.avx512.mask.paddus.b.128" => "__builtin_ia32_paddusb128_mask", + "llvm.x86.avx512.mask.paddus.b.256" => "__builtin_ia32_paddusb256_mask", + "llvm.x86.avx512.mask.paddus.b.512" => "__builtin_ia32_paddusb512_mask", + "llvm.x86.avx512.mask.paddus.w.128" => "__builtin_ia32_paddusw128_mask", + "llvm.x86.avx512.mask.paddus.w.256" => "__builtin_ia32_paddusw256_mask", + "llvm.x86.avx512.mask.paddus.w.512" => "__builtin_ia32_paddusw512_mask", + "llvm.x86.avx512.mask.pand.d.512" => "__builtin_ia32_pandd512_mask", + "llvm.x86.avx512.mask.pand.q.512" => "__builtin_ia32_pandq512_mask", + "llvm.x86.avx512.mask.pavg.b.128" => "__builtin_ia32_pavgb128_mask", + "llvm.x86.avx512.mask.pavg.b.256" => "__builtin_ia32_pavgb256_mask", + "llvm.x86.avx512.mask.pavg.b.512" => "__builtin_ia32_pavgb512_mask", + "llvm.x86.avx512.mask.pavg.w.128" => "__builtin_ia32_pavgw128_mask", + "llvm.x86.avx512.mask.pavg.w.256" => "__builtin_ia32_pavgw256_mask", + "llvm.x86.avx512.mask.pavg.w.512" => "__builtin_ia32_pavgw512_mask", + "llvm.x86.avx512.mask.pbroadcast.b.gpr.128" => "__builtin_ia32_pbroadcastb128_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.b.gpr.256" => "__builtin_ia32_pbroadcastb256_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.b.gpr.512" => "__builtin_ia32_pbroadcastb512_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.d.gpr.128" => "__builtin_ia32_pbroadcastd128_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.d.gpr.256" => "__builtin_ia32_pbroadcastd256_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.d.gpr.512" => "__builtin_ia32_pbroadcastd512_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.q.gpr.128" => "__builtin_ia32_pbroadcastq128_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.q.gpr.256" => "__builtin_ia32_pbroadcastq256_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.q.gpr.512" => "__builtin_ia32_pbroadcastq512_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.q.mem.512" => "__builtin_ia32_pbroadcastq512_mem_mask", + "llvm.x86.avx512.mask.pbroadcast.w.gpr.128" => "__builtin_ia32_pbroadcastw128_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.w.gpr.256" => "__builtin_ia32_pbroadcastw256_gpr_mask", + "llvm.x86.avx512.mask.pbroadcast.w.gpr.512" => "__builtin_ia32_pbroadcastw512_gpr_mask", + "llvm.x86.avx512.mask.pcmpeq.b.128" => "__builtin_ia32_pcmpeqb128_mask", + "llvm.x86.avx512.mask.pcmpeq.b.256" => "__builtin_ia32_pcmpeqb256_mask", + "llvm.x86.avx512.mask.pcmpeq.b.512" => "__builtin_ia32_pcmpeqb512_mask", + "llvm.x86.avx512.mask.pcmpeq.d.128" => "__builtin_ia32_pcmpeqd128_mask", + "llvm.x86.avx512.mask.pcmpeq.d.256" => "__builtin_ia32_pcmpeqd256_mask", + "llvm.x86.avx512.mask.pcmpeq.d.512" => "__builtin_ia32_pcmpeqd512_mask", + "llvm.x86.avx512.mask.pcmpeq.q.128" => "__builtin_ia32_pcmpeqq128_mask", + "llvm.x86.avx512.mask.pcmpeq.q.256" => "__builtin_ia32_pcmpeqq256_mask", + "llvm.x86.avx512.mask.pcmpeq.q.512" => "__builtin_ia32_pcmpeqq512_mask", + "llvm.x86.avx512.mask.pcmpeq.w.128" => "__builtin_ia32_pcmpeqw128_mask", + "llvm.x86.avx512.mask.pcmpeq.w.256" => "__builtin_ia32_pcmpeqw256_mask", + "llvm.x86.avx512.mask.pcmpeq.w.512" => "__builtin_ia32_pcmpeqw512_mask", + "llvm.x86.avx512.mask.pcmpgt.b.128" => "__builtin_ia32_pcmpgtb128_mask", + "llvm.x86.avx512.mask.pcmpgt.b.256" => "__builtin_ia32_pcmpgtb256_mask", + "llvm.x86.avx512.mask.pcmpgt.b.512" => "__builtin_ia32_pcmpgtb512_mask", + "llvm.x86.avx512.mask.pcmpgt.d.128" => "__builtin_ia32_pcmpgtd128_mask", + "llvm.x86.avx512.mask.pcmpgt.d.256" => "__builtin_ia32_pcmpgtd256_mask", + "llvm.x86.avx512.mask.pcmpgt.d.512" => "__builtin_ia32_pcmpgtd512_mask", + "llvm.x86.avx512.mask.pcmpgt.q.128" => "__builtin_ia32_pcmpgtq128_mask", + "llvm.x86.avx512.mask.pcmpgt.q.256" => "__builtin_ia32_pcmpgtq256_mask", + "llvm.x86.avx512.mask.pcmpgt.q.512" => "__builtin_ia32_pcmpgtq512_mask", + "llvm.x86.avx512.mask.pcmpgt.w.128" => "__builtin_ia32_pcmpgtw128_mask", + "llvm.x86.avx512.mask.pcmpgt.w.256" => "__builtin_ia32_pcmpgtw256_mask", + "llvm.x86.avx512.mask.pcmpgt.w.512" => "__builtin_ia32_pcmpgtw512_mask", + "llvm.x86.avx512.mask.permvar.df.256" => "__builtin_ia32_permvardf256_mask", + "llvm.x86.avx512.mask.permvar.df.512" => "__builtin_ia32_permvardf512_mask", + "llvm.x86.avx512.mask.permvar.di.256" => "__builtin_ia32_permvardi256_mask", + "llvm.x86.avx512.mask.permvar.di.512" => "__builtin_ia32_permvardi512_mask", + "llvm.x86.avx512.mask.permvar.hi.128" => "__builtin_ia32_permvarhi128_mask", + "llvm.x86.avx512.mask.permvar.hi.256" => "__builtin_ia32_permvarhi256_mask", + "llvm.x86.avx512.mask.permvar.hi.512" => "__builtin_ia32_permvarhi512_mask", + "llvm.x86.avx512.mask.permvar.qi.128" => "__builtin_ia32_permvarqi128_mask", + "llvm.x86.avx512.mask.permvar.qi.256" => "__builtin_ia32_permvarqi256_mask", + "llvm.x86.avx512.mask.permvar.qi.512" => "__builtin_ia32_permvarqi512_mask", + "llvm.x86.avx512.mask.permvar.sf.256" => "__builtin_ia32_permvarsf256_mask", + "llvm.x86.avx512.mask.permvar.sf.512" => "__builtin_ia32_permvarsf512_mask", + "llvm.x86.avx512.mask.permvar.si.256" => "__builtin_ia32_permvarsi256_mask", + "llvm.x86.avx512.mask.permvar.si.512" => "__builtin_ia32_permvarsi512_mask", + "llvm.x86.avx512.mask.pmaddubs.w.128" => "__builtin_ia32_pmaddubsw128_mask", + "llvm.x86.avx512.mask.pmaddubs.w.256" => "__builtin_ia32_pmaddubsw256_mask", + "llvm.x86.avx512.mask.pmaddubs.w.512" => "__builtin_ia32_pmaddubsw512_mask", + "llvm.x86.avx512.mask.pmaddw.d.128" => "__builtin_ia32_pmaddwd128_mask", + "llvm.x86.avx512.mask.pmaddw.d.256" => "__builtin_ia32_pmaddwd256_mask", + "llvm.x86.avx512.mask.pmaddw.d.512" => "__builtin_ia32_pmaddwd512_mask", + "llvm.x86.avx512.mask.pmaxs.b.128" => "__builtin_ia32_pmaxsb128_mask", + "llvm.x86.avx512.mask.pmaxs.b.256" => "__builtin_ia32_pmaxsb256_mask", + "llvm.x86.avx512.mask.pmaxs.b.512" => "__builtin_ia32_pmaxsb512_mask", + "llvm.x86.avx512.mask.pmaxs.d.128" => "__builtin_ia32_pmaxsd128_mask", + "llvm.x86.avx512.mask.pmaxs.d.256" => "__builtin_ia32_pmaxsd256_mask", + "llvm.x86.avx512.mask.pmaxs.d.512" => "__builtin_ia32_pmaxsd512_mask", + "llvm.x86.avx512.mask.pmaxs.q.128" => "__builtin_ia32_pmaxsq128_mask", + "llvm.x86.avx512.mask.pmaxs.q.256" => "__builtin_ia32_pmaxsq256_mask", + "llvm.x86.avx512.mask.pmaxs.q.512" => "__builtin_ia32_pmaxsq512_mask", + "llvm.x86.avx512.mask.pmaxs.w.128" => "__builtin_ia32_pmaxsw128_mask", + "llvm.x86.avx512.mask.pmaxs.w.256" => "__builtin_ia32_pmaxsw256_mask", + "llvm.x86.avx512.mask.pmaxs.w.512" => "__builtin_ia32_pmaxsw512_mask", + "llvm.x86.avx512.mask.pmaxu.b.128" => "__builtin_ia32_pmaxub128_mask", + "llvm.x86.avx512.mask.pmaxu.b.256" => "__builtin_ia32_pmaxub256_mask", + "llvm.x86.avx512.mask.pmaxu.b.512" => "__builtin_ia32_pmaxub512_mask", + "llvm.x86.avx512.mask.pmaxu.d.128" => "__builtin_ia32_pmaxud128_mask", + "llvm.x86.avx512.mask.pmaxu.d.256" => "__builtin_ia32_pmaxud256_mask", + "llvm.x86.avx512.mask.pmaxu.d.512" => "__builtin_ia32_pmaxud512_mask", + "llvm.x86.avx512.mask.pmaxu.q.128" => "__builtin_ia32_pmaxuq128_mask", + "llvm.x86.avx512.mask.pmaxu.q.256" => "__builtin_ia32_pmaxuq256_mask", + "llvm.x86.avx512.mask.pmaxu.q.512" => "__builtin_ia32_pmaxuq512_mask", + "llvm.x86.avx512.mask.pmaxu.w.128" => "__builtin_ia32_pmaxuw128_mask", + "llvm.x86.avx512.mask.pmaxu.w.256" => "__builtin_ia32_pmaxuw256_mask", + "llvm.x86.avx512.mask.pmaxu.w.512" => "__builtin_ia32_pmaxuw512_mask", + "llvm.x86.avx512.mask.pmins.b.128" => "__builtin_ia32_pminsb128_mask", + "llvm.x86.avx512.mask.pmins.b.256" => "__builtin_ia32_pminsb256_mask", + "llvm.x86.avx512.mask.pmins.b.512" => "__builtin_ia32_pminsb512_mask", + "llvm.x86.avx512.mask.pmins.d.128" => "__builtin_ia32_pminsd128_mask", + "llvm.x86.avx512.mask.pmins.d.256" => "__builtin_ia32_pminsd256_mask", + "llvm.x86.avx512.mask.pmins.d.512" => "__builtin_ia32_pminsd512_mask", + "llvm.x86.avx512.mask.pmins.q.128" => "__builtin_ia32_pminsq128_mask", + "llvm.x86.avx512.mask.pmins.q.256" => "__builtin_ia32_pminsq256_mask", + "llvm.x86.avx512.mask.pmins.q.512" => "__builtin_ia32_pminsq512_mask", + "llvm.x86.avx512.mask.pmins.w.128" => "__builtin_ia32_pminsw128_mask", + "llvm.x86.avx512.mask.pmins.w.256" => "__builtin_ia32_pminsw256_mask", + "llvm.x86.avx512.mask.pmins.w.512" => "__builtin_ia32_pminsw512_mask", + "llvm.x86.avx512.mask.pminu.b.128" => "__builtin_ia32_pminub128_mask", + "llvm.x86.avx512.mask.pminu.b.256" => "__builtin_ia32_pminub256_mask", + "llvm.x86.avx512.mask.pminu.b.512" => "__builtin_ia32_pminub512_mask", + "llvm.x86.avx512.mask.pminu.d.128" => "__builtin_ia32_pminud128_mask", + "llvm.x86.avx512.mask.pminu.d.256" => "__builtin_ia32_pminud256_mask", + "llvm.x86.avx512.mask.pminu.d.512" => "__builtin_ia32_pminud512_mask", + "llvm.x86.avx512.mask.pminu.q.128" => "__builtin_ia32_pminuq128_mask", + "llvm.x86.avx512.mask.pminu.q.256" => "__builtin_ia32_pminuq256_mask", + "llvm.x86.avx512.mask.pminu.q.512" => "__builtin_ia32_pminuq512_mask", + "llvm.x86.avx512.mask.pminu.w.128" => "__builtin_ia32_pminuw128_mask", + "llvm.x86.avx512.mask.pminu.w.256" => "__builtin_ia32_pminuw256_mask", + "llvm.x86.avx512.mask.pminu.w.512" => "__builtin_ia32_pminuw512_mask", + "llvm.x86.avx512.mask.pmov.db.128" => "__builtin_ia32_pmovdb128_mask", + "llvm.x86.avx512.mask.pmov.db.256" => "__builtin_ia32_pmovdb256_mask", + "llvm.x86.avx512.mask.pmov.db.512" => "__builtin_ia32_pmovdb512_mask", + "llvm.x86.avx512.mask.pmov.db.mem.128" => "__builtin_ia32_pmovdb128mem_mask", + "llvm.x86.avx512.mask.pmov.db.mem.256" => "__builtin_ia32_pmovdb256mem_mask", + "llvm.x86.avx512.mask.pmov.db.mem.512" => "__builtin_ia32_pmovdb512mem_mask", + "llvm.x86.avx512.mask.pmov.dw.128" => "__builtin_ia32_pmovdw128_mask", + "llvm.x86.avx512.mask.pmov.dw.256" => "__builtin_ia32_pmovdw256_mask", + "llvm.x86.avx512.mask.pmov.dw.512" => "__builtin_ia32_pmovdw512_mask", + "llvm.x86.avx512.mask.pmov.dw.mem.128" => "__builtin_ia32_pmovdw128mem_mask", + "llvm.x86.avx512.mask.pmov.dw.mem.256" => "__builtin_ia32_pmovdw256mem_mask", + "llvm.x86.avx512.mask.pmov.dw.mem.512" => "__builtin_ia32_pmovdw512mem_mask", + "llvm.x86.avx512.mask.pmov.qb.128" => "__builtin_ia32_pmovqb128_mask", + "llvm.x86.avx512.mask.pmov.qb.256" => "__builtin_ia32_pmovqb256_mask", + "llvm.x86.avx512.mask.pmov.qb.512" => "__builtin_ia32_pmovqb512_mask", + "llvm.x86.avx512.mask.pmov.qb.mem.128" => "__builtin_ia32_pmovqb128mem_mask", + "llvm.x86.avx512.mask.pmov.qb.mem.256" => "__builtin_ia32_pmovqb256mem_mask", + "llvm.x86.avx512.mask.pmov.qb.mem.512" => "__builtin_ia32_pmovqb512mem_mask", + "llvm.x86.avx512.mask.pmov.qd.128" => "__builtin_ia32_pmovqd128_mask", + "llvm.x86.avx512.mask.pmov.qd.256" => "__builtin_ia32_pmovqd256_mask", + "llvm.x86.avx512.mask.pmov.qd.512" => "__builtin_ia32_pmovqd512_mask", + "llvm.x86.avx512.mask.pmov.qd.mem.128" => "__builtin_ia32_pmovqd128mem_mask", + "llvm.x86.avx512.mask.pmov.qd.mem.256" => "__builtin_ia32_pmovqd256mem_mask", + "llvm.x86.avx512.mask.pmov.qd.mem.512" => "__builtin_ia32_pmovqd512mem_mask", + "llvm.x86.avx512.mask.pmov.qw.128" => "__builtin_ia32_pmovqw128_mask", + "llvm.x86.avx512.mask.pmov.qw.256" => "__builtin_ia32_pmovqw256_mask", + "llvm.x86.avx512.mask.pmov.qw.512" => "__builtin_ia32_pmovqw512_mask", + "llvm.x86.avx512.mask.pmov.qw.mem.128" => "__builtin_ia32_pmovqw128mem_mask", + "llvm.x86.avx512.mask.pmov.qw.mem.256" => "__builtin_ia32_pmovqw256mem_mask", + "llvm.x86.avx512.mask.pmov.qw.mem.512" => "__builtin_ia32_pmovqw512mem_mask", + "llvm.x86.avx512.mask.pmov.wb.128" => "__builtin_ia32_pmovwb128_mask", + "llvm.x86.avx512.mask.pmov.wb.256" => "__builtin_ia32_pmovwb256_mask", + "llvm.x86.avx512.mask.pmov.wb.512" => "__builtin_ia32_pmovwb512_mask", + "llvm.x86.avx512.mask.pmov.wb.mem.128" => "__builtin_ia32_pmovwb128mem_mask", + "llvm.x86.avx512.mask.pmov.wb.mem.256" => "__builtin_ia32_pmovwb256mem_mask", + "llvm.x86.avx512.mask.pmov.wb.mem.512" => "__builtin_ia32_pmovwb512mem_mask", + "llvm.x86.avx512.mask.pmovs.db.128" => "__builtin_ia32_pmovsdb128_mask", + "llvm.x86.avx512.mask.pmovs.db.256" => "__builtin_ia32_pmovsdb256_mask", + "llvm.x86.avx512.mask.pmovs.db.512" => "__builtin_ia32_pmovsdb512_mask", + "llvm.x86.avx512.mask.pmovs.db.mem.128" => "__builtin_ia32_pmovsdb128mem_mask", + "llvm.x86.avx512.mask.pmovs.db.mem.256" => "__builtin_ia32_pmovsdb256mem_mask", + "llvm.x86.avx512.mask.pmovs.db.mem.512" => "__builtin_ia32_pmovsdb512mem_mask", + "llvm.x86.avx512.mask.pmovs.dw.128" => "__builtin_ia32_pmovsdw128_mask", + "llvm.x86.avx512.mask.pmovs.dw.256" => "__builtin_ia32_pmovsdw256_mask", + "llvm.x86.avx512.mask.pmovs.dw.512" => "__builtin_ia32_pmovsdw512_mask", + "llvm.x86.avx512.mask.pmovs.dw.mem.128" => "__builtin_ia32_pmovsdw128mem_mask", + "llvm.x86.avx512.mask.pmovs.dw.mem.256" => "__builtin_ia32_pmovsdw256mem_mask", + "llvm.x86.avx512.mask.pmovs.dw.mem.512" => "__builtin_ia32_pmovsdw512mem_mask", + "llvm.x86.avx512.mask.pmovs.qb.128" => "__builtin_ia32_pmovsqb128_mask", + "llvm.x86.avx512.mask.pmovs.qb.256" => "__builtin_ia32_pmovsqb256_mask", + "llvm.x86.avx512.mask.pmovs.qb.512" => "__builtin_ia32_pmovsqb512_mask", + "llvm.x86.avx512.mask.pmovs.qb.mem.128" => "__builtin_ia32_pmovsqb128mem_mask", + "llvm.x86.avx512.mask.pmovs.qb.mem.256" => "__builtin_ia32_pmovsqb256mem_mask", + "llvm.x86.avx512.mask.pmovs.qb.mem.512" => "__builtin_ia32_pmovsqb512mem_mask", + "llvm.x86.avx512.mask.pmovs.qd.128" => "__builtin_ia32_pmovsqd128_mask", + "llvm.x86.avx512.mask.pmovs.qd.256" => "__builtin_ia32_pmovsqd256_mask", + "llvm.x86.avx512.mask.pmovs.qd.512" => "__builtin_ia32_pmovsqd512_mask", + "llvm.x86.avx512.mask.pmovs.qd.mem.128" => "__builtin_ia32_pmovsqd128mem_mask", + "llvm.x86.avx512.mask.pmovs.qd.mem.256" => "__builtin_ia32_pmovsqd256mem_mask", + "llvm.x86.avx512.mask.pmovs.qd.mem.512" => "__builtin_ia32_pmovsqd512mem_mask", + "llvm.x86.avx512.mask.pmovs.qw.128" => "__builtin_ia32_pmovsqw128_mask", + "llvm.x86.avx512.mask.pmovs.qw.256" => "__builtin_ia32_pmovsqw256_mask", + "llvm.x86.avx512.mask.pmovs.qw.512" => "__builtin_ia32_pmovsqw512_mask", + "llvm.x86.avx512.mask.pmovs.qw.mem.128" => "__builtin_ia32_pmovsqw128mem_mask", + "llvm.x86.avx512.mask.pmovs.qw.mem.256" => "__builtin_ia32_pmovsqw256mem_mask", + "llvm.x86.avx512.mask.pmovs.qw.mem.512" => "__builtin_ia32_pmovsqw512mem_mask", + "llvm.x86.avx512.mask.pmovs.wb.128" => "__builtin_ia32_pmovswb128_mask", + "llvm.x86.avx512.mask.pmovs.wb.256" => "__builtin_ia32_pmovswb256_mask", + "llvm.x86.avx512.mask.pmovs.wb.512" => "__builtin_ia32_pmovswb512_mask", + "llvm.x86.avx512.mask.pmovs.wb.mem.128" => "__builtin_ia32_pmovswb128mem_mask", + "llvm.x86.avx512.mask.pmovs.wb.mem.256" => "__builtin_ia32_pmovswb256mem_mask", + "llvm.x86.avx512.mask.pmovs.wb.mem.512" => "__builtin_ia32_pmovswb512mem_mask", + "llvm.x86.avx512.mask.pmovsxb.d.128" => "__builtin_ia32_pmovsxbd128_mask", + "llvm.x86.avx512.mask.pmovsxb.d.256" => "__builtin_ia32_pmovsxbd256_mask", + "llvm.x86.avx512.mask.pmovsxb.d.512" => "__builtin_ia32_pmovsxbd512_mask", + "llvm.x86.avx512.mask.pmovsxb.q.128" => "__builtin_ia32_pmovsxbq128_mask", + "llvm.x86.avx512.mask.pmovsxb.q.256" => "__builtin_ia32_pmovsxbq256_mask", + "llvm.x86.avx512.mask.pmovsxb.q.512" => "__builtin_ia32_pmovsxbq512_mask", + "llvm.x86.avx512.mask.pmovsxb.w.128" => "__builtin_ia32_pmovsxbw128_mask", + "llvm.x86.avx512.mask.pmovsxb.w.256" => "__builtin_ia32_pmovsxbw256_mask", + "llvm.x86.avx512.mask.pmovsxb.w.512" => "__builtin_ia32_pmovsxbw512_mask", + "llvm.x86.avx512.mask.pmovsxd.q.128" => "__builtin_ia32_pmovsxdq128_mask", + "llvm.x86.avx512.mask.pmovsxd.q.256" => "__builtin_ia32_pmovsxdq256_mask", + "llvm.x86.avx512.mask.pmovsxd.q.512" => "__builtin_ia32_pmovsxdq512_mask", + "llvm.x86.avx512.mask.pmovsxw.d.128" => "__builtin_ia32_pmovsxwd128_mask", + "llvm.x86.avx512.mask.pmovsxw.d.256" => "__builtin_ia32_pmovsxwd256_mask", + "llvm.x86.avx512.mask.pmovsxw.d.512" => "__builtin_ia32_pmovsxwd512_mask", + "llvm.x86.avx512.mask.pmovsxw.q.128" => "__builtin_ia32_pmovsxwq128_mask", + "llvm.x86.avx512.mask.pmovsxw.q.256" => "__builtin_ia32_pmovsxwq256_mask", + "llvm.x86.avx512.mask.pmovsxw.q.512" => "__builtin_ia32_pmovsxwq512_mask", + "llvm.x86.avx512.mask.pmovus.db.128" => "__builtin_ia32_pmovusdb128_mask", + "llvm.x86.avx512.mask.pmovus.db.256" => "__builtin_ia32_pmovusdb256_mask", + "llvm.x86.avx512.mask.pmovus.db.512" => "__builtin_ia32_pmovusdb512_mask", + "llvm.x86.avx512.mask.pmovus.db.mem.128" => "__builtin_ia32_pmovusdb128mem_mask", + "llvm.x86.avx512.mask.pmovus.db.mem.256" => "__builtin_ia32_pmovusdb256mem_mask", + "llvm.x86.avx512.mask.pmovus.db.mem.512" => "__builtin_ia32_pmovusdb512mem_mask", + "llvm.x86.avx512.mask.pmovus.dw.128" => "__builtin_ia32_pmovusdw128_mask", + "llvm.x86.avx512.mask.pmovus.dw.256" => "__builtin_ia32_pmovusdw256_mask", + "llvm.x86.avx512.mask.pmovus.dw.512" => "__builtin_ia32_pmovusdw512_mask", + "llvm.x86.avx512.mask.pmovus.dw.mem.128" => "__builtin_ia32_pmovusdw128mem_mask", + "llvm.x86.avx512.mask.pmovus.dw.mem.256" => "__builtin_ia32_pmovusdw256mem_mask", + "llvm.x86.avx512.mask.pmovus.dw.mem.512" => "__builtin_ia32_pmovusdw512mem_mask", + "llvm.x86.avx512.mask.pmovus.qb.128" => "__builtin_ia32_pmovusqb128_mask", + "llvm.x86.avx512.mask.pmovus.qb.256" => "__builtin_ia32_pmovusqb256_mask", + "llvm.x86.avx512.mask.pmovus.qb.512" => "__builtin_ia32_pmovusqb512_mask", + "llvm.x86.avx512.mask.pmovus.qb.mem.128" => "__builtin_ia32_pmovusqb128mem_mask", + "llvm.x86.avx512.mask.pmovus.qb.mem.256" => "__builtin_ia32_pmovusqb256mem_mask", + "llvm.x86.avx512.mask.pmovus.qb.mem.512" => "__builtin_ia32_pmovusqb512mem_mask", + "llvm.x86.avx512.mask.pmovus.qd.128" => "__builtin_ia32_pmovusqd128_mask", + "llvm.x86.avx512.mask.pmovus.qd.256" => "__builtin_ia32_pmovusqd256_mask", + "llvm.x86.avx512.mask.pmovus.qd.512" => "__builtin_ia32_pmovusqd512_mask", + "llvm.x86.avx512.mask.pmovus.qd.mem.128" => "__builtin_ia32_pmovusqd128mem_mask", + "llvm.x86.avx512.mask.pmovus.qd.mem.256" => "__builtin_ia32_pmovusqd256mem_mask", + "llvm.x86.avx512.mask.pmovus.qd.mem.512" => "__builtin_ia32_pmovusqd512mem_mask", + "llvm.x86.avx512.mask.pmovus.qw.128" => "__builtin_ia32_pmovusqw128_mask", + "llvm.x86.avx512.mask.pmovus.qw.256" => "__builtin_ia32_pmovusqw256_mask", + "llvm.x86.avx512.mask.pmovus.qw.512" => "__builtin_ia32_pmovusqw512_mask", + "llvm.x86.avx512.mask.pmovus.qw.mem.128" => "__builtin_ia32_pmovusqw128mem_mask", + "llvm.x86.avx512.mask.pmovus.qw.mem.256" => "__builtin_ia32_pmovusqw256mem_mask", + "llvm.x86.avx512.mask.pmovus.qw.mem.512" => "__builtin_ia32_pmovusqw512mem_mask", + "llvm.x86.avx512.mask.pmovus.wb.128" => "__builtin_ia32_pmovuswb128_mask", + "llvm.x86.avx512.mask.pmovus.wb.256" => "__builtin_ia32_pmovuswb256_mask", + "llvm.x86.avx512.mask.pmovus.wb.512" => "__builtin_ia32_pmovuswb512_mask", + "llvm.x86.avx512.mask.pmovus.wb.mem.128" => "__builtin_ia32_pmovuswb128mem_mask", + "llvm.x86.avx512.mask.pmovus.wb.mem.256" => "__builtin_ia32_pmovuswb256mem_mask", + "llvm.x86.avx512.mask.pmovus.wb.mem.512" => "__builtin_ia32_pmovuswb512mem_mask", + "llvm.x86.avx512.mask.pmovzxb.d.128" => "__builtin_ia32_pmovzxbd128_mask", + "llvm.x86.avx512.mask.pmovzxb.d.256" => "__builtin_ia32_pmovzxbd256_mask", + "llvm.x86.avx512.mask.pmovzxb.d.512" => "__builtin_ia32_pmovzxbd512_mask", + "llvm.x86.avx512.mask.pmovzxb.q.128" => "__builtin_ia32_pmovzxbq128_mask", + "llvm.x86.avx512.mask.pmovzxb.q.256" => "__builtin_ia32_pmovzxbq256_mask", + "llvm.x86.avx512.mask.pmovzxb.q.512" => "__builtin_ia32_pmovzxbq512_mask", + "llvm.x86.avx512.mask.pmovzxb.w.128" => "__builtin_ia32_pmovzxbw128_mask", + "llvm.x86.avx512.mask.pmovzxb.w.256" => "__builtin_ia32_pmovzxbw256_mask", + "llvm.x86.avx512.mask.pmovzxb.w.512" => "__builtin_ia32_pmovzxbw512_mask", + "llvm.x86.avx512.mask.pmovzxd.q.128" => "__builtin_ia32_pmovzxdq128_mask", + "llvm.x86.avx512.mask.pmovzxd.q.256" => "__builtin_ia32_pmovzxdq256_mask", + "llvm.x86.avx512.mask.pmovzxd.q.512" => "__builtin_ia32_pmovzxdq512_mask", + "llvm.x86.avx512.mask.pmovzxw.d.128" => "__builtin_ia32_pmovzxwd128_mask", + "llvm.x86.avx512.mask.pmovzxw.d.256" => "__builtin_ia32_pmovzxwd256_mask", + "llvm.x86.avx512.mask.pmovzxw.d.512" => "__builtin_ia32_pmovzxwd512_mask", + "llvm.x86.avx512.mask.pmovzxw.q.128" => "__builtin_ia32_pmovzxwq128_mask", + "llvm.x86.avx512.mask.pmovzxw.q.256" => "__builtin_ia32_pmovzxwq256_mask", + "llvm.x86.avx512.mask.pmovzxw.q.512" => "__builtin_ia32_pmovzxwq512_mask", + "llvm.x86.avx512.mask.pmul.dq.128" => "__builtin_ia32_pmuldq128_mask", + "llvm.x86.avx512.mask.pmul.dq.256" => "__builtin_ia32_pmuldq256_mask", + "llvm.x86.avx512.mask.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask", + "llvm.x86.avx512.mask.pmul.hr.sw.128" => "__builtin_ia32_pmulhrsw128_mask", + "llvm.x86.avx512.mask.pmul.hr.sw.256" => "__builtin_ia32_pmulhrsw256_mask", + "llvm.x86.avx512.mask.pmul.hr.sw.512" => "__builtin_ia32_pmulhrsw512_mask", + "llvm.x86.avx512.mask.pmulh.w.128" => "__builtin_ia32_pmulhw128_mask", + "llvm.x86.avx512.mask.pmulh.w.256" => "__builtin_ia32_pmulhw256_mask", + "llvm.x86.avx512.mask.pmulh.w.512" => "__builtin_ia32_pmulhw512_mask", + "llvm.x86.avx512.mask.pmulhu.w.128" => "__builtin_ia32_pmulhuw128_mask", + "llvm.x86.avx512.mask.pmulhu.w.256" => "__builtin_ia32_pmulhuw256_mask", + "llvm.x86.avx512.mask.pmulhu.w.512" => "__builtin_ia32_pmulhuw512_mask", + "llvm.x86.avx512.mask.pmull.d.128" => "__builtin_ia32_pmulld128_mask", + "llvm.x86.avx512.mask.pmull.d.256" => "__builtin_ia32_pmulld256_mask", + "llvm.x86.avx512.mask.pmull.d.512" => "__builtin_ia32_pmulld512_mask", + "llvm.x86.avx512.mask.pmull.q.128" => "__builtin_ia32_pmullq128_mask", + "llvm.x86.avx512.mask.pmull.q.256" => "__builtin_ia32_pmullq256_mask", + "llvm.x86.avx512.mask.pmull.q.512" => "__builtin_ia32_pmullq512_mask", + "llvm.x86.avx512.mask.pmull.w.128" => "__builtin_ia32_pmullw128_mask", + "llvm.x86.avx512.mask.pmull.w.256" => "__builtin_ia32_pmullw256_mask", + "llvm.x86.avx512.mask.pmull.w.512" => "__builtin_ia32_pmullw512_mask", + "llvm.x86.avx512.mask.pmultishift.qb.128" => "__builtin_ia32_vpmultishiftqb128_mask", + "llvm.x86.avx512.mask.pmultishift.qb.256" => "__builtin_ia32_vpmultishiftqb256_mask", + "llvm.x86.avx512.mask.pmultishift.qb.512" => "__builtin_ia32_vpmultishiftqb512_mask", + "llvm.x86.avx512.mask.pmulu.dq.128" => "__builtin_ia32_pmuludq128_mask", + "llvm.x86.avx512.mask.pmulu.dq.256" => "__builtin_ia32_pmuludq256_mask", + "llvm.x86.avx512.mask.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask", + "llvm.x86.avx512.mask.prol.d.128" => "__builtin_ia32_prold128_mask", + "llvm.x86.avx512.mask.prol.d.256" => "__builtin_ia32_prold256_mask", + "llvm.x86.avx512.mask.prol.d.512" => "__builtin_ia32_prold512_mask", + "llvm.x86.avx512.mask.prol.q.128" => "__builtin_ia32_prolq128_mask", + "llvm.x86.avx512.mask.prol.q.256" => "__builtin_ia32_prolq256_mask", + "llvm.x86.avx512.mask.prol.q.512" => "__builtin_ia32_prolq512_mask", + "llvm.x86.avx512.mask.prolv.d.128" => "__builtin_ia32_prolvd128_mask", + "llvm.x86.avx512.mask.prolv.d.256" => "__builtin_ia32_prolvd256_mask", + "llvm.x86.avx512.mask.prolv.d.512" => "__builtin_ia32_prolvd512_mask", + "llvm.x86.avx512.mask.prolv.q.128" => "__builtin_ia32_prolvq128_mask", + "llvm.x86.avx512.mask.prolv.q.256" => "__builtin_ia32_prolvq256_mask", + "llvm.x86.avx512.mask.prolv.q.512" => "__builtin_ia32_prolvq512_mask", + "llvm.x86.avx512.mask.pror.d.128" => "__builtin_ia32_prord128_mask", + "llvm.x86.avx512.mask.pror.d.256" => "__builtin_ia32_prord256_mask", + "llvm.x86.avx512.mask.pror.d.512" => "__builtin_ia32_prord512_mask", + "llvm.x86.avx512.mask.pror.q.128" => "__builtin_ia32_prorq128_mask", + "llvm.x86.avx512.mask.pror.q.256" => "__builtin_ia32_prorq256_mask", + "llvm.x86.avx512.mask.pror.q.512" => "__builtin_ia32_prorq512_mask", + "llvm.x86.avx512.mask.prorv.d.128" => "__builtin_ia32_prorvd128_mask", + "llvm.x86.avx512.mask.prorv.d.256" => "__builtin_ia32_prorvd256_mask", + "llvm.x86.avx512.mask.prorv.d.512" => "__builtin_ia32_prorvd512_mask", + "llvm.x86.avx512.mask.prorv.q.128" => "__builtin_ia32_prorvq128_mask", + "llvm.x86.avx512.mask.prorv.q.256" => "__builtin_ia32_prorvq256_mask", + "llvm.x86.avx512.mask.prorv.q.512" => "__builtin_ia32_prorvq512_mask", + "llvm.x86.avx512.mask.pshuf.b.128" => "__builtin_ia32_pshufb128_mask", + "llvm.x86.avx512.mask.pshuf.b.256" => "__builtin_ia32_pshufb256_mask", + "llvm.x86.avx512.mask.pshuf.b.512" => "__builtin_ia32_pshufb512_mask", + "llvm.x86.avx512.mask.psll.d" => "__builtin_ia32_pslld512_mask", + "llvm.x86.avx512.mask.psll.d.128" => "__builtin_ia32_pslld128_mask", + "llvm.x86.avx512.mask.psll.d.256" => "__builtin_ia32_pslld256_mask", + "llvm.x86.avx512.mask.psll.di.128" => "__builtin_ia32_pslldi128_mask", + "llvm.x86.avx512.mask.psll.di.256" => "__builtin_ia32_pslldi256_mask", + "llvm.x86.avx512.mask.psll.di.512" => "__builtin_ia32_pslldi512_mask", + "llvm.x86.avx512.mask.psll.q" => "__builtin_ia32_psllq512_mask", + "llvm.x86.avx512.mask.psll.q.128" => "__builtin_ia32_psllq128_mask", + "llvm.x86.avx512.mask.psll.q.256" => "__builtin_ia32_psllq256_mask", + "llvm.x86.avx512.mask.psll.qi.128" => "__builtin_ia32_psllqi128_mask", + "llvm.x86.avx512.mask.psll.qi.256" => "__builtin_ia32_psllqi256_mask", + "llvm.x86.avx512.mask.psll.qi.512" => "__builtin_ia32_psllqi512_mask", + "llvm.x86.avx512.mask.psll.w.128" => "__builtin_ia32_psllw128_mask", + "llvm.x86.avx512.mask.psll.w.256" => "__builtin_ia32_psllw256_mask", + "llvm.x86.avx512.mask.psll.w.512" => "__builtin_ia32_psllw512_mask", + "llvm.x86.avx512.mask.psll.wi.128" => "__builtin_ia32_psllwi128_mask", + "llvm.x86.avx512.mask.psll.wi.256" => "__builtin_ia32_psllwi256_mask", + "llvm.x86.avx512.mask.psll.wi.512" => "__builtin_ia32_psllwi512_mask", + "llvm.x86.avx512.mask.psllv.d" => "__builtin_ia32_psllv16si_mask", + "llvm.x86.avx512.mask.psllv.q" => "__builtin_ia32_psllv8di_mask", + "llvm.x86.avx512.mask.psllv16.hi" => "__builtin_ia32_psllv16hi_mask", + "llvm.x86.avx512.mask.psllv2.di" => "__builtin_ia32_psllv2di_mask", + "llvm.x86.avx512.mask.psllv32hi" => "__builtin_ia32_psllv32hi_mask", + "llvm.x86.avx512.mask.psllv4.di" => "__builtin_ia32_psllv4di_mask", + "llvm.x86.avx512.mask.psllv4.si" => "__builtin_ia32_psllv4si_mask", + "llvm.x86.avx512.mask.psllv8.hi" => "__builtin_ia32_psllv8hi_mask", + "llvm.x86.avx512.mask.psllv8.si" => "__builtin_ia32_psllv8si_mask", + "llvm.x86.avx512.mask.psra.d" => "__builtin_ia32_psrad512_mask", + "llvm.x86.avx512.mask.psra.d.128" => "__builtin_ia32_psrad128_mask", + "llvm.x86.avx512.mask.psra.d.256" => "__builtin_ia32_psrad256_mask", + "llvm.x86.avx512.mask.psra.di.128" => "__builtin_ia32_psradi128_mask", + "llvm.x86.avx512.mask.psra.di.256" => "__builtin_ia32_psradi256_mask", + "llvm.x86.avx512.mask.psra.di.512" => "__builtin_ia32_psradi512_mask", + "llvm.x86.avx512.mask.psra.q" => "__builtin_ia32_psraq512_mask", + "llvm.x86.avx512.mask.psra.q.128" => "__builtin_ia32_psraq128_mask", + "llvm.x86.avx512.mask.psra.q.256" => "__builtin_ia32_psraq256_mask", + "llvm.x86.avx512.mask.psra.qi.128" => "__builtin_ia32_psraqi128_mask", + "llvm.x86.avx512.mask.psra.qi.256" => "__builtin_ia32_psraqi256_mask", + "llvm.x86.avx512.mask.psra.qi.512" => "__builtin_ia32_psraqi512_mask", + "llvm.x86.avx512.mask.psra.w.128" => "__builtin_ia32_psraw128_mask", + "llvm.x86.avx512.mask.psra.w.256" => "__builtin_ia32_psraw256_mask", + "llvm.x86.avx512.mask.psra.w.512" => "__builtin_ia32_psraw512_mask", + "llvm.x86.avx512.mask.psra.wi.128" => "__builtin_ia32_psrawi128_mask", + "llvm.x86.avx512.mask.psra.wi.256" => "__builtin_ia32_psrawi256_mask", + "llvm.x86.avx512.mask.psra.wi.512" => "__builtin_ia32_psrawi512_mask", + "llvm.x86.avx512.mask.psrav.d" => "__builtin_ia32_psrav16si_mask", + "llvm.x86.avx512.mask.psrav.q" => "__builtin_ia32_psrav8di_mask", + "llvm.x86.avx512.mask.psrav.q.128" => "__builtin_ia32_psravq128_mask", + "llvm.x86.avx512.mask.psrav.q.256" => "__builtin_ia32_psravq256_mask", + "llvm.x86.avx512.mask.psrav16.hi" => "__builtin_ia32_psrav16hi_mask", + "llvm.x86.avx512.mask.psrav32.hi" => "__builtin_ia32_psrav32hi_mask", + "llvm.x86.avx512.mask.psrav4.si" => "__builtin_ia32_psrav4si_mask", + "llvm.x86.avx512.mask.psrav8.hi" => "__builtin_ia32_psrav8hi_mask", + "llvm.x86.avx512.mask.psrav8.si" => "__builtin_ia32_psrav8si_mask", + "llvm.x86.avx512.mask.psrl.d" => "__builtin_ia32_psrld512_mask", + "llvm.x86.avx512.mask.psrl.d.128" => "__builtin_ia32_psrld128_mask", + "llvm.x86.avx512.mask.psrl.d.256" => "__builtin_ia32_psrld256_mask", + "llvm.x86.avx512.mask.psrl.di.128" => "__builtin_ia32_psrldi128_mask", + "llvm.x86.avx512.mask.psrl.di.256" => "__builtin_ia32_psrldi256_mask", + "llvm.x86.avx512.mask.psrl.di.512" => "__builtin_ia32_psrldi512_mask", + "llvm.x86.avx512.mask.psrl.q" => "__builtin_ia32_psrlq512_mask", + "llvm.x86.avx512.mask.psrl.q.128" => "__builtin_ia32_psrlq128_mask", + "llvm.x86.avx512.mask.psrl.q.256" => "__builtin_ia32_psrlq256_mask", + "llvm.x86.avx512.mask.psrl.qi.128" => "__builtin_ia32_psrlqi128_mask", + "llvm.x86.avx512.mask.psrl.qi.256" => "__builtin_ia32_psrlqi256_mask", + "llvm.x86.avx512.mask.psrl.qi.512" => "__builtin_ia32_psrlqi512_mask", + "llvm.x86.avx512.mask.psrl.w.128" => "__builtin_ia32_psrlw128_mask", + "llvm.x86.avx512.mask.psrl.w.256" => "__builtin_ia32_psrlw256_mask", + "llvm.x86.avx512.mask.psrl.w.512" => "__builtin_ia32_psrlw512_mask", + "llvm.x86.avx512.mask.psrl.wi.128" => "__builtin_ia32_psrlwi128_mask", + "llvm.x86.avx512.mask.psrl.wi.256" => "__builtin_ia32_psrlwi256_mask", + "llvm.x86.avx512.mask.psrl.wi.512" => "__builtin_ia32_psrlwi512_mask", + "llvm.x86.avx512.mask.psrlv.d" => "__builtin_ia32_psrlv16si_mask", + "llvm.x86.avx512.mask.psrlv.q" => "__builtin_ia32_psrlv8di_mask", + "llvm.x86.avx512.mask.psrlv16.hi" => "__builtin_ia32_psrlv16hi_mask", + "llvm.x86.avx512.mask.psrlv2.di" => "__builtin_ia32_psrlv2di_mask", + "llvm.x86.avx512.mask.psrlv32hi" => "__builtin_ia32_psrlv32hi_mask", + "llvm.x86.avx512.mask.psrlv4.di" => "__builtin_ia32_psrlv4di_mask", + "llvm.x86.avx512.mask.psrlv4.si" => "__builtin_ia32_psrlv4si_mask", + "llvm.x86.avx512.mask.psrlv8.hi" => "__builtin_ia32_psrlv8hi_mask", + "llvm.x86.avx512.mask.psrlv8.si" => "__builtin_ia32_psrlv8si_mask", + "llvm.x86.avx512.mask.psub.b.128" => "__builtin_ia32_psubb128_mask", + "llvm.x86.avx512.mask.psub.b.256" => "__builtin_ia32_psubb256_mask", + "llvm.x86.avx512.mask.psub.b.512" => "__builtin_ia32_psubb512_mask", + "llvm.x86.avx512.mask.psub.d.128" => "__builtin_ia32_psubd128_mask", + "llvm.x86.avx512.mask.psub.d.256" => "__builtin_ia32_psubd256_mask", + "llvm.x86.avx512.mask.psub.d.512" => "__builtin_ia32_psubd512_mask", + "llvm.x86.avx512.mask.psub.q.128" => "__builtin_ia32_psubq128_mask", + "llvm.x86.avx512.mask.psub.q.256" => "__builtin_ia32_psubq256_mask", + "llvm.x86.avx512.mask.psub.q.512" => "__builtin_ia32_psubq512_mask", + "llvm.x86.avx512.mask.psub.w.128" => "__builtin_ia32_psubw128_mask", + "llvm.x86.avx512.mask.psub.w.256" => "__builtin_ia32_psubw256_mask", + "llvm.x86.avx512.mask.psub.w.512" => "__builtin_ia32_psubw512_mask", + "llvm.x86.avx512.mask.psubs.b.128" => "__builtin_ia32_psubsb128_mask", + "llvm.x86.avx512.mask.psubs.b.256" => "__builtin_ia32_psubsb256_mask", + "llvm.x86.avx512.mask.psubs.b.512" => "__builtin_ia32_psubsb512_mask", + "llvm.x86.avx512.mask.psubs.w.128" => "__builtin_ia32_psubsw128_mask", + "llvm.x86.avx512.mask.psubs.w.256" => "__builtin_ia32_psubsw256_mask", + "llvm.x86.avx512.mask.psubs.w.512" => "__builtin_ia32_psubsw512_mask", + "llvm.x86.avx512.mask.psubus.b.128" => "__builtin_ia32_psubusb128_mask", + "llvm.x86.avx512.mask.psubus.b.256" => "__builtin_ia32_psubusb256_mask", + "llvm.x86.avx512.mask.psubus.b.512" => "__builtin_ia32_psubusb512_mask", + "llvm.x86.avx512.mask.psubus.w.128" => "__builtin_ia32_psubusw128_mask", + "llvm.x86.avx512.mask.psubus.w.256" => "__builtin_ia32_psubusw256_mask", + "llvm.x86.avx512.mask.psubus.w.512" => "__builtin_ia32_psubusw512_mask", + "llvm.x86.avx512.mask.pternlog.d.128" => "__builtin_ia32_pternlogd128_mask", + "llvm.x86.avx512.mask.pternlog.d.256" => "__builtin_ia32_pternlogd256_mask", + "llvm.x86.avx512.mask.pternlog.d.512" => "__builtin_ia32_pternlogd512_mask", + "llvm.x86.avx512.mask.pternlog.q.128" => "__builtin_ia32_pternlogq128_mask", + "llvm.x86.avx512.mask.pternlog.q.256" => "__builtin_ia32_pternlogq256_mask", + "llvm.x86.avx512.mask.pternlog.q.512" => "__builtin_ia32_pternlogq512_mask", + "llvm.x86.avx512.mask.ptestm.d.512" => "__builtin_ia32_ptestmd512", + "llvm.x86.avx512.mask.ptestm.q.512" => "__builtin_ia32_ptestmq512", + "llvm.x86.avx512.mask.range.pd.128" => "__builtin_ia32_rangepd128_mask", + "llvm.x86.avx512.mask.range.pd.256" => "__builtin_ia32_rangepd256_mask", + "llvm.x86.avx512.mask.range.pd.512" => "__builtin_ia32_rangepd512_mask", + "llvm.x86.avx512.mask.range.ps.128" => "__builtin_ia32_rangeps128_mask", + "llvm.x86.avx512.mask.range.ps.256" => "__builtin_ia32_rangeps256_mask", + "llvm.x86.avx512.mask.range.ps.512" => "__builtin_ia32_rangeps512_mask", + "llvm.x86.avx512.mask.range.sd" => "__builtin_ia32_rangesd128_round_mask", + "llvm.x86.avx512.mask.range.ss" => "__builtin_ia32_rangess128_round_mask", + "llvm.x86.avx512.mask.reduce.pd.128" => "__builtin_ia32_reducepd128_mask", + "llvm.x86.avx512.mask.reduce.pd.256" => "__builtin_ia32_reducepd256_mask", + "llvm.x86.avx512.mask.reduce.pd.512" => "__builtin_ia32_reducepd512_mask", + "llvm.x86.avx512.mask.reduce.ps.128" => "__builtin_ia32_reduceps128_mask", + "llvm.x86.avx512.mask.reduce.ps.256" => "__builtin_ia32_reduceps256_mask", + "llvm.x86.avx512.mask.reduce.ps.512" => "__builtin_ia32_reduceps512_mask", + "llvm.x86.avx512.mask.reduce.sd" => "__builtin_ia32_reducesd_mask", + "llvm.x86.avx512.mask.reduce.ss" => "__builtin_ia32_reducess_mask", + "llvm.x86.avx512.mask.rndscale.pd.128" => "__builtin_ia32_rndscalepd_128_mask", + "llvm.x86.avx512.mask.rndscale.pd.256" => "__builtin_ia32_rndscalepd_256_mask", + "llvm.x86.avx512.mask.rndscale.pd.512" => "__builtin_ia32_rndscalepd_mask", + "llvm.x86.avx512.mask.rndscale.ps.128" => "__builtin_ia32_rndscaleps_128_mask", + "llvm.x86.avx512.mask.rndscale.ps.256" => "__builtin_ia32_rndscaleps_256_mask", + "llvm.x86.avx512.mask.rndscale.ps.512" => "__builtin_ia32_rndscaleps_mask", + "llvm.x86.avx512.mask.rndscale.sd" => "__builtin_ia32_rndscalesd_round_mask", + "llvm.x86.avx512.mask.rndscale.ss" => "__builtin_ia32_rndscaless_round_mask", + "llvm.x86.avx512.mask.scalef.pd.128" => "__builtin_ia32_scalefpd128_mask", + "llvm.x86.avx512.mask.scalef.pd.256" => "__builtin_ia32_scalefpd256_mask", + "llvm.x86.avx512.mask.scalef.pd.512" => "__builtin_ia32_scalefpd512_mask", + "llvm.x86.avx512.mask.scalef.ps.128" => "__builtin_ia32_scalefps128_mask", + "llvm.x86.avx512.mask.scalef.ps.256" => "__builtin_ia32_scalefps256_mask", + "llvm.x86.avx512.mask.scalef.ps.512" => "__builtin_ia32_scalefps512_mask", + "llvm.x86.avx512.mask.scalef.sd" => "__builtin_ia32_scalefsd_round_mask", + "llvm.x86.avx512.mask.scalef.ss" => "__builtin_ia32_scalefss_round_mask", + "llvm.x86.avx512.mask.shuf.f32x4" => "__builtin_ia32_shuf_f32x4_mask", + "llvm.x86.avx512.mask.shuf.f32x4.256" => "__builtin_ia32_shuf_f32x4_256_mask", + "llvm.x86.avx512.mask.shuf.f64x2" => "__builtin_ia32_shuf_f64x2_mask", + "llvm.x86.avx512.mask.shuf.f64x2.256" => "__builtin_ia32_shuf_f64x2_256_mask", + "llvm.x86.avx512.mask.shuf.i32x4" => "__builtin_ia32_shuf_i32x4_mask", + "llvm.x86.avx512.mask.shuf.i32x4.256" => "__builtin_ia32_shuf_i32x4_256_mask", + "llvm.x86.avx512.mask.shuf.i64x2" => "__builtin_ia32_shuf_i64x2_mask", + "llvm.x86.avx512.mask.shuf.i64x2.256" => "__builtin_ia32_shuf_i64x2_256_mask", + "llvm.x86.avx512.mask.shuf.pd.128" => "__builtin_ia32_shufpd128_mask", + "llvm.x86.avx512.mask.shuf.pd.256" => "__builtin_ia32_shufpd256_mask", + "llvm.x86.avx512.mask.shuf.pd.512" => "__builtin_ia32_shufpd512_mask", + "llvm.x86.avx512.mask.shuf.ps.128" => "__builtin_ia32_shufps128_mask", + "llvm.x86.avx512.mask.shuf.ps.256" => "__builtin_ia32_shufps256_mask", + "llvm.x86.avx512.mask.shuf.ps.512" => "__builtin_ia32_shufps512_mask", + "llvm.x86.avx512.mask.sqrt.pd.128" => "__builtin_ia32_sqrtpd128_mask", + "llvm.x86.avx512.mask.sqrt.pd.256" => "__builtin_ia32_sqrtpd256_mask", + "llvm.x86.avx512.mask.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", + "llvm.x86.avx512.mask.sqrt.ps.128" => "__builtin_ia32_sqrtps128_mask", + "llvm.x86.avx512.mask.sqrt.ps.256" => "__builtin_ia32_sqrtps256_mask", + "llvm.x86.avx512.mask.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", + "llvm.x86.avx512.mask.sqrt.sd" => "__builtin_ia32_sqrtsd_round_mask", + "llvm.x86.avx512.mask.sqrt.ss" => "__builtin_ia32_sqrtss_round_mask", + "llvm.x86.avx512.mask.store.ss" => "__builtin_ia32_storess_mask", + "llvm.x86.avx512.mask.storeu.d.512" => "__builtin_ia32_storedqusi512_mask", + "llvm.x86.avx512.mask.storeu.pd.512" => "__builtin_ia32_storeupd512_mask", + "llvm.x86.avx512.mask.storeu.ps.512" => "__builtin_ia32_storeups512_mask", + "llvm.x86.avx512.mask.storeu.q.512" => "__builtin_ia32_storedqudi512_mask", + "llvm.x86.avx512.mask.sub.pd.128" => "__builtin_ia32_subpd128_mask", + "llvm.x86.avx512.mask.sub.pd.256" => "__builtin_ia32_subpd256_mask", + "llvm.x86.avx512.mask.sub.pd.512" => "__builtin_ia32_subpd512_mask", + "llvm.x86.avx512.mask.sub.ps.128" => "__builtin_ia32_subps128_mask", + "llvm.x86.avx512.mask.sub.ps.256" => "__builtin_ia32_subps256_mask", + "llvm.x86.avx512.mask.sub.ps.512" => "__builtin_ia32_subps512_mask", + "llvm.x86.avx512.mask.sub.sd.round" => "__builtin_ia32_subsd_round_mask", + "llvm.x86.avx512.mask.sub.ss.round" => "__builtin_ia32_subss_round_mask", + "llvm.x86.avx512.mask.valign.d.128" => "__builtin_ia32_alignd128_mask", + "llvm.x86.avx512.mask.valign.d.256" => "__builtin_ia32_alignd256_mask", + "llvm.x86.avx512.mask.valign.d.512" => "__builtin_ia32_alignd512_mask", + "llvm.x86.avx512.mask.valign.q.128" => "__builtin_ia32_alignq128_mask", + "llvm.x86.avx512.mask.valign.q.256" => "__builtin_ia32_alignq256_mask", + "llvm.x86.avx512.mask.valign.q.512" => "__builtin_ia32_alignq512_mask", + "llvm.x86.avx512.mask.vcvtph2ps.128" => "__builtin_ia32_vcvtph2ps_mask", + "llvm.x86.avx512.mask.vcvtph2ps.256" => "__builtin_ia32_vcvtph2ps256_mask", + "llvm.x86.avx512.mask.vcvtph2ps.512" => "__builtin_ia32_vcvtph2ps512_mask", + "llvm.x86.avx512.mask.vcvtps2ph.128" => "__builtin_ia32_vcvtps2ph_mask", + "llvm.x86.avx512.mask.vcvtps2ph.256" => "__builtin_ia32_vcvtps2ph256_mask", + "llvm.x86.avx512.mask.vcvtps2ph.512" => "__builtin_ia32_vcvtps2ph512_mask", + "llvm.x86.avx512.mask.vextractf32x4.256" => "__builtin_ia32_extractf32x4_256_mask", + "llvm.x86.avx512.mask.vextractf32x4.512" => "__builtin_ia32_extractf32x4_mask", + "llvm.x86.avx512.mask.vextractf32x8.512" => "__builtin_ia32_extractf32x8_mask", + "llvm.x86.avx512.mask.vextractf64x2.256" => "__builtin_ia32_extractf64x2_256_mask", + "llvm.x86.avx512.mask.vextractf64x2.512" => "__builtin_ia32_extractf64x2_512_mask", + "llvm.x86.avx512.mask.vextractf64x4.512" => "__builtin_ia32_extractf64x4_mask", + "llvm.x86.avx512.mask.vextracti32x4.256" => "__builtin_ia32_extracti32x4_256_mask", + "llvm.x86.avx512.mask.vextracti32x4.512" => "__builtin_ia32_extracti32x4_mask", + "llvm.x86.avx512.mask.vextracti32x8.512" => "__builtin_ia32_extracti32x8_mask", + "llvm.x86.avx512.mask.vextracti64x2.256" => "__builtin_ia32_extracti64x2_256_mask", + "llvm.x86.avx512.mask.vextracti64x2.512" => "__builtin_ia32_extracti64x2_512_mask", + "llvm.x86.avx512.mask.vextracti64x4.512" => "__builtin_ia32_extracti64x4_mask", + "llvm.x86.avx512.mask.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask", + "llvm.x86.avx512.mask.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask", + "llvm.x86.avx512.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", + "llvm.x86.avx512.mask.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask", + "llvm.x86.avx512.mask.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask", + "llvm.x86.avx512.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", + "llvm.x86.avx512.mask.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask", + "llvm.x86.avx512.mask.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask", + "llvm.x86.avx512.mask.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask", + "llvm.x86.avx512.mask.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask", + "llvm.x86.avx512.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", + "llvm.x86.avx512.mask.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask", + "llvm.x86.avx512.mask.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask", + "llvm.x86.avx512.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", + "llvm.x86.avx512.mask.vfnmadd.pd.128" => "__builtin_ia32_vfnmaddpd128_mask", + "llvm.x86.avx512.mask.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256_mask", + "llvm.x86.avx512.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", + "llvm.x86.avx512.mask.vfnmadd.ps.128" => "__builtin_ia32_vfnmaddps128_mask", + "llvm.x86.avx512.mask.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256_mask", + "llvm.x86.avx512.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", + "llvm.x86.avx512.mask.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask", + "llvm.x86.avx512.mask.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask", + "llvm.x86.avx512.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", + "llvm.x86.avx512.mask.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask", + "llvm.x86.avx512.mask.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask", + "llvm.x86.avx512.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", + "llvm.x86.avx512.mask.vpermi2var.d.128" => "__builtin_ia32_vpermi2vard128_mask", + "llvm.x86.avx512.mask.vpermi2var.d.256" => "__builtin_ia32_vpermi2vard256_mask", + "llvm.x86.avx512.mask.vpermi2var.d.512" => "__builtin_ia32_vpermi2vard512_mask", + "llvm.x86.avx512.mask.vpermi2var.hi.128" => "__builtin_ia32_vpermi2varhi128_mask", + "llvm.x86.avx512.mask.vpermi2var.hi.256" => "__builtin_ia32_vpermi2varhi256_mask", + "llvm.x86.avx512.mask.vpermi2var.hi.512" => "__builtin_ia32_vpermi2varhi512_mask", + "llvm.x86.avx512.mask.vpermi2var.pd.128" => "__builtin_ia32_vpermi2varpd128_mask", + "llvm.x86.avx512.mask.vpermi2var.pd.256" => "__builtin_ia32_vpermi2varpd256_mask", + "llvm.x86.avx512.mask.vpermi2var.pd.512" => "__builtin_ia32_vpermi2varpd512_mask", + "llvm.x86.avx512.mask.vpermi2var.ps.128" => "__builtin_ia32_vpermi2varps128_mask", + "llvm.x86.avx512.mask.vpermi2var.ps.256" => "__builtin_ia32_vpermi2varps256_mask", + "llvm.x86.avx512.mask.vpermi2var.ps.512" => "__builtin_ia32_vpermi2varps512_mask", + "llvm.x86.avx512.mask.vpermi2var.q.128" => "__builtin_ia32_vpermi2varq128_mask", + "llvm.x86.avx512.mask.vpermi2var.q.256" => "__builtin_ia32_vpermi2varq256_mask", + "llvm.x86.avx512.mask.vpermi2var.q.512" => "__builtin_ia32_vpermi2varq512_mask", + "llvm.x86.avx512.mask.vpermi2var.qi.128" => "__builtin_ia32_vpermi2varqi128_mask", + "llvm.x86.avx512.mask.vpermi2var.qi.256" => "__builtin_ia32_vpermi2varqi256_mask", + "llvm.x86.avx512.mask.vpermi2var.qi.512" => "__builtin_ia32_vpermi2varqi512_mask", + "llvm.x86.avx512.mask.vpermilvar.pd.128" => "__builtin_ia32_vpermilvarpd_mask", + "llvm.x86.avx512.mask.vpermilvar.pd.256" => "__builtin_ia32_vpermilvarpd256_mask", + "llvm.x86.avx512.mask.vpermilvar.pd.512" => "__builtin_ia32_vpermilvarpd512_mask", + "llvm.x86.avx512.mask.vpermilvar.ps.128" => "__builtin_ia32_vpermilvarps_mask", + "llvm.x86.avx512.mask.vpermilvar.ps.256" => "__builtin_ia32_vpermilvarps256_mask", + "llvm.x86.avx512.mask.vpermilvar.ps.512" => "__builtin_ia32_vpermilvarps512_mask", + "llvm.x86.avx512.mask.vpermt.d.512" => "__builtin_ia32_vpermt2vard512_mask", + "llvm.x86.avx512.mask.vpermt.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", + "llvm.x86.avx512.mask.vpermt.ps.512" => "__builtin_ia32_vpermt2varps512_mask", + "llvm.x86.avx512.mask.vpermt.q.512" => "__builtin_ia32_vpermt2varq512_mask", + "llvm.x86.avx512.mask.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_mask", + "llvm.x86.avx512.mask.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_mask", + "llvm.x86.avx512.mask.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_mask", + "llvm.x86.avx512.mask.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_mask", + "llvm.x86.avx512.mask.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_mask", + "llvm.x86.avx512.mask.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_mask", + "llvm.x86.avx512.mask.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_mask", + "llvm.x86.avx512.mask.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_mask", + "llvm.x86.avx512.mask.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", + "llvm.x86.avx512.mask.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_mask", + "llvm.x86.avx512.mask.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_mask", + "llvm.x86.avx512.mask.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_mask", + "llvm.x86.avx512.mask.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_mask", + "llvm.x86.avx512.mask.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_mask", + "llvm.x86.avx512.mask.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_mask", + "llvm.x86.avx512.mask.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_mask", + "llvm.x86.avx512.mask.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_mask", + "llvm.x86.avx512.mask.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_mask", + "llvm.x86.avx512.mask.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_mask", + "llvm.x86.avx512.mask.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_mask", + "llvm.x86.avx512.mask.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_mask", + "llvm.x86.avx512.mask.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_mask", + "llvm.x86.avx512.mask.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_mask", + "llvm.x86.avx512.mask.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_mask", + "llvm.x86.avx512.mask.xor.pd.128" => "__builtin_ia32_xorpd128_mask", + "llvm.x86.avx512.mask.xor.pd.256" => "__builtin_ia32_xorpd256_mask", + "llvm.x86.avx512.mask.xor.pd.512" => "__builtin_ia32_xorpd512_mask", + "llvm.x86.avx512.mask.xor.ps.128" => "__builtin_ia32_xorps128_mask", + "llvm.x86.avx512.mask.xor.ps.256" => "__builtin_ia32_xorps256_mask", + "llvm.x86.avx512.mask.xor.ps.512" => "__builtin_ia32_xorps512_mask", + "llvm.x86.avx512.mask3.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask3", + "llvm.x86.avx512.mask3.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask3", + "llvm.x86.avx512.mask3.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask3", + "llvm.x86.avx512.mask3.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask3", + "llvm.x86.avx512.mask3.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask3", + "llvm.x86.avx512.mask3.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask3", + "llvm.x86.avx512.mask3.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask3", + "llvm.x86.avx512.mask3.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask3", + "llvm.x86.avx512.mask3.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask3", + "llvm.x86.avx512.mask3.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask3", + "llvm.x86.avx512.mask3.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask3", + "llvm.x86.avx512.mask3.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask3", + "llvm.x86.avx512.mask3.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask3", + "llvm.x86.avx512.mask3.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask3", + "llvm.x86.avx512.mask3.vfmsub.pd.128" => "__builtin_ia32_vfmsubpd128_mask3", + "llvm.x86.avx512.mask3.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256_mask3", + "llvm.x86.avx512.mask3.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask3", + "llvm.x86.avx512.mask3.vfmsub.ps.128" => "__builtin_ia32_vfmsubps128_mask3", + "llvm.x86.avx512.mask3.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256_mask3", + "llvm.x86.avx512.mask3.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask3", + "llvm.x86.avx512.mask3.vfmsubadd.pd.128" => "__builtin_ia32_vfmsubaddpd128_mask3", + "llvm.x86.avx512.mask3.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256_mask3", + "llvm.x86.avx512.mask3.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask3", + "llvm.x86.avx512.mask3.vfmsubadd.ps.128" => "__builtin_ia32_vfmsubaddps128_mask3", + "llvm.x86.avx512.mask3.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256_mask3", + "llvm.x86.avx512.mask3.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask3", + "llvm.x86.avx512.mask3.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask3", + "llvm.x86.avx512.mask3.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask3", + "llvm.x86.avx512.mask3.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask3", + "llvm.x86.avx512.mask3.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask3", + "llvm.x86.avx512.mask3.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask3", + "llvm.x86.avx512.mask3.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask3", + "llvm.x86.avx512.maskz.fixupimm.pd.128" => "__builtin_ia32_fixupimmpd128_maskz", + "llvm.x86.avx512.maskz.fixupimm.pd.256" => "__builtin_ia32_fixupimmpd256_maskz", + "llvm.x86.avx512.maskz.fixupimm.pd.512" => "__builtin_ia32_fixupimmpd512_maskz", + "llvm.x86.avx512.maskz.fixupimm.ps.128" => "__builtin_ia32_fixupimmps128_maskz", + "llvm.x86.avx512.maskz.fixupimm.ps.256" => "__builtin_ia32_fixupimmps256_maskz", + "llvm.x86.avx512.maskz.fixupimm.ps.512" => "__builtin_ia32_fixupimmps512_maskz", + "llvm.x86.avx512.maskz.fixupimm.sd" => "__builtin_ia32_fixupimmsd_maskz", + "llvm.x86.avx512.maskz.fixupimm.ss" => "__builtin_ia32_fixupimmss_maskz", + "llvm.x86.avx512.maskz.pternlog.d.128" => "__builtin_ia32_pternlogd128_maskz", + "llvm.x86.avx512.maskz.pternlog.d.256" => "__builtin_ia32_pternlogd256_maskz", + "llvm.x86.avx512.maskz.pternlog.d.512" => "__builtin_ia32_pternlogd512_maskz", + "llvm.x86.avx512.maskz.pternlog.q.128" => "__builtin_ia32_pternlogq128_maskz", + "llvm.x86.avx512.maskz.pternlog.q.256" => "__builtin_ia32_pternlogq256_maskz", + "llvm.x86.avx512.maskz.pternlog.q.512" => "__builtin_ia32_pternlogq512_maskz", + "llvm.x86.avx512.maskz.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_maskz", + "llvm.x86.avx512.maskz.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_maskz", + "llvm.x86.avx512.maskz.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_maskz", + "llvm.x86.avx512.maskz.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_maskz", + "llvm.x86.avx512.maskz.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_maskz", + "llvm.x86.avx512.maskz.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_maskz", + "llvm.x86.avx512.maskz.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_maskz", + "llvm.x86.avx512.maskz.vfmadd.ss" => "__builtin_ia32_vfmaddss3_maskz", + "llvm.x86.avx512.maskz.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_maskz", + "llvm.x86.avx512.maskz.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_maskz", + "llvm.x86.avx512.maskz.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_maskz", + "llvm.x86.avx512.maskz.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_maskz", + "llvm.x86.avx512.maskz.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_maskz", + "llvm.x86.avx512.maskz.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_maskz", + "llvm.x86.avx512.maskz.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_maskz", + "llvm.x86.avx512.maskz.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_maskz", + "llvm.x86.avx512.maskz.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_maskz", + "llvm.x86.avx512.maskz.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_maskz", + "llvm.x86.avx512.maskz.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_maskz", + "llvm.x86.avx512.maskz.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_maskz", + "llvm.x86.avx512.maskz.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_maskz", + "llvm.x86.avx512.maskz.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_maskz", + "llvm.x86.avx512.maskz.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_maskz", + "llvm.x86.avx512.maskz.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_maskz", + "llvm.x86.avx512.maskz.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_maskz", + "llvm.x86.avx512.maskz.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_maskz", + "llvm.x86.avx512.maskz.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_maskz", + "llvm.x86.avx512.maskz.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_maskz", + "llvm.x86.avx512.maskz.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_maskz", + "llvm.x86.avx512.maskz.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_maskz", + "llvm.x86.avx512.maskz.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_maskz", + "llvm.x86.avx512.maskz.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_maskz", + "llvm.x86.avx512.maskz.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_maskz", + "llvm.x86.avx512.maskz.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_maskz", + "llvm.x86.avx512.maskz.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_maskz", + "llvm.x86.avx512.maskz.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_maskz", + "llvm.x86.avx512.maskz.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_maskz", + "llvm.x86.avx512.maskz.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_maskz", + "llvm.x86.avx512.max.pd.512" => "__builtin_ia32_maxpd512", + "llvm.x86.avx512.max.ps.512" => "__builtin_ia32_maxps512", + "llvm.x86.avx512.min.pd.512" => "__builtin_ia32_minpd512", + "llvm.x86.avx512.min.ps.512" => "__builtin_ia32_minps512", + "llvm.x86.avx512.movntdqa" => "__builtin_ia32_movntdqa512", + "llvm.x86.avx512.mul.pd.512" => "__builtin_ia32_mulpd512", + "llvm.x86.avx512.mul.ps.512" => "__builtin_ia32_mulps512", + "llvm.x86.avx512.packssdw.512" => "__builtin_ia32_packssdw512", + "llvm.x86.avx512.packsswb.512" => "__builtin_ia32_packsswb512", + "llvm.x86.avx512.packusdw.512" => "__builtin_ia32_packusdw512", + "llvm.x86.avx512.packuswb.512" => "__builtin_ia32_packuswb512", + "llvm.x86.avx512.pavg.b.512" => "__builtin_ia32_pavgb512", + "llvm.x86.avx512.pavg.w.512" => "__builtin_ia32_pavgw512", + "llvm.x86.avx512.pbroadcastd.512" => "__builtin_ia32_pbroadcastd512", + "llvm.x86.avx512.pbroadcastq.512" => "__builtin_ia32_pbroadcastq512", + "llvm.x86.avx512.permvar.df.256" => "__builtin_ia32_permvardf256", + "llvm.x86.avx512.permvar.df.512" => "__builtin_ia32_permvardf512", + "llvm.x86.avx512.permvar.di.256" => "__builtin_ia32_permvardi256", + "llvm.x86.avx512.permvar.di.512" => "__builtin_ia32_permvardi512", + "llvm.x86.avx512.permvar.hi.128" => "__builtin_ia32_permvarhi128", + "llvm.x86.avx512.permvar.hi.256" => "__builtin_ia32_permvarhi256", + "llvm.x86.avx512.permvar.hi.512" => "__builtin_ia32_permvarhi512", + "llvm.x86.avx512.permvar.qi.128" => "__builtin_ia32_permvarqi128", + "llvm.x86.avx512.permvar.qi.256" => "__builtin_ia32_permvarqi256", + "llvm.x86.avx512.permvar.qi.512" => "__builtin_ia32_permvarqi512", + "llvm.x86.avx512.permvar.sf.512" => "__builtin_ia32_permvarsf512", + "llvm.x86.avx512.permvar.si.512" => "__builtin_ia32_permvarsi512", + "llvm.x86.avx512.pmaddubs.w.512" => "__builtin_ia32_pmaddubsw512", + "llvm.x86.avx512.pmaddw.d.512" => "__builtin_ia32_pmaddwd512", + "llvm.x86.avx512.pmovzxbd" => "__builtin_ia32_pmovzxbd512", + "llvm.x86.avx512.pmovzxbq" => "__builtin_ia32_pmovzxbq512", + "llvm.x86.avx512.pmovzxdq" => "__builtin_ia32_pmovzxdq512", + "llvm.x86.avx512.pmovzxwd" => "__builtin_ia32_pmovzxwd512", + "llvm.x86.avx512.pmovzxwq" => "__builtin_ia32_pmovzxwq512", + "llvm.x86.avx512.pmul.hr.sw.512" => "__builtin_ia32_pmulhrsw512", + "llvm.x86.avx512.pmulh.w.512" => "__builtin_ia32_pmulhw512", + "llvm.x86.avx512.pmulhu.w.512" => "__builtin_ia32_pmulhuw512", + "llvm.x86.avx512.pmultishift.qb.128" => "__builtin_ia32_vpmultishiftqb128", + "llvm.x86.avx512.pmultishift.qb.256" => "__builtin_ia32_vpmultishiftqb256", + "llvm.x86.avx512.pmultishift.qb.512" => "__builtin_ia32_vpmultishiftqb512", + "llvm.x86.avx512.psad.bw.512" => "__builtin_ia32_psadbw512", + "llvm.x86.avx512.pshuf.b.512" => "__builtin_ia32_pshufb512", + "llvm.x86.avx512.psll.d.512" => "__builtin_ia32_pslld512", + "llvm.x86.avx512.psll.dq" => "__builtin_ia32_pslldqi512", + "llvm.x86.avx512.psll.dq.bs" => "__builtin_ia32_pslldqi512_byteshift", + "llvm.x86.avx512.psll.q.512" => "__builtin_ia32_psllq512", + "llvm.x86.avx512.psll.w.512" => "__builtin_ia32_psllw512", + "llvm.x86.avx512.pslli.d.512" => "__builtin_ia32_pslldi512", + "llvm.x86.avx512.pslli.q.512" => "__builtin_ia32_psllqi512", + "llvm.x86.avx512.pslli.w.512" => "__builtin_ia32_psllwi512", + "llvm.x86.avx512.psllv.d.512" => "__builtin_ia32_psllv16si", + "llvm.x86.avx512.psllv.q.512" => "__builtin_ia32_psllv8di", + "llvm.x86.avx512.psllv.w.128" => "__builtin_ia32_psllv8hi", + "llvm.x86.avx512.psllv.w.256" => "__builtin_ia32_psllv16hi", + "llvm.x86.avx512.psllv.w.512" => "__builtin_ia32_psllv32hi", + "llvm.x86.avx512.psra.d.512" => "__builtin_ia32_psrad512", + "llvm.x86.avx512.psra.q.128" => "__builtin_ia32_psraq128", + "llvm.x86.avx512.psra.q.256" => "__builtin_ia32_psraq256", + "llvm.x86.avx512.psra.q.512" => "__builtin_ia32_psraq512", + "llvm.x86.avx512.psra.w.512" => "__builtin_ia32_psraw512", + "llvm.x86.avx512.psrai.d.512" => "__builtin_ia32_psradi512", + "llvm.x86.avx512.psrai.q.128" => "__builtin_ia32_psraqi128", + "llvm.x86.avx512.psrai.q.256" => "__builtin_ia32_psraqi256", + "llvm.x86.avx512.psrai.q.512" => "__builtin_ia32_psraqi512", + "llvm.x86.avx512.psrai.w.512" => "__builtin_ia32_psrawi512", + "llvm.x86.avx512.psrav.d.512" => "__builtin_ia32_psrav16si", + "llvm.x86.avx512.psrav.q.128" => "__builtin_ia32_psravq128", + "llvm.x86.avx512.psrav.q.256" => "__builtin_ia32_psravq256", + "llvm.x86.avx512.psrav.q.512" => "__builtin_ia32_psrav8di", + "llvm.x86.avx512.psrav.w.128" => "__builtin_ia32_psrav8hi", + "llvm.x86.avx512.psrav.w.256" => "__builtin_ia32_psrav16hi", + "llvm.x86.avx512.psrav.w.512" => "__builtin_ia32_psrav32hi", + "llvm.x86.avx512.psrl.d.512" => "__builtin_ia32_psrld512", + "llvm.x86.avx512.psrl.dq" => "__builtin_ia32_psrldqi512", + "llvm.x86.avx512.psrl.dq.bs" => "__builtin_ia32_psrldqi512_byteshift", + "llvm.x86.avx512.psrl.q.512" => "__builtin_ia32_psrlq512", + "llvm.x86.avx512.psrl.w.512" => "__builtin_ia32_psrlw512", + "llvm.x86.avx512.psrli.d.512" => "__builtin_ia32_psrldi512", + "llvm.x86.avx512.psrli.q.512" => "__builtin_ia32_psrlqi512", + "llvm.x86.avx512.psrli.w.512" => "__builtin_ia32_psrlwi512", + "llvm.x86.avx512.psrlv.d.512" => "__builtin_ia32_psrlv16si", + "llvm.x86.avx512.psrlv.q.512" => "__builtin_ia32_psrlv8di", + "llvm.x86.avx512.psrlv.w.128" => "__builtin_ia32_psrlv8hi", + "llvm.x86.avx512.psrlv.w.256" => "__builtin_ia32_psrlv16hi", + "llvm.x86.avx512.psrlv.w.512" => "__builtin_ia32_psrlv32hi", + "llvm.x86.avx512.pternlog.d.128" => "__builtin_ia32_pternlogd128", + "llvm.x86.avx512.pternlog.d.256" => "__builtin_ia32_pternlogd256", + "llvm.x86.avx512.pternlog.d.512" => "__builtin_ia32_pternlogd512", + "llvm.x86.avx512.pternlog.q.128" => "__builtin_ia32_pternlogq128", + "llvm.x86.avx512.pternlog.q.256" => "__builtin_ia32_pternlogq256", + "llvm.x86.avx512.pternlog.q.512" => "__builtin_ia32_pternlogq512", + "llvm.x86.avx512.ptestm.b.128" => "__builtin_ia32_ptestmb128", + "llvm.x86.avx512.ptestm.b.256" => "__builtin_ia32_ptestmb256", + "llvm.x86.avx512.ptestm.b.512" => "__builtin_ia32_ptestmb512", + "llvm.x86.avx512.ptestm.d.128" => "__builtin_ia32_ptestmd128", + "llvm.x86.avx512.ptestm.d.256" => "__builtin_ia32_ptestmd256", + "llvm.x86.avx512.ptestm.d.512" => "__builtin_ia32_ptestmd512", + "llvm.x86.avx512.ptestm.q.128" => "__builtin_ia32_ptestmq128", + "llvm.x86.avx512.ptestm.q.256" => "__builtin_ia32_ptestmq256", + "llvm.x86.avx512.ptestm.q.512" => "__builtin_ia32_ptestmq512", + "llvm.x86.avx512.ptestm.w.128" => "__builtin_ia32_ptestmw128", + "llvm.x86.avx512.ptestm.w.256" => "__builtin_ia32_ptestmw256", + "llvm.x86.avx512.ptestm.w.512" => "__builtin_ia32_ptestmw512", + "llvm.x86.avx512.ptestnm.b.128" => "__builtin_ia32_ptestnmb128", + "llvm.x86.avx512.ptestnm.b.256" => "__builtin_ia32_ptestnmb256", + "llvm.x86.avx512.ptestnm.b.512" => "__builtin_ia32_ptestnmb512", + "llvm.x86.avx512.ptestnm.d.128" => "__builtin_ia32_ptestnmd128", + "llvm.x86.avx512.ptestnm.d.256" => "__builtin_ia32_ptestnmd256", + "llvm.x86.avx512.ptestnm.d.512" => "__builtin_ia32_ptestnmd512", + "llvm.x86.avx512.ptestnm.q.128" => "__builtin_ia32_ptestnmq128", + "llvm.x86.avx512.ptestnm.q.256" => "__builtin_ia32_ptestnmq256", + "llvm.x86.avx512.ptestnm.q.512" => "__builtin_ia32_ptestnmq512", + "llvm.x86.avx512.ptestnm.w.128" => "__builtin_ia32_ptestnmw128", + "llvm.x86.avx512.ptestnm.w.256" => "__builtin_ia32_ptestnmw256", + "llvm.x86.avx512.ptestnm.w.512" => "__builtin_ia32_ptestnmw512", + "llvm.x86.avx512.rcp14.pd.128" => "__builtin_ia32_rcp14pd128_mask", + "llvm.x86.avx512.rcp14.pd.256" => "__builtin_ia32_rcp14pd256_mask", + "llvm.x86.avx512.rcp14.pd.512" => "__builtin_ia32_rcp14pd512_mask", + "llvm.x86.avx512.rcp14.ps.128" => "__builtin_ia32_rcp14ps128_mask", + "llvm.x86.avx512.rcp14.ps.256" => "__builtin_ia32_rcp14ps256_mask", + "llvm.x86.avx512.rcp14.ps.512" => "__builtin_ia32_rcp14ps512_mask", + "llvm.x86.avx512.rcp14.sd" => "__builtin_ia32_rcp14sd_mask", + "llvm.x86.avx512.rcp14.ss" => "__builtin_ia32_rcp14ss_mask", + "llvm.x86.avx512.rcp28.pd" => "__builtin_ia32_rcp28pd_mask", + "llvm.x86.avx512.rcp28.ps" => "__builtin_ia32_rcp28ps_mask", + "llvm.x86.avx512.rcp28.sd" => "__builtin_ia32_rcp28sd_round_mask", + // [DUPLICATE]: "llvm.x86.avx512.rcp28.sd" => "__builtin_ia32_rcp28sd_mask", + "llvm.x86.avx512.rcp28.ss" => "__builtin_ia32_rcp28ss_round_mask", + // [DUPLICATE]: "llvm.x86.avx512.rcp28.ss" => "__builtin_ia32_rcp28ss_mask", + "llvm.x86.avx512.rndscale.sd" => "__builtin_ia32_rndscalesd", + "llvm.x86.avx512.rndscale.ss" => "__builtin_ia32_rndscaless", + "llvm.x86.avx512.rsqrt14.pd.128" => "__builtin_ia32_rsqrt14pd128_mask", + "llvm.x86.avx512.rsqrt14.pd.256" => "__builtin_ia32_rsqrt14pd256_mask", + "llvm.x86.avx512.rsqrt14.pd.512" => "__builtin_ia32_rsqrt14pd512_mask", + "llvm.x86.avx512.rsqrt14.ps.128" => "__builtin_ia32_rsqrt14ps128_mask", + "llvm.x86.avx512.rsqrt14.ps.256" => "__builtin_ia32_rsqrt14ps256_mask", + "llvm.x86.avx512.rsqrt14.ps.512" => "__builtin_ia32_rsqrt14ps512_mask", + "llvm.x86.avx512.rsqrt14.sd" => "__builtin_ia32_rsqrt14sd_mask", + "llvm.x86.avx512.rsqrt14.ss" => "__builtin_ia32_rsqrt14ss_mask", + "llvm.x86.avx512.rsqrt28.pd" => "__builtin_ia32_rsqrt28pd_mask", + "llvm.x86.avx512.rsqrt28.ps" => "__builtin_ia32_rsqrt28ps_mask", + "llvm.x86.avx512.rsqrt28.sd" => "__builtin_ia32_rsqrt28sd_round_mask", + // [DUPLICATE]: "llvm.x86.avx512.rsqrt28.sd" => "__builtin_ia32_rsqrt28sd_mask", + "llvm.x86.avx512.rsqrt28.ss" => "__builtin_ia32_rsqrt28ss_round_mask", + // [DUPLICATE]: "llvm.x86.avx512.rsqrt28.ss" => "__builtin_ia32_rsqrt28ss_mask", + "llvm.x86.avx512.scatter.dpd.512" => "__builtin_ia32_scattersiv8df", + "llvm.x86.avx512.scatter.dpi.512" => "__builtin_ia32_scattersiv16si", + "llvm.x86.avx512.scatter.dpq.512" => "__builtin_ia32_scattersiv8di", + "llvm.x86.avx512.scatter.dps.512" => "__builtin_ia32_scattersiv16sf", + "llvm.x86.avx512.scatter.qpd.512" => "__builtin_ia32_scatterdiv8df", + "llvm.x86.avx512.scatter.qpi.512" => "__builtin_ia32_scatterdiv16si", + "llvm.x86.avx512.scatter.qpq.512" => "__builtin_ia32_scatterdiv8di", + "llvm.x86.avx512.scatter.qps.512" => "__builtin_ia32_scatterdiv16sf", + "llvm.x86.avx512.scatterdiv2.df" => "__builtin_ia32_scatterdiv2df", + "llvm.x86.avx512.scatterdiv2.di" => "__builtin_ia32_scatterdiv2di", + "llvm.x86.avx512.scatterdiv4.df" => "__builtin_ia32_scatterdiv4df", + "llvm.x86.avx512.scatterdiv4.di" => "__builtin_ia32_scatterdiv4di", + "llvm.x86.avx512.scatterdiv4.sf" => "__builtin_ia32_scatterdiv4sf", + "llvm.x86.avx512.scatterdiv4.si" => "__builtin_ia32_scatterdiv4si", + "llvm.x86.avx512.scatterdiv8.sf" => "__builtin_ia32_scatterdiv8sf", + "llvm.x86.avx512.scatterdiv8.si" => "__builtin_ia32_scatterdiv8si", + "llvm.x86.avx512.scatterpf.dpd.512" => "__builtin_ia32_scatterpfdpd", + "llvm.x86.avx512.scatterpf.dps.512" => "__builtin_ia32_scatterpfdps", + "llvm.x86.avx512.scatterpf.qpd.512" => "__builtin_ia32_scatterpfqpd", + "llvm.x86.avx512.scatterpf.qps.512" => "__builtin_ia32_scatterpfqps", + "llvm.x86.avx512.scattersiv2.df" => "__builtin_ia32_scattersiv2df", + "llvm.x86.avx512.scattersiv2.di" => "__builtin_ia32_scattersiv2di", + "llvm.x86.avx512.scattersiv4.df" => "__builtin_ia32_scattersiv4df", + "llvm.x86.avx512.scattersiv4.di" => "__builtin_ia32_scattersiv4di", + "llvm.x86.avx512.scattersiv4.sf" => "__builtin_ia32_scattersiv4sf", + "llvm.x86.avx512.scattersiv4.si" => "__builtin_ia32_scattersiv4si", + "llvm.x86.avx512.scattersiv8.sf" => "__builtin_ia32_scattersiv8sf", + "llvm.x86.avx512.scattersiv8.si" => "__builtin_ia32_scattersiv8si", + "llvm.x86.avx512.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", + "llvm.x86.avx512.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", + "llvm.x86.avx512.sqrt.sd" => "__builtin_ia32_sqrtrndsd", + "llvm.x86.avx512.sqrt.ss" => "__builtin_ia32_sqrtrndss", + "llvm.x86.avx512.sub.pd.512" => "__builtin_ia32_subpd512", + "llvm.x86.avx512.sub.ps.512" => "__builtin_ia32_subps512", + "llvm.x86.avx512.vbroadcast.sd.512" => "__builtin_ia32_vbroadcastsd512", + "llvm.x86.avx512.vbroadcast.sd.pd.512" => "__builtin_ia32_vbroadcastsd_pd512", + "llvm.x86.avx512.vbroadcast.ss.512" => "__builtin_ia32_vbroadcastss512", + "llvm.x86.avx512.vbroadcast.ss.ps.512" => "__builtin_ia32_vbroadcastss_ps512", + "llvm.x86.avx512.vcomi.sd" => "__builtin_ia32_vcomisd", + "llvm.x86.avx512.vcomi.ss" => "__builtin_ia32_vcomiss", + "llvm.x86.avx512.vcvtsd2si32" => "__builtin_ia32_vcvtsd2si32", + "llvm.x86.avx512.vcvtsd2si64" => "__builtin_ia32_vcvtsd2si64", + "llvm.x86.avx512.vcvtsd2usi32" => "__builtin_ia32_vcvtsd2usi32", + "llvm.x86.avx512.vcvtsd2usi64" => "__builtin_ia32_vcvtsd2usi64", + "llvm.x86.avx512.vcvtss2si32" => "__builtin_ia32_vcvtss2si32", + "llvm.x86.avx512.vcvtss2si64" => "__builtin_ia32_vcvtss2si64", + "llvm.x86.avx512.vcvtss2usi32" => "__builtin_ia32_vcvtss2usi32", + "llvm.x86.avx512.vcvtss2usi64" => "__builtin_ia32_vcvtss2usi64", + "llvm.x86.avx512.vpdpbusd.128" => "__builtin_ia32_vpdpbusd128", + "llvm.x86.avx512.vpdpbusd.256" => "__builtin_ia32_vpdpbusd256", + "llvm.x86.avx512.vpdpbusd.512" => "__builtin_ia32_vpdpbusd512", + "llvm.x86.avx512.vpdpbusds.128" => "__builtin_ia32_vpdpbusds128", + "llvm.x86.avx512.vpdpbusds.256" => "__builtin_ia32_vpdpbusds256", + "llvm.x86.avx512.vpdpbusds.512" => "__builtin_ia32_vpdpbusds512", + "llvm.x86.avx512.vpdpwssd.128" => "__builtin_ia32_vpdpwssd128", + "llvm.x86.avx512.vpdpwssd.256" => "__builtin_ia32_vpdpwssd256", + "llvm.x86.avx512.vpdpwssd.512" => "__builtin_ia32_vpdpwssd512", + "llvm.x86.avx512.vpdpwssds.128" => "__builtin_ia32_vpdpwssds128", + "llvm.x86.avx512.vpdpwssds.256" => "__builtin_ia32_vpdpwssds256", + "llvm.x86.avx512.vpdpwssds.512" => "__builtin_ia32_vpdpwssds512", + "llvm.x86.avx512.vpermi2var.d.128" => "__builtin_ia32_vpermi2vard128", + "llvm.x86.avx512.vpermi2var.d.256" => "__builtin_ia32_vpermi2vard256", + "llvm.x86.avx512.vpermi2var.d.512" => "__builtin_ia32_vpermi2vard512", + "llvm.x86.avx512.vpermi2var.hi.128" => "__builtin_ia32_vpermi2varhi128", + "llvm.x86.avx512.vpermi2var.hi.256" => "__builtin_ia32_vpermi2varhi256", + "llvm.x86.avx512.vpermi2var.hi.512" => "__builtin_ia32_vpermi2varhi512", + "llvm.x86.avx512.vpermi2var.pd.128" => "__builtin_ia32_vpermi2varpd128", + "llvm.x86.avx512.vpermi2var.pd.256" => "__builtin_ia32_vpermi2varpd256", + "llvm.x86.avx512.vpermi2var.pd.512" => "__builtin_ia32_vpermi2varpd512", + "llvm.x86.avx512.vpermi2var.ps.128" => "__builtin_ia32_vpermi2varps128", + "llvm.x86.avx512.vpermi2var.ps.256" => "__builtin_ia32_vpermi2varps256", + "llvm.x86.avx512.vpermi2var.ps.512" => "__builtin_ia32_vpermi2varps512", + "llvm.x86.avx512.vpermi2var.q.128" => "__builtin_ia32_vpermi2varq128", + "llvm.x86.avx512.vpermi2var.q.256" => "__builtin_ia32_vpermi2varq256", + "llvm.x86.avx512.vpermi2var.q.512" => "__builtin_ia32_vpermi2varq512", + "llvm.x86.avx512.vpermi2var.qi.128" => "__builtin_ia32_vpermi2varqi128", + "llvm.x86.avx512.vpermi2var.qi.256" => "__builtin_ia32_vpermi2varqi256", + "llvm.x86.avx512.vpermi2var.qi.512" => "__builtin_ia32_vpermi2varqi512", + "llvm.x86.avx512.vpermilvar.pd.512" => "__builtin_ia32_vpermilvarpd512", + "llvm.x86.avx512.vpermilvar.ps.512" => "__builtin_ia32_vpermilvarps512", + "llvm.x86.avx512.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128", + "llvm.x86.avx512.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256", + "llvm.x86.avx512.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512", + "llvm.x86.avx512.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128", + "llvm.x86.avx512.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256", + "llvm.x86.avx512.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512", + "llvm.x86.avx512bf16.cvtne2ps2bf16.128" => "__builtin_ia32_cvtne2ps2bf16_128", + "llvm.x86.avx512bf16.cvtne2ps2bf16.256" => "__builtin_ia32_cvtne2ps2bf16_256", + "llvm.x86.avx512bf16.cvtne2ps2bf16.512" => "__builtin_ia32_cvtne2ps2bf16_512", + "llvm.x86.avx512bf16.cvtneps2bf16.256" => "__builtin_ia32_cvtneps2bf16_256", + "llvm.x86.avx512bf16.cvtneps2bf16.512" => "__builtin_ia32_cvtneps2bf16_512", + "llvm.x86.avx512bf16.dpbf16ps.128" => "__builtin_ia32_dpbf16ps_128", + "llvm.x86.avx512bf16.dpbf16ps.256" => "__builtin_ia32_dpbf16ps_256", + "llvm.x86.avx512bf16.dpbf16ps.512" => "__builtin_ia32_dpbf16ps_512", + "llvm.x86.avx512fp16.add.ph.512" => "__builtin_ia32_addph512", + "llvm.x86.avx512fp16.div.ph.512" => "__builtin_ia32_divph512", + "llvm.x86.avx512fp16.mask.add.sh.round" => "__builtin_ia32_addsh_round_mask", + "llvm.x86.avx512fp16.mask.cmp.sh" => "__builtin_ia32_cmpsh_mask", + "llvm.x86.avx512fp16.mask.div.sh.round" => "__builtin_ia32_divsh_round_mask", + "llvm.x86.avx512fp16.mask.fpclass.sh" => "__builtin_ia32_fpclasssh_mask", + "llvm.x86.avx512fp16.mask.getexp.ph.128" => "__builtin_ia32_getexpph128_mask", + "llvm.x86.avx512fp16.mask.getexp.ph.256" => "__builtin_ia32_getexpph256_mask", + "llvm.x86.avx512fp16.mask.getexp.ph.512" => "__builtin_ia32_getexpph512_mask", + "llvm.x86.avx512fp16.mask.getexp.sh" => "__builtin_ia32_getexpsh128_round_mask", + "llvm.x86.avx512fp16.mask.getmant.ph.128" => "__builtin_ia32_getmantph128_mask", + "llvm.x86.avx512fp16.mask.getmant.ph.256" => "__builtin_ia32_getmantph256_mask", + "llvm.x86.avx512fp16.mask.getmant.ph.512" => "__builtin_ia32_getmantph512_mask", + "llvm.x86.avx512fp16.mask.getmant.sh" => "__builtin_ia32_getmantsh_round_mask", + "llvm.x86.avx512fp16.mask.max.sh.round" => "__builtin_ia32_maxsh_round_mask", + "llvm.x86.avx512fp16.mask.min.sh.round" => "__builtin_ia32_minsh_round_mask", + "llvm.x86.avx512fp16.mask.mul.sh.round" => "__builtin_ia32_mulsh_round_mask", + "llvm.x86.avx512fp16.mask.rcp.ph.128" => "__builtin_ia32_rcpph128_mask", + "llvm.x86.avx512fp16.mask.rcp.ph.256" => "__builtin_ia32_rcpph256_mask", + "llvm.x86.avx512fp16.mask.rcp.ph.512" => "__builtin_ia32_rcpph512_mask", + "llvm.x86.avx512fp16.mask.rcp.sh" => "__builtin_ia32_rcpsh_mask", + "llvm.x86.avx512fp16.mask.reduce.ph.128" => "__builtin_ia32_reduceph128_mask", + "llvm.x86.avx512fp16.mask.reduce.ph.256" => "__builtin_ia32_reduceph256_mask", + "llvm.x86.avx512fp16.mask.reduce.ph.512" => "__builtin_ia32_reduceph512_mask", + "llvm.x86.avx512fp16.mask.reduce.sh" => "__builtin_ia32_reducesh_mask", + "llvm.x86.avx512fp16.mask.rndscale.ph.128" => "__builtin_ia32_rndscaleph_128_mask", + "llvm.x86.avx512fp16.mask.rndscale.ph.256" => "__builtin_ia32_rndscaleph_256_mask", + "llvm.x86.avx512fp16.mask.rndscale.ph.512" => "__builtin_ia32_rndscaleph_mask", + "llvm.x86.avx512fp16.mask.rndscale.sh" => "__builtin_ia32_rndscalesh_round_mask", + "llvm.x86.avx512fp16.mask.rsqrt.ph.128" => "__builtin_ia32_rsqrtph128_mask", + "llvm.x86.avx512fp16.mask.rsqrt.ph.256" => "__builtin_ia32_rsqrtph256_mask", + "llvm.x86.avx512fp16.mask.rsqrt.ph.512" => "__builtin_ia32_rsqrtph512_mask", + "llvm.x86.avx512fp16.mask.rsqrt.sh" => "__builtin_ia32_rsqrtsh_mask", + "llvm.x86.avx512fp16.mask.scalef.ph.128" => "__builtin_ia32_scalefph128_mask", + "llvm.x86.avx512fp16.mask.scalef.ph.256" => "__builtin_ia32_scalefph256_mask", + "llvm.x86.avx512fp16.mask.scalef.ph.512" => "__builtin_ia32_scalefph512_mask", + "llvm.x86.avx512fp16.mask.scalef.sh" => "__builtin_ia32_scalefsh_round_mask", + "llvm.x86.avx512fp16.mask.sub.sh.round" => "__builtin_ia32_subsh_round_mask", + "llvm.x86.avx512fp16.mask.vcvtdq2ph.128" => "__builtin_ia32_vcvtdq2ph128_mask", + "llvm.x86.avx512fp16.mask.vcvtpd2ph.128" => "__builtin_ia32_vcvtpd2ph128_mask", + "llvm.x86.avx512fp16.mask.vcvtpd2ph.256" => "__builtin_ia32_vcvtpd2ph256_mask", + "llvm.x86.avx512fp16.mask.vcvtpd2ph.512" => "__builtin_ia32_vcvtpd2ph512_mask", + "llvm.x86.avx512fp16.mask.vcvtph2dq.128" => "__builtin_ia32_vcvtph2dq128_mask", + "llvm.x86.avx512fp16.mask.vcvtph2dq.256" => "__builtin_ia32_vcvtph2dq256_mask", + "llvm.x86.avx512fp16.mask.vcvtph2dq.512" => "__builtin_ia32_vcvtph2dq512_mask", + "llvm.x86.avx512fp16.mask.vcvtph2pd.128" => "__builtin_ia32_vcvtph2pd128_mask", + "llvm.x86.avx512fp16.mask.vcvtph2pd.256" => "__builtin_ia32_vcvtph2pd256_mask", + "llvm.x86.avx512fp16.mask.vcvtph2pd.512" => "__builtin_ia32_vcvtph2pd512_mask", + "llvm.x86.avx512fp16.mask.vcvtph2psx.128" => "__builtin_ia32_vcvtph2psx128_mask", + "llvm.x86.avx512fp16.mask.vcvtph2psx.256" => "__builtin_ia32_vcvtph2psx256_mask", + "llvm.x86.avx512fp16.mask.vcvtph2psx.512" => "__builtin_ia32_vcvtph2psx512_mask", + "llvm.x86.avx512fp16.mask.vcvtph2qq.128" => "__builtin_ia32_vcvtph2qq128_mask", + "llvm.x86.avx512fp16.mask.vcvtph2qq.256" => "__builtin_ia32_vcvtph2qq256_mask", + "llvm.x86.avx512fp16.mask.vcvtph2qq.512" => "__builtin_ia32_vcvtph2qq512_mask", + "llvm.x86.avx512fp16.mask.vcvtph2udq.128" => "__builtin_ia32_vcvtph2udq128_mask", + "llvm.x86.avx512fp16.mask.vcvtph2udq.256" => "__builtin_ia32_vcvtph2udq256_mask", + "llvm.x86.avx512fp16.mask.vcvtph2udq.512" => "__builtin_ia32_vcvtph2udq512_mask", + "llvm.x86.avx512fp16.mask.vcvtph2uqq.128" => "__builtin_ia32_vcvtph2uqq128_mask", + "llvm.x86.avx512fp16.mask.vcvtph2uqq.256" => "__builtin_ia32_vcvtph2uqq256_mask", + "llvm.x86.avx512fp16.mask.vcvtph2uqq.512" => "__builtin_ia32_vcvtph2uqq512_mask", + "llvm.x86.avx512fp16.mask.vcvtph2uw.128" => "__builtin_ia32_vcvtph2uw128_mask", + "llvm.x86.avx512fp16.mask.vcvtph2uw.256" => "__builtin_ia32_vcvtph2uw256_mask", + "llvm.x86.avx512fp16.mask.vcvtph2uw.512" => "__builtin_ia32_vcvtph2uw512_mask", + "llvm.x86.avx512fp16.mask.vcvtph2w.128" => "__builtin_ia32_vcvtph2w128_mask", + "llvm.x86.avx512fp16.mask.vcvtph2w.256" => "__builtin_ia32_vcvtph2w256_mask", + "llvm.x86.avx512fp16.mask.vcvtph2w.512" => "__builtin_ia32_vcvtph2w512_mask", + "llvm.x86.avx512fp16.mask.vcvtps2phx.128" => "__builtin_ia32_vcvtps2phx128_mask", + "llvm.x86.avx512fp16.mask.vcvtps2phx.256" => "__builtin_ia32_vcvtps2phx256_mask", + "llvm.x86.avx512fp16.mask.vcvtps2phx.512" => "__builtin_ia32_vcvtps2phx512_mask", + "llvm.x86.avx512fp16.mask.vcvtqq2ph.128" => "__builtin_ia32_vcvtqq2ph128_mask", + "llvm.x86.avx512fp16.mask.vcvtqq2ph.256" => "__builtin_ia32_vcvtqq2ph256_mask", + "llvm.x86.avx512fp16.mask.vcvtsd2sh.round" => "__builtin_ia32_vcvtsd2sh_round_mask", + "llvm.x86.avx512fp16.mask.vcvtsh2sd.round" => "__builtin_ia32_vcvtsh2sd_round_mask", + "llvm.x86.avx512fp16.mask.vcvtsh2ss.round" => "__builtin_ia32_vcvtsh2ss_round_mask", + "llvm.x86.avx512fp16.mask.vcvtss2sh.round" => "__builtin_ia32_vcvtss2sh_round_mask", + "llvm.x86.avx512fp16.mask.vcvttph2dq.128" => "__builtin_ia32_vcvttph2dq128_mask", + "llvm.x86.avx512fp16.mask.vcvttph2dq.256" => "__builtin_ia32_vcvttph2dq256_mask", + "llvm.x86.avx512fp16.mask.vcvttph2dq.512" => "__builtin_ia32_vcvttph2dq512_mask", + "llvm.x86.avx512fp16.mask.vcvttph2qq.128" => "__builtin_ia32_vcvttph2qq128_mask", + "llvm.x86.avx512fp16.mask.vcvttph2qq.256" => "__builtin_ia32_vcvttph2qq256_mask", + "llvm.x86.avx512fp16.mask.vcvttph2qq.512" => "__builtin_ia32_vcvttph2qq512_mask", + "llvm.x86.avx512fp16.mask.vcvttph2udq.128" => "__builtin_ia32_vcvttph2udq128_mask", + "llvm.x86.avx512fp16.mask.vcvttph2udq.256" => "__builtin_ia32_vcvttph2udq256_mask", + "llvm.x86.avx512fp16.mask.vcvttph2udq.512" => "__builtin_ia32_vcvttph2udq512_mask", + "llvm.x86.avx512fp16.mask.vcvttph2uqq.128" => "__builtin_ia32_vcvttph2uqq128_mask", + "llvm.x86.avx512fp16.mask.vcvttph2uqq.256" => "__builtin_ia32_vcvttph2uqq256_mask", + "llvm.x86.avx512fp16.mask.vcvttph2uqq.512" => "__builtin_ia32_vcvttph2uqq512_mask", + "llvm.x86.avx512fp16.mask.vcvttph2uw.128" => "__builtin_ia32_vcvttph2uw128_mask", + "llvm.x86.avx512fp16.mask.vcvttph2uw.256" => "__builtin_ia32_vcvttph2uw256_mask", + "llvm.x86.avx512fp16.mask.vcvttph2uw.512" => "__builtin_ia32_vcvttph2uw512_mask", + "llvm.x86.avx512fp16.mask.vcvttph2w.128" => "__builtin_ia32_vcvttph2w128_mask", + "llvm.x86.avx512fp16.mask.vcvttph2w.256" => "__builtin_ia32_vcvttph2w256_mask", + "llvm.x86.avx512fp16.mask.vcvttph2w.512" => "__builtin_ia32_vcvttph2w512_mask", + "llvm.x86.avx512fp16.mask.vcvtudq2ph.128" => "__builtin_ia32_vcvtudq2ph128_mask", + "llvm.x86.avx512fp16.mask.vcvtuqq2ph.128" => "__builtin_ia32_vcvtuqq2ph128_mask", + "llvm.x86.avx512fp16.mask.vcvtuqq2ph.256" => "__builtin_ia32_vcvtuqq2ph256_mask", + "llvm.x86.avx512fp16.mask.vfcmadd.cph.128" => "__builtin_ia32_vfcmaddcph128_mask", + "llvm.x86.avx512fp16.mask.vfcmadd.cph.256" => "__builtin_ia32_vfcmaddcph256_mask", + "llvm.x86.avx512fp16.mask.vfcmadd.cph.512" => "__builtin_ia32_vfcmaddcph512_mask3", + "llvm.x86.avx512fp16.mask.vfcmadd.csh" => "__builtin_ia32_vfcmaddcsh_mask", + "llvm.x86.avx512fp16.mask.vfcmul.cph.128" => "__builtin_ia32_vfcmulcph128_mask", + "llvm.x86.avx512fp16.mask.vfcmul.cph.256" => "__builtin_ia32_vfcmulcph256_mask", + "llvm.x86.avx512fp16.mask.vfcmul.cph.512" => "__builtin_ia32_vfcmulcph512_mask", + "llvm.x86.avx512fp16.mask.vfcmul.csh" => "__builtin_ia32_vfcmulcsh_mask", + "llvm.x86.avx512fp16.mask.vfmadd.cph.128" => "__builtin_ia32_vfmaddcph128_mask", + "llvm.x86.avx512fp16.mask.vfmadd.cph.256" => "__builtin_ia32_vfmaddcph256_mask", + "llvm.x86.avx512fp16.mask.vfmadd.cph.512" => "__builtin_ia32_vfmaddcph512_mask3", + "llvm.x86.avx512fp16.mask.vfmadd.csh" => "__builtin_ia32_vfmaddcsh_mask", + "llvm.x86.avx512fp16.mask.vfmul.cph.128" => "__builtin_ia32_vfmulcph128_mask", + "llvm.x86.avx512fp16.mask.vfmul.cph.256" => "__builtin_ia32_vfmulcph256_mask", + "llvm.x86.avx512fp16.mask.vfmul.cph.512" => "__builtin_ia32_vfmulcph512_mask", + "llvm.x86.avx512fp16.mask.vfmul.csh" => "__builtin_ia32_vfmulcsh_mask", + "llvm.x86.avx512fp16.maskz.vfcmadd.cph.128" => "__builtin_ia32_vfcmaddcph128_maskz", + "llvm.x86.avx512fp16.maskz.vfcmadd.cph.256" => "__builtin_ia32_vfcmaddcph256_maskz", + "llvm.x86.avx512fp16.maskz.vfcmadd.cph.512" => "__builtin_ia32_vfcmaddcph512_maskz", + "llvm.x86.avx512fp16.maskz.vfcmadd.csh" => "__builtin_ia32_vfcmaddcsh_maskz", + "llvm.x86.avx512fp16.maskz.vfmadd.cph.128" => "__builtin_ia32_vfmaddcph128_maskz", + "llvm.x86.avx512fp16.maskz.vfmadd.cph.256" => "__builtin_ia32_vfmaddcph256_maskz", + "llvm.x86.avx512fp16.maskz.vfmadd.cph.512" => "__builtin_ia32_vfmaddcph512_maskz", + "llvm.x86.avx512fp16.maskz.vfmadd.csh" => "__builtin_ia32_vfmaddcsh_maskz", + "llvm.x86.avx512fp16.max.ph.128" => "__builtin_ia32_maxph128", + "llvm.x86.avx512fp16.max.ph.256" => "__builtin_ia32_maxph256", + "llvm.x86.avx512fp16.max.ph.512" => "__builtin_ia32_maxph512", + "llvm.x86.avx512fp16.min.ph.128" => "__builtin_ia32_minph128", + "llvm.x86.avx512fp16.min.ph.256" => "__builtin_ia32_minph256", + "llvm.x86.avx512fp16.min.ph.512" => "__builtin_ia32_minph512", + "llvm.x86.avx512fp16.mul.ph.512" => "__builtin_ia32_mulph512", + "llvm.x86.avx512fp16.sub.ph.512" => "__builtin_ia32_subph512", + "llvm.x86.avx512fp16.vcomi.sh" => "__builtin_ia32_vcomish", + "llvm.x86.avx512fp16.vcvtsh2si32" => "__builtin_ia32_vcvtsh2si32", + "llvm.x86.avx512fp16.vcvtsh2si64" => "__builtin_ia32_vcvtsh2si64", + "llvm.x86.avx512fp16.vcvtsh2usi32" => "__builtin_ia32_vcvtsh2usi32", + "llvm.x86.avx512fp16.vcvtsh2usi64" => "__builtin_ia32_vcvtsh2usi64", + "llvm.x86.avx512fp16.vcvtsi2sh" => "__builtin_ia32_vcvtsi2sh", + "llvm.x86.avx512fp16.vcvtsi642sh" => "__builtin_ia32_vcvtsi642sh", + "llvm.x86.avx512fp16.vcvttsh2si32" => "__builtin_ia32_vcvttsh2si32", + "llvm.x86.avx512fp16.vcvttsh2si64" => "__builtin_ia32_vcvttsh2si64", + "llvm.x86.avx512fp16.vcvttsh2usi32" => "__builtin_ia32_vcvttsh2usi32", + "llvm.x86.avx512fp16.vcvttsh2usi64" => "__builtin_ia32_vcvttsh2usi64", + "llvm.x86.avx512fp16.vcvtusi2sh" => "__builtin_ia32_vcvtusi2sh", + "llvm.x86.avx512fp16.vcvtusi642sh" => "__builtin_ia32_vcvtusi642sh", + "llvm.x86.avx512fp16.vfmaddsub.ph.128" => "__builtin_ia32_vfmaddsubph", + "llvm.x86.avx512fp16.vfmaddsub.ph.256" => "__builtin_ia32_vfmaddsubph256", + "llvm.x86.bmi.bextr.32" => "__builtin_ia32_bextr_u32", + "llvm.x86.bmi.bextr.64" => "__builtin_ia32_bextr_u64", + "llvm.x86.bmi.bzhi.32" => "__builtin_ia32_bzhi_si", + "llvm.x86.bmi.bzhi.64" => "__builtin_ia32_bzhi_di", + "llvm.x86.bmi.pdep.32" => "__builtin_ia32_pdep_si", + "llvm.x86.bmi.pdep.64" => "__builtin_ia32_pdep_di", + "llvm.x86.bmi.pext.32" => "__builtin_ia32_pext_si", + "llvm.x86.bmi.pext.64" => "__builtin_ia32_pext_di", + "llvm.x86.cldemote" => "__builtin_ia32_cldemote", + "llvm.x86.clflushopt" => "__builtin_ia32_clflushopt", + "llvm.x86.clrssbsy" => "__builtin_ia32_clrssbsy", + "llvm.x86.clui" => "__builtin_ia32_clui", + "llvm.x86.clwb" => "__builtin_ia32_clwb", + "llvm.x86.clzero" => "__builtin_ia32_clzero", + "llvm.x86.directstore32" => "__builtin_ia32_directstore_u32", + "llvm.x86.directstore64" => "__builtin_ia32_directstore_u64", + "llvm.x86.enqcmd" => "__builtin_ia32_enqcmd", + "llvm.x86.enqcmds" => "__builtin_ia32_enqcmds", + "llvm.x86.flags.read.u32" => "__builtin_ia32_readeflags_u32", + "llvm.x86.flags.read.u64" => "__builtin_ia32_readeflags_u64", + "llvm.x86.flags.write.u32" => "__builtin_ia32_writeeflags_u32", + "llvm.x86.flags.write.u64" => "__builtin_ia32_writeeflags_u64", + "llvm.x86.fma.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", + "llvm.x86.fma.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", + "llvm.x86.fma.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", + "llvm.x86.fma.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", + "llvm.x86.fma.mask.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask", + "llvm.x86.fma.mask.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask", + "llvm.x86.fma.mask.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask", + "llvm.x86.fma.mask.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask", + "llvm.x86.fma.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", + "llvm.x86.fma.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", + "llvm.x86.fma.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", + "llvm.x86.fma.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", + "llvm.x86.fma.vfmadd.pd" => "__builtin_ia32_vfmaddpd", + "llvm.x86.fma.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256", + "llvm.x86.fma.vfmadd.ps" => "__builtin_ia32_vfmaddps", + "llvm.x86.fma.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256", + "llvm.x86.fma.vfmadd.sd" => "__builtin_ia32_vfmaddsd", + "llvm.x86.fma.vfmadd.ss" => "__builtin_ia32_vfmaddss", + "llvm.x86.fma.vfmaddsub.pd" => "__builtin_ia32_vfmaddsubpd", + "llvm.x86.fma.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256", + "llvm.x86.fma.vfmaddsub.ps" => "__builtin_ia32_vfmaddsubps", + "llvm.x86.fma.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256", + "llvm.x86.fma.vfmsub.pd" => "__builtin_ia32_vfmsubpd", + "llvm.x86.fma.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256", + "llvm.x86.fma.vfmsub.ps" => "__builtin_ia32_vfmsubps", + "llvm.x86.fma.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256", + "llvm.x86.fma.vfmsub.sd" => "__builtin_ia32_vfmsubsd", + "llvm.x86.fma.vfmsub.ss" => "__builtin_ia32_vfmsubss", + "llvm.x86.fma.vfmsubadd.pd" => "__builtin_ia32_vfmsubaddpd", + "llvm.x86.fma.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256", + "llvm.x86.fma.vfmsubadd.ps" => "__builtin_ia32_vfmsubaddps", + "llvm.x86.fma.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256", + "llvm.x86.fma.vfnmadd.pd" => "__builtin_ia32_vfnmaddpd", + "llvm.x86.fma.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256", + "llvm.x86.fma.vfnmadd.ps" => "__builtin_ia32_vfnmaddps", + "llvm.x86.fma.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256", + "llvm.x86.fma.vfnmadd.sd" => "__builtin_ia32_vfnmaddsd", + "llvm.x86.fma.vfnmadd.ss" => "__builtin_ia32_vfnmaddss", + "llvm.x86.fma.vfnmsub.pd" => "__builtin_ia32_vfnmsubpd", + "llvm.x86.fma.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256", + "llvm.x86.fma.vfnmsub.ps" => "__builtin_ia32_vfnmsubps", + "llvm.x86.fma.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256", + "llvm.x86.fma.vfnmsub.sd" => "__builtin_ia32_vfnmsubsd", + "llvm.x86.fma.vfnmsub.ss" => "__builtin_ia32_vfnmsubss", + "llvm.x86.fxrstor" => "__builtin_ia32_fxrstor", + "llvm.x86.fxrstor64" => "__builtin_ia32_fxrstor64", + "llvm.x86.fxsave" => "__builtin_ia32_fxsave", + "llvm.x86.fxsave64" => "__builtin_ia32_fxsave64", + "llvm.x86.incsspd" => "__builtin_ia32_incsspd", + "llvm.x86.incsspq" => "__builtin_ia32_incsspq", + "llvm.x86.invpcid" => "__builtin_ia32_invpcid", + "llvm.x86.ldtilecfg" => "__builtin_ia32_tile_loadconfig", + "llvm.x86.ldtilecfg.internal" => "__builtin_ia32_tile_loadconfig_internal", + "llvm.x86.llwpcb" => "__builtin_ia32_llwpcb", + "llvm.x86.loadiwkey" => "__builtin_ia32_loadiwkey", + "llvm.x86.lwpins32" => "__builtin_ia32_lwpins32", + "llvm.x86.lwpins64" => "__builtin_ia32_lwpins64", + "llvm.x86.lwpval32" => "__builtin_ia32_lwpval32", + "llvm.x86.lwpval64" => "__builtin_ia32_lwpval64", + "llvm.x86.mmx.emms" => "__builtin_ia32_emms", + "llvm.x86.mmx.femms" => "__builtin_ia32_femms", + "llvm.x86.mmx.maskmovq" => "__builtin_ia32_maskmovq", + "llvm.x86.mmx.movnt.dq" => "__builtin_ia32_movntq", + "llvm.x86.mmx.packssdw" => "__builtin_ia32_packssdw", + "llvm.x86.mmx.packsswb" => "__builtin_ia32_packsswb", + "llvm.x86.mmx.packuswb" => "__builtin_ia32_packuswb", + "llvm.x86.mmx.padd.b" => "__builtin_ia32_paddb", + "llvm.x86.mmx.padd.d" => "__builtin_ia32_paddd", + "llvm.x86.mmx.padd.q" => "__builtin_ia32_paddq", + "llvm.x86.mmx.padd.w" => "__builtin_ia32_paddw", + "llvm.x86.mmx.padds.b" => "__builtin_ia32_paddsb", + "llvm.x86.mmx.padds.w" => "__builtin_ia32_paddsw", + "llvm.x86.mmx.paddus.b" => "__builtin_ia32_paddusb", + "llvm.x86.mmx.paddus.w" => "__builtin_ia32_paddusw", + "llvm.x86.mmx.palignr.b" => "__builtin_ia32_palignr", + "llvm.x86.mmx.pand" => "__builtin_ia32_pand", + "llvm.x86.mmx.pandn" => "__builtin_ia32_pandn", + "llvm.x86.mmx.pavg.b" => "__builtin_ia32_pavgb", + "llvm.x86.mmx.pavg.w" => "__builtin_ia32_pavgw", + "llvm.x86.mmx.pcmpeq.b" => "__builtin_ia32_pcmpeqb", + "llvm.x86.mmx.pcmpeq.d" => "__builtin_ia32_pcmpeqd", + "llvm.x86.mmx.pcmpeq.w" => "__builtin_ia32_pcmpeqw", + "llvm.x86.mmx.pcmpgt.b" => "__builtin_ia32_pcmpgtb", + "llvm.x86.mmx.pcmpgt.d" => "__builtin_ia32_pcmpgtd", + "llvm.x86.mmx.pcmpgt.w" => "__builtin_ia32_pcmpgtw", + "llvm.x86.mmx.pextr.w" => "__builtin_ia32_vec_ext_v4hi", + "llvm.x86.mmx.pinsr.w" => "__builtin_ia32_vec_set_v4hi", + "llvm.x86.mmx.pmadd.wd" => "__builtin_ia32_pmaddwd", + "llvm.x86.mmx.pmaxs.w" => "__builtin_ia32_pmaxsw", + "llvm.x86.mmx.pmaxu.b" => "__builtin_ia32_pmaxub", + "llvm.x86.mmx.pmins.w" => "__builtin_ia32_pminsw", + "llvm.x86.mmx.pminu.b" => "__builtin_ia32_pminub", + "llvm.x86.mmx.pmovmskb" => "__builtin_ia32_pmovmskb", + "llvm.x86.mmx.pmulh.w" => "__builtin_ia32_pmulhw", + "llvm.x86.mmx.pmulhu.w" => "__builtin_ia32_pmulhuw", + "llvm.x86.mmx.pmull.w" => "__builtin_ia32_pmullw", + "llvm.x86.mmx.pmulu.dq" => "__builtin_ia32_pmuludq", + "llvm.x86.mmx.por" => "__builtin_ia32_por", + "llvm.x86.mmx.psad.bw" => "__builtin_ia32_psadbw", + "llvm.x86.mmx.psll.d" => "__builtin_ia32_pslld", + "llvm.x86.mmx.psll.q" => "__builtin_ia32_psllq", + "llvm.x86.mmx.psll.w" => "__builtin_ia32_psllw", + "llvm.x86.mmx.pslli.d" => "__builtin_ia32_pslldi", + "llvm.x86.mmx.pslli.q" => "__builtin_ia32_psllqi", + "llvm.x86.mmx.pslli.w" => "__builtin_ia32_psllwi", + "llvm.x86.mmx.psra.d" => "__builtin_ia32_psrad", + "llvm.x86.mmx.psra.w" => "__builtin_ia32_psraw", + "llvm.x86.mmx.psrai.d" => "__builtin_ia32_psradi", + "llvm.x86.mmx.psrai.w" => "__builtin_ia32_psrawi", + "llvm.x86.mmx.psrl.d" => "__builtin_ia32_psrld", + "llvm.x86.mmx.psrl.q" => "__builtin_ia32_psrlq", + "llvm.x86.mmx.psrl.w" => "__builtin_ia32_psrlw", + "llvm.x86.mmx.psrli.d" => "__builtin_ia32_psrldi", + "llvm.x86.mmx.psrli.q" => "__builtin_ia32_psrlqi", + "llvm.x86.mmx.psrli.w" => "__builtin_ia32_psrlwi", + "llvm.x86.mmx.psub.b" => "__builtin_ia32_psubb", + "llvm.x86.mmx.psub.d" => "__builtin_ia32_psubd", + "llvm.x86.mmx.psub.q" => "__builtin_ia32_psubq", + "llvm.x86.mmx.psub.w" => "__builtin_ia32_psubw", + "llvm.x86.mmx.psubs.b" => "__builtin_ia32_psubsb", + "llvm.x86.mmx.psubs.w" => "__builtin_ia32_psubsw", + "llvm.x86.mmx.psubus.b" => "__builtin_ia32_psubusb", + "llvm.x86.mmx.psubus.w" => "__builtin_ia32_psubusw", + "llvm.x86.mmx.punpckhbw" => "__builtin_ia32_punpckhbw", + "llvm.x86.mmx.punpckhdq" => "__builtin_ia32_punpckhdq", + "llvm.x86.mmx.punpckhwd" => "__builtin_ia32_punpckhwd", + "llvm.x86.mmx.punpcklbw" => "__builtin_ia32_punpcklbw", + "llvm.x86.mmx.punpckldq" => "__builtin_ia32_punpckldq", + "llvm.x86.mmx.punpcklwd" => "__builtin_ia32_punpcklwd", + "llvm.x86.mmx.pxor" => "__builtin_ia32_pxor", + "llvm.x86.monitorx" => "__builtin_ia32_monitorx", + "llvm.x86.movdir64b" => "__builtin_ia32_movdir64b", + "llvm.x86.mwaitx" => "__builtin_ia32_mwaitx", + "llvm.x86.pclmulqdq" => "__builtin_ia32_pclmulqdq128", + "llvm.x86.pclmulqdq.256" => "__builtin_ia32_pclmulqdq256", + "llvm.x86.pclmulqdq.512" => "__builtin_ia32_pclmulqdq512", + "llvm.x86.ptwrite32" => "__builtin_ia32_ptwrite32", + "llvm.x86.ptwrite64" => "__builtin_ia32_ptwrite64", + "llvm.x86.rdfsbase.32" => "__builtin_ia32_rdfsbase32", + "llvm.x86.rdfsbase.64" => "__builtin_ia32_rdfsbase64", + "llvm.x86.rdgsbase.32" => "__builtin_ia32_rdgsbase32", + "llvm.x86.rdgsbase.64" => "__builtin_ia32_rdgsbase64", + "llvm.x86.rdpid" => "__builtin_ia32_rdpid", + "llvm.x86.rdpkru" => "__builtin_ia32_rdpkru", + "llvm.x86.rdpmc" => "__builtin_ia32_rdpmc", + "llvm.x86.rdsspd" => "__builtin_ia32_rdsspd", + "llvm.x86.rdsspq" => "__builtin_ia32_rdsspq", + "llvm.x86.rdtsc" => "__builtin_ia32_rdtsc", + "llvm.x86.rdtscp" => "__builtin_ia32_rdtscp", + "llvm.x86.rstorssp" => "__builtin_ia32_rstorssp", + "llvm.x86.saveprevssp" => "__builtin_ia32_saveprevssp", + "llvm.x86.senduipi" => "__builtin_ia32_senduipi", + "llvm.x86.serialize" => "__builtin_ia32_serialize", + "llvm.x86.setssbsy" => "__builtin_ia32_setssbsy", + "llvm.x86.sha1msg1" => "__builtin_ia32_sha1msg1", + "llvm.x86.sha1msg2" => "__builtin_ia32_sha1msg2", + "llvm.x86.sha1nexte" => "__builtin_ia32_sha1nexte", + "llvm.x86.sha1rnds4" => "__builtin_ia32_sha1rnds4", + "llvm.x86.sha256msg1" => "__builtin_ia32_sha256msg1", + "llvm.x86.sha256msg2" => "__builtin_ia32_sha256msg2", + "llvm.x86.sha256rnds2" => "__builtin_ia32_sha256rnds2", + "llvm.x86.slwpcb" => "__builtin_ia32_slwpcb", + "llvm.x86.sse.add.ss" => "__builtin_ia32_addss", + "llvm.x86.sse.cmp.ps" => "__builtin_ia32_cmpps", + "llvm.x86.sse.cmp.ss" => "__builtin_ia32_cmpss", + "llvm.x86.sse.comieq.ss" => "__builtin_ia32_comieq", + "llvm.x86.sse.comige.ss" => "__builtin_ia32_comige", + "llvm.x86.sse.comigt.ss" => "__builtin_ia32_comigt", + "llvm.x86.sse.comile.ss" => "__builtin_ia32_comile", + "llvm.x86.sse.comilt.ss" => "__builtin_ia32_comilt", + "llvm.x86.sse.comineq.ss" => "__builtin_ia32_comineq", + "llvm.x86.sse.cvtpd2pi" => "__builtin_ia32_cvtpd2pi", + "llvm.x86.sse.cvtpi2pd" => "__builtin_ia32_cvtpi2pd", + "llvm.x86.sse.cvtpi2ps" => "__builtin_ia32_cvtpi2ps", + "llvm.x86.sse.cvtps2pi" => "__builtin_ia32_cvtps2pi", + "llvm.x86.sse.cvtsi2ss" => "__builtin_ia32_cvtsi2ss", + "llvm.x86.sse.cvtsi642ss" => "__builtin_ia32_cvtsi642ss", + "llvm.x86.sse.cvtss2si" => "__builtin_ia32_cvtss2si", + "llvm.x86.sse.cvtss2si64" => "__builtin_ia32_cvtss2si64", + "llvm.x86.sse.cvttpd2pi" => "__builtin_ia32_cvttpd2pi", + "llvm.x86.sse.cvttps2pi" => "__builtin_ia32_cvttps2pi", + "llvm.x86.sse.cvttss2si" => "__builtin_ia32_cvttss2si", + "llvm.x86.sse.cvttss2si64" => "__builtin_ia32_cvttss2si64", + "llvm.x86.sse.div.ss" => "__builtin_ia32_divss", + "llvm.x86.sse.max.ps" => "__builtin_ia32_maxps", + "llvm.x86.sse.max.ss" => "__builtin_ia32_maxss", + "llvm.x86.sse.min.ps" => "__builtin_ia32_minps", + "llvm.x86.sse.min.ss" => "__builtin_ia32_minss", + "llvm.x86.sse.movmsk.ps" => "__builtin_ia32_movmskps", + "llvm.x86.sse.mul.ss" => "__builtin_ia32_mulss", + "llvm.x86.sse.pshuf.w" => "__builtin_ia32_pshufw", + "llvm.x86.sse.rcp.ps" => "__builtin_ia32_rcpps", + "llvm.x86.sse.rcp.ss" => "__builtin_ia32_rcpss", + "llvm.x86.sse.rsqrt.ps" => "__builtin_ia32_rsqrtps", + "llvm.x86.sse.rsqrt.ss" => "__builtin_ia32_rsqrtss", + "llvm.x86.sse.sfence" => "__builtin_ia32_sfence", + "llvm.x86.sse.sqrt.ps" => "__builtin_ia32_sqrtps", + "llvm.x86.sse.sqrt.ss" => "__builtin_ia32_sqrtss", + "llvm.x86.sse.storeu.ps" => "__builtin_ia32_storeups", + "llvm.x86.sse.sub.ss" => "__builtin_ia32_subss", + "llvm.x86.sse.ucomieq.ss" => "__builtin_ia32_ucomieq", + "llvm.x86.sse.ucomige.ss" => "__builtin_ia32_ucomige", + "llvm.x86.sse.ucomigt.ss" => "__builtin_ia32_ucomigt", + "llvm.x86.sse.ucomile.ss" => "__builtin_ia32_ucomile", + "llvm.x86.sse.ucomilt.ss" => "__builtin_ia32_ucomilt", + "llvm.x86.sse.ucomineq.ss" => "__builtin_ia32_ucomineq", + "llvm.x86.sse2.add.sd" => "__builtin_ia32_addsd", + "llvm.x86.sse2.clflush" => "__builtin_ia32_clflush", + "llvm.x86.sse2.cmp.pd" => "__builtin_ia32_cmppd", + "llvm.x86.sse2.cmp.sd" => "__builtin_ia32_cmpsd", + "llvm.x86.sse2.comieq.sd" => "__builtin_ia32_comisdeq", + "llvm.x86.sse2.comige.sd" => "__builtin_ia32_comisdge", + "llvm.x86.sse2.comigt.sd" => "__builtin_ia32_comisdgt", + "llvm.x86.sse2.comile.sd" => "__builtin_ia32_comisdle", + "llvm.x86.sse2.comilt.sd" => "__builtin_ia32_comisdlt", + "llvm.x86.sse2.comineq.sd" => "__builtin_ia32_comisdneq", + "llvm.x86.sse2.cvtdq2pd" => "__builtin_ia32_cvtdq2pd", + "llvm.x86.sse2.cvtdq2ps" => "__builtin_ia32_cvtdq2ps", + "llvm.x86.sse2.cvtpd2dq" => "__builtin_ia32_cvtpd2dq", + "llvm.x86.sse2.cvtpd2ps" => "__builtin_ia32_cvtpd2ps", + "llvm.x86.sse2.cvtps2dq" => "__builtin_ia32_cvtps2dq", + "llvm.x86.sse2.cvtps2pd" => "__builtin_ia32_cvtps2pd", + "llvm.x86.sse2.cvtsd2si" => "__builtin_ia32_cvtsd2si", + "llvm.x86.sse2.cvtsd2si64" => "__builtin_ia32_cvtsd2si64", + "llvm.x86.sse2.cvtsd2ss" => "__builtin_ia32_cvtsd2ss", + "llvm.x86.sse2.cvtsi2sd" => "__builtin_ia32_cvtsi2sd", + "llvm.x86.sse2.cvtsi642sd" => "__builtin_ia32_cvtsi642sd", + "llvm.x86.sse2.cvtss2sd" => "__builtin_ia32_cvtss2sd", + "llvm.x86.sse2.cvttpd2dq" => "__builtin_ia32_cvttpd2dq", + "llvm.x86.sse2.cvttps2dq" => "__builtin_ia32_cvttps2dq", + "llvm.x86.sse2.cvttsd2si" => "__builtin_ia32_cvttsd2si", + "llvm.x86.sse2.cvttsd2si64" => "__builtin_ia32_cvttsd2si64", + "llvm.x86.sse2.div.sd" => "__builtin_ia32_divsd", + "llvm.x86.sse2.lfence" => "__builtin_ia32_lfence", + "llvm.x86.sse2.maskmov.dqu" => "__builtin_ia32_maskmovdqu", + "llvm.x86.sse2.max.pd" => "__builtin_ia32_maxpd", + "llvm.x86.sse2.max.sd" => "__builtin_ia32_maxsd", + "llvm.x86.sse2.mfence" => "__builtin_ia32_mfence", + "llvm.x86.sse2.min.pd" => "__builtin_ia32_minpd", + "llvm.x86.sse2.min.sd" => "__builtin_ia32_minsd", + "llvm.x86.sse2.movmsk.pd" => "__builtin_ia32_movmskpd", + "llvm.x86.sse2.mul.sd" => "__builtin_ia32_mulsd", + "llvm.x86.sse2.packssdw.128" => "__builtin_ia32_packssdw128", + "llvm.x86.sse2.packsswb.128" => "__builtin_ia32_packsswb128", + "llvm.x86.sse2.packuswb.128" => "__builtin_ia32_packuswb128", + "llvm.x86.sse2.padds.b" => "__builtin_ia32_paddsb128", + "llvm.x86.sse2.padds.w" => "__builtin_ia32_paddsw128", + "llvm.x86.sse2.paddus.b" => "__builtin_ia32_paddusb128", + "llvm.x86.sse2.paddus.w" => "__builtin_ia32_paddusw128", + "llvm.x86.sse2.pause" => "__builtin_ia32_pause", + "llvm.x86.sse2.pavg.b" => "__builtin_ia32_pavgb128", + "llvm.x86.sse2.pavg.w" => "__builtin_ia32_pavgw128", + "llvm.x86.sse2.pmadd.wd" => "__builtin_ia32_pmaddwd128", + "llvm.x86.sse2.pmaxs.w" => "__builtin_ia32_pmaxsw128", + "llvm.x86.sse2.pmaxu.b" => "__builtin_ia32_pmaxub128", + "llvm.x86.sse2.pmins.w" => "__builtin_ia32_pminsw128", + "llvm.x86.sse2.pminu.b" => "__builtin_ia32_pminub128", + "llvm.x86.sse2.pmovmskb.128" => "__builtin_ia32_pmovmskb128", + "llvm.x86.sse2.pmulh.w" => "__builtin_ia32_pmulhw128", + "llvm.x86.sse2.pmulhu.w" => "__builtin_ia32_pmulhuw128", + "llvm.x86.sse2.pmulu.dq" => "__builtin_ia32_pmuludq128", + "llvm.x86.sse2.psad.bw" => "__builtin_ia32_psadbw128", + "llvm.x86.sse2.pshuf.d" => "__builtin_ia32_pshufd", + "llvm.x86.sse2.pshufh.w" => "__builtin_ia32_pshufhw", + "llvm.x86.sse2.pshufl.w" => "__builtin_ia32_pshuflw", + "llvm.x86.sse2.psll.d" => "__builtin_ia32_pslld128", + "llvm.x86.sse2.psll.dq" => "__builtin_ia32_pslldqi128", + "llvm.x86.sse2.psll.dq.bs" => "__builtin_ia32_pslldqi128_byteshift", + "llvm.x86.sse2.psll.q" => "__builtin_ia32_psllq128", + "llvm.x86.sse2.psll.w" => "__builtin_ia32_psllw128", + "llvm.x86.sse2.pslli.d" => "__builtin_ia32_pslldi128", + "llvm.x86.sse2.pslli.q" => "__builtin_ia32_psllqi128", + "llvm.x86.sse2.pslli.w" => "__builtin_ia32_psllwi128", + "llvm.x86.sse2.psra.d" => "__builtin_ia32_psrad128", + "llvm.x86.sse2.psra.w" => "__builtin_ia32_psraw128", + "llvm.x86.sse2.psrai.d" => "__builtin_ia32_psradi128", + "llvm.x86.sse2.psrai.w" => "__builtin_ia32_psrawi128", + "llvm.x86.sse2.psrl.d" => "__builtin_ia32_psrld128", + "llvm.x86.sse2.psrl.dq" => "__builtin_ia32_psrldqi128", + "llvm.x86.sse2.psrl.dq.bs" => "__builtin_ia32_psrldqi128_byteshift", + "llvm.x86.sse2.psrl.q" => "__builtin_ia32_psrlq128", + "llvm.x86.sse2.psrl.w" => "__builtin_ia32_psrlw128", + "llvm.x86.sse2.psrli.d" => "__builtin_ia32_psrldi128", + "llvm.x86.sse2.psrli.q" => "__builtin_ia32_psrlqi128", + "llvm.x86.sse2.psrli.w" => "__builtin_ia32_psrlwi128", + "llvm.x86.sse2.psubs.b" => "__builtin_ia32_psubsb128", + "llvm.x86.sse2.psubs.w" => "__builtin_ia32_psubsw128", + "llvm.x86.sse2.psubus.b" => "__builtin_ia32_psubusb128", + "llvm.x86.sse2.psubus.w" => "__builtin_ia32_psubusw128", + "llvm.x86.sse2.sqrt.pd" => "__builtin_ia32_sqrtpd", + "llvm.x86.sse2.sqrt.sd" => "__builtin_ia32_sqrtsd", + "llvm.x86.sse2.storel.dq" => "__builtin_ia32_storelv4si", + "llvm.x86.sse2.storeu.dq" => "__builtin_ia32_storedqu", + "llvm.x86.sse2.storeu.pd" => "__builtin_ia32_storeupd", + "llvm.x86.sse2.sub.sd" => "__builtin_ia32_subsd", + "llvm.x86.sse2.ucomieq.sd" => "__builtin_ia32_ucomisdeq", + "llvm.x86.sse2.ucomige.sd" => "__builtin_ia32_ucomisdge", + "llvm.x86.sse2.ucomigt.sd" => "__builtin_ia32_ucomisdgt", + "llvm.x86.sse2.ucomile.sd" => "__builtin_ia32_ucomisdle", + "llvm.x86.sse2.ucomilt.sd" => "__builtin_ia32_ucomisdlt", + "llvm.x86.sse2.ucomineq.sd" => "__builtin_ia32_ucomisdneq", + "llvm.x86.sse3.addsub.pd" => "__builtin_ia32_addsubpd", + "llvm.x86.sse3.addsub.ps" => "__builtin_ia32_addsubps", + "llvm.x86.sse3.hadd.pd" => "__builtin_ia32_haddpd", + "llvm.x86.sse3.hadd.ps" => "__builtin_ia32_haddps", + "llvm.x86.sse3.hsub.pd" => "__builtin_ia32_hsubpd", + "llvm.x86.sse3.hsub.ps" => "__builtin_ia32_hsubps", + "llvm.x86.sse3.ldu.dq" => "__builtin_ia32_lddqu", + "llvm.x86.sse3.monitor" => "__builtin_ia32_monitor", + "llvm.x86.sse3.mwait" => "__builtin_ia32_mwait", + "llvm.x86.sse41.blendpd" => "__builtin_ia32_blendpd", + "llvm.x86.sse41.blendps" => "__builtin_ia32_blendps", + "llvm.x86.sse41.blendvpd" => "__builtin_ia32_blendvpd", + "llvm.x86.sse41.blendvps" => "__builtin_ia32_blendvps", + "llvm.x86.sse41.dppd" => "__builtin_ia32_dppd", + "llvm.x86.sse41.dpps" => "__builtin_ia32_dpps", + "llvm.x86.sse41.extractps" => "__builtin_ia32_extractps128", + "llvm.x86.sse41.insertps" => "__builtin_ia32_insertps128", + "llvm.x86.sse41.movntdqa" => "__builtin_ia32_movntdqa", + "llvm.x86.sse41.mpsadbw" => "__builtin_ia32_mpsadbw128", + "llvm.x86.sse41.packusdw" => "__builtin_ia32_packusdw128", + "llvm.x86.sse41.pblendvb" => "__builtin_ia32_pblendvb128", + "llvm.x86.sse41.pblendw" => "__builtin_ia32_pblendw128", + "llvm.x86.sse41.phminposuw" => "__builtin_ia32_phminposuw128", + "llvm.x86.sse41.pmaxsb" => "__builtin_ia32_pmaxsb128", + "llvm.x86.sse41.pmaxsd" => "__builtin_ia32_pmaxsd128", + "llvm.x86.sse41.pmaxud" => "__builtin_ia32_pmaxud128", + "llvm.x86.sse41.pmaxuw" => "__builtin_ia32_pmaxuw128", + "llvm.x86.sse41.pminsb" => "__builtin_ia32_pminsb128", + "llvm.x86.sse41.pminsd" => "__builtin_ia32_pminsd128", + "llvm.x86.sse41.pminud" => "__builtin_ia32_pminud128", + "llvm.x86.sse41.pminuw" => "__builtin_ia32_pminuw128", + "llvm.x86.sse41.pmovsxbd" => "__builtin_ia32_pmovsxbd128", + "llvm.x86.sse41.pmovsxbq" => "__builtin_ia32_pmovsxbq128", + "llvm.x86.sse41.pmovsxbw" => "__builtin_ia32_pmovsxbw128", + "llvm.x86.sse41.pmovsxdq" => "__builtin_ia32_pmovsxdq128", + "llvm.x86.sse41.pmovsxwd" => "__builtin_ia32_pmovsxwd128", + "llvm.x86.sse41.pmovsxwq" => "__builtin_ia32_pmovsxwq128", + "llvm.x86.sse41.pmovzxbd" => "__builtin_ia32_pmovzxbd128", + "llvm.x86.sse41.pmovzxbq" => "__builtin_ia32_pmovzxbq128", + "llvm.x86.sse41.pmovzxbw" => "__builtin_ia32_pmovzxbw128", + "llvm.x86.sse41.pmovzxdq" => "__builtin_ia32_pmovzxdq128", + "llvm.x86.sse41.pmovzxwd" => "__builtin_ia32_pmovzxwd128", + "llvm.x86.sse41.pmovzxwq" => "__builtin_ia32_pmovzxwq128", + "llvm.x86.sse41.pmuldq" => "__builtin_ia32_pmuldq128", + "llvm.x86.sse41.ptestc" => "__builtin_ia32_ptestc128", + "llvm.x86.sse41.ptestnzc" => "__builtin_ia32_ptestnzc128", + "llvm.x86.sse41.ptestz" => "__builtin_ia32_ptestz128", + "llvm.x86.sse41.round.pd" => "__builtin_ia32_roundpd", + "llvm.x86.sse41.round.ps" => "__builtin_ia32_roundps", + "llvm.x86.sse41.round.sd" => "__builtin_ia32_roundsd", + "llvm.x86.sse41.round.ss" => "__builtin_ia32_roundss", + "llvm.x86.sse42.crc32.32.16" => "__builtin_ia32_crc32hi", + "llvm.x86.sse42.crc32.32.32" => "__builtin_ia32_crc32si", + "llvm.x86.sse42.crc32.32.8" => "__builtin_ia32_crc32qi", + "llvm.x86.sse42.crc32.64.64" => "__builtin_ia32_crc32di", + "llvm.x86.sse42.pcmpestri128" => "__builtin_ia32_pcmpestri128", + "llvm.x86.sse42.pcmpestria128" => "__builtin_ia32_pcmpestria128", + "llvm.x86.sse42.pcmpestric128" => "__builtin_ia32_pcmpestric128", + "llvm.x86.sse42.pcmpestrio128" => "__builtin_ia32_pcmpestrio128", + "llvm.x86.sse42.pcmpestris128" => "__builtin_ia32_pcmpestris128", + "llvm.x86.sse42.pcmpestriz128" => "__builtin_ia32_pcmpestriz128", + "llvm.x86.sse42.pcmpestrm128" => "__builtin_ia32_pcmpestrm128", + "llvm.x86.sse42.pcmpistri128" => "__builtin_ia32_pcmpistri128", + "llvm.x86.sse42.pcmpistria128" => "__builtin_ia32_pcmpistria128", + "llvm.x86.sse42.pcmpistric128" => "__builtin_ia32_pcmpistric128", + "llvm.x86.sse42.pcmpistrio128" => "__builtin_ia32_pcmpistrio128", + "llvm.x86.sse42.pcmpistris128" => "__builtin_ia32_pcmpistris128", + "llvm.x86.sse42.pcmpistriz128" => "__builtin_ia32_pcmpistriz128", + "llvm.x86.sse42.pcmpistrm128" => "__builtin_ia32_pcmpistrm128", + "llvm.x86.sse4a.extrq" => "__builtin_ia32_extrq", + "llvm.x86.sse4a.extrqi" => "__builtin_ia32_extrqi", + "llvm.x86.sse4a.insertq" => "__builtin_ia32_insertq", + "llvm.x86.sse4a.insertqi" => "__builtin_ia32_insertqi", + "llvm.x86.sse4a.movnt.sd" => "__builtin_ia32_movntsd", + "llvm.x86.sse4a.movnt.ss" => "__builtin_ia32_movntss", + "llvm.x86.ssse3.pabs.b" => "__builtin_ia32_pabsb", + "llvm.x86.ssse3.pabs.b.128" => "__builtin_ia32_pabsb128", + "llvm.x86.ssse3.pabs.d" => "__builtin_ia32_pabsd", + "llvm.x86.ssse3.pabs.d.128" => "__builtin_ia32_pabsd128", + "llvm.x86.ssse3.pabs.w" => "__builtin_ia32_pabsw", + "llvm.x86.ssse3.pabs.w.128" => "__builtin_ia32_pabsw128", + "llvm.x86.ssse3.phadd.d" => "__builtin_ia32_phaddd", + "llvm.x86.ssse3.phadd.d.128" => "__builtin_ia32_phaddd128", + "llvm.x86.ssse3.phadd.sw" => "__builtin_ia32_phaddsw", + "llvm.x86.ssse3.phadd.sw.128" => "__builtin_ia32_phaddsw128", + "llvm.x86.ssse3.phadd.w" => "__builtin_ia32_phaddw", + "llvm.x86.ssse3.phadd.w.128" => "__builtin_ia32_phaddw128", + "llvm.x86.ssse3.phsub.d" => "__builtin_ia32_phsubd", + "llvm.x86.ssse3.phsub.d.128" => "__builtin_ia32_phsubd128", + "llvm.x86.ssse3.phsub.sw" => "__builtin_ia32_phsubsw", + "llvm.x86.ssse3.phsub.sw.128" => "__builtin_ia32_phsubsw128", + "llvm.x86.ssse3.phsub.w" => "__builtin_ia32_phsubw", + "llvm.x86.ssse3.phsub.w.128" => "__builtin_ia32_phsubw128", + "llvm.x86.ssse3.pmadd.ub.sw" => "__builtin_ia32_pmaddubsw", + "llvm.x86.ssse3.pmadd.ub.sw.128" => "__builtin_ia32_pmaddubsw128", + "llvm.x86.ssse3.pmul.hr.sw" => "__builtin_ia32_pmulhrsw", + "llvm.x86.ssse3.pmul.hr.sw.128" => "__builtin_ia32_pmulhrsw128", + "llvm.x86.ssse3.pshuf.b" => "__builtin_ia32_pshufb", + "llvm.x86.ssse3.pshuf.b.128" => "__builtin_ia32_pshufb128", + "llvm.x86.ssse3.psign.b" => "__builtin_ia32_psignb", + "llvm.x86.ssse3.psign.b.128" => "__builtin_ia32_psignb128", + "llvm.x86.ssse3.psign.d" => "__builtin_ia32_psignd", + "llvm.x86.ssse3.psign.d.128" => "__builtin_ia32_psignd128", + "llvm.x86.ssse3.psign.w" => "__builtin_ia32_psignw", + "llvm.x86.ssse3.psign.w.128" => "__builtin_ia32_psignw128", + "llvm.x86.sttilecfg" => "__builtin_ia32_tile_storeconfig", + "llvm.x86.stui" => "__builtin_ia32_stui", + "llvm.x86.subborrow.u32" => "__builtin_ia32_subborrow_u32", + "llvm.x86.subborrow.u64" => "__builtin_ia32_subborrow_u64", + "llvm.x86.tbm.bextri.u32" => "__builtin_ia32_bextri_u32", + "llvm.x86.tbm.bextri.u64" => "__builtin_ia32_bextri_u64", + "llvm.x86.tdpbf16ps" => "__builtin_ia32_tdpbf16ps", + "llvm.x86.tdpbf16ps.internal" => "__builtin_ia32_tdpbf16ps_internal", + "llvm.x86.tdpbssd" => "__builtin_ia32_tdpbssd", + "llvm.x86.tdpbssd.internal" => "__builtin_ia32_tdpbssd_internal", + "llvm.x86.tdpbsud" => "__builtin_ia32_tdpbsud", + "llvm.x86.tdpbsud.internal" => "__builtin_ia32_tdpbsud_internal", + "llvm.x86.tdpbusd" => "__builtin_ia32_tdpbusd", + "llvm.x86.tdpbusd.internal" => "__builtin_ia32_tdpbusd_internal", + "llvm.x86.tdpbuud" => "__builtin_ia32_tdpbuud", + "llvm.x86.tdpbuud.internal" => "__builtin_ia32_tdpbuud_internal", + "llvm.x86.testui" => "__builtin_ia32_testui", + "llvm.x86.tileloadd64" => "__builtin_ia32_tileloadd64", + "llvm.x86.tileloadd64.internal" => "__builtin_ia32_tileloadd64_internal", + "llvm.x86.tileloaddt164" => "__builtin_ia32_tileloaddt164", + "llvm.x86.tileloaddt164.internal" => "__builtin_ia32_tileloaddt164_internal", + "llvm.x86.tilerelease" => "__builtin_ia32_tilerelease", + "llvm.x86.tilestored64" => "__builtin_ia32_tilestored64", + "llvm.x86.tilestored64.internal" => "__builtin_ia32_tilestored64_internal", + "llvm.x86.tilezero" => "__builtin_ia32_tilezero", + "llvm.x86.tilezero.internal" => "__builtin_ia32_tilezero_internal", + "llvm.x86.tpause" => "__builtin_ia32_tpause", + "llvm.x86.umonitor" => "__builtin_ia32_umonitor", + "llvm.x86.umwait" => "__builtin_ia32_umwait", + "llvm.x86.vcvtph2ps.128" => "__builtin_ia32_vcvtph2ps", + "llvm.x86.vcvtph2ps.256" => "__builtin_ia32_vcvtph2ps256", + "llvm.x86.vcvtps2ph.128" => "__builtin_ia32_vcvtps2ph", + "llvm.x86.vcvtps2ph.256" => "__builtin_ia32_vcvtps2ph256", + "llvm.x86.vgf2p8affineinvqb.128" => "__builtin_ia32_vgf2p8affineinvqb_v16qi", + "llvm.x86.vgf2p8affineinvqb.256" => "__builtin_ia32_vgf2p8affineinvqb_v32qi", + "llvm.x86.vgf2p8affineinvqb.512" => "__builtin_ia32_vgf2p8affineinvqb_v64qi", + "llvm.x86.vgf2p8affineqb.128" => "__builtin_ia32_vgf2p8affineqb_v16qi", + "llvm.x86.vgf2p8affineqb.256" => "__builtin_ia32_vgf2p8affineqb_v32qi", + "llvm.x86.vgf2p8affineqb.512" => "__builtin_ia32_vgf2p8affineqb_v64qi", + "llvm.x86.vgf2p8mulb.128" => "__builtin_ia32_vgf2p8mulb_v16qi", + "llvm.x86.vgf2p8mulb.256" => "__builtin_ia32_vgf2p8mulb_v32qi", + "llvm.x86.vgf2p8mulb.512" => "__builtin_ia32_vgf2p8mulb_v64qi", + "llvm.x86.wbinvd" => "__builtin_ia32_wbinvd", + "llvm.x86.wbnoinvd" => "__builtin_ia32_wbnoinvd", + "llvm.x86.wrfsbase.32" => "__builtin_ia32_wrfsbase32", + "llvm.x86.wrfsbase.64" => "__builtin_ia32_wrfsbase64", + "llvm.x86.wrgsbase.32" => "__builtin_ia32_wrgsbase32", + "llvm.x86.wrgsbase.64" => "__builtin_ia32_wrgsbase64", + "llvm.x86.wrpkru" => "__builtin_ia32_wrpkru", + "llvm.x86.wrssd" => "__builtin_ia32_wrssd", + "llvm.x86.wrssq" => "__builtin_ia32_wrssq", + "llvm.x86.wrussd" => "__builtin_ia32_wrussd", + "llvm.x86.wrussq" => "__builtin_ia32_wrussq", + "llvm.x86.xabort" => "__builtin_ia32_xabort", + "llvm.x86.xbegin" => "__builtin_ia32_xbegin", + "llvm.x86.xend" => "__builtin_ia32_xend", + "llvm.x86.xop.vfrcz.pd" => "__builtin_ia32_vfrczpd", + "llvm.x86.xop.vfrcz.pd.256" => "__builtin_ia32_vfrczpd256", + "llvm.x86.xop.vfrcz.ps" => "__builtin_ia32_vfrczps", + "llvm.x86.xop.vfrcz.ps.256" => "__builtin_ia32_vfrczps256", + "llvm.x86.xop.vfrcz.sd" => "__builtin_ia32_vfrczsd", + "llvm.x86.xop.vfrcz.ss" => "__builtin_ia32_vfrczss", + "llvm.x86.xop.vpcmov" => "__builtin_ia32_vpcmov", + "llvm.x86.xop.vpcmov.256" => "__builtin_ia32_vpcmov_256", + "llvm.x86.xop.vpcomb" => "__builtin_ia32_vpcomb", + "llvm.x86.xop.vpcomd" => "__builtin_ia32_vpcomd", + "llvm.x86.xop.vpcomq" => "__builtin_ia32_vpcomq", + "llvm.x86.xop.vpcomub" => "__builtin_ia32_vpcomub", + "llvm.x86.xop.vpcomud" => "__builtin_ia32_vpcomud", + "llvm.x86.xop.vpcomuq" => "__builtin_ia32_vpcomuq", + "llvm.x86.xop.vpcomuw" => "__builtin_ia32_vpcomuw", + "llvm.x86.xop.vpcomw" => "__builtin_ia32_vpcomw", + "llvm.x86.xop.vpermil2pd" => "__builtin_ia32_vpermil2pd", + "llvm.x86.xop.vpermil2pd.256" => "__builtin_ia32_vpermil2pd256", + "llvm.x86.xop.vpermil2ps" => "__builtin_ia32_vpermil2ps", + "llvm.x86.xop.vpermil2ps.256" => "__builtin_ia32_vpermil2ps256", + "llvm.x86.xop.vphaddbd" => "__builtin_ia32_vphaddbd", + "llvm.x86.xop.vphaddbq" => "__builtin_ia32_vphaddbq", + "llvm.x86.xop.vphaddbw" => "__builtin_ia32_vphaddbw", + "llvm.x86.xop.vphadddq" => "__builtin_ia32_vphadddq", + "llvm.x86.xop.vphaddubd" => "__builtin_ia32_vphaddubd", + "llvm.x86.xop.vphaddubq" => "__builtin_ia32_vphaddubq", + "llvm.x86.xop.vphaddubw" => "__builtin_ia32_vphaddubw", + "llvm.x86.xop.vphaddudq" => "__builtin_ia32_vphaddudq", + "llvm.x86.xop.vphadduwd" => "__builtin_ia32_vphadduwd", + "llvm.x86.xop.vphadduwq" => "__builtin_ia32_vphadduwq", + "llvm.x86.xop.vphaddwd" => "__builtin_ia32_vphaddwd", + "llvm.x86.xop.vphaddwq" => "__builtin_ia32_vphaddwq", + "llvm.x86.xop.vphsubbw" => "__builtin_ia32_vphsubbw", + "llvm.x86.xop.vphsubdq" => "__builtin_ia32_vphsubdq", + "llvm.x86.xop.vphsubwd" => "__builtin_ia32_vphsubwd", + "llvm.x86.xop.vpmacsdd" => "__builtin_ia32_vpmacsdd", + "llvm.x86.xop.vpmacsdqh" => "__builtin_ia32_vpmacsdqh", + "llvm.x86.xop.vpmacsdql" => "__builtin_ia32_vpmacsdql", + "llvm.x86.xop.vpmacssdd" => "__builtin_ia32_vpmacssdd", + "llvm.x86.xop.vpmacssdqh" => "__builtin_ia32_vpmacssdqh", + "llvm.x86.xop.vpmacssdql" => "__builtin_ia32_vpmacssdql", + "llvm.x86.xop.vpmacsswd" => "__builtin_ia32_vpmacsswd", + "llvm.x86.xop.vpmacssww" => "__builtin_ia32_vpmacssww", + "llvm.x86.xop.vpmacswd" => "__builtin_ia32_vpmacswd", + "llvm.x86.xop.vpmacsww" => "__builtin_ia32_vpmacsww", + "llvm.x86.xop.vpmadcsswd" => "__builtin_ia32_vpmadcsswd", + "llvm.x86.xop.vpmadcswd" => "__builtin_ia32_vpmadcswd", + "llvm.x86.xop.vpperm" => "__builtin_ia32_vpperm", + "llvm.x86.xop.vprotb" => "__builtin_ia32_vprotb", + "llvm.x86.xop.vprotbi" => "__builtin_ia32_vprotbi", + "llvm.x86.xop.vprotd" => "__builtin_ia32_vprotd", + "llvm.x86.xop.vprotdi" => "__builtin_ia32_vprotdi", + "llvm.x86.xop.vprotq" => "__builtin_ia32_vprotq", + "llvm.x86.xop.vprotqi" => "__builtin_ia32_vprotqi", + "llvm.x86.xop.vprotw" => "__builtin_ia32_vprotw", + "llvm.x86.xop.vprotwi" => "__builtin_ia32_vprotwi", + "llvm.x86.xop.vpshab" => "__builtin_ia32_vpshab", + "llvm.x86.xop.vpshad" => "__builtin_ia32_vpshad", + "llvm.x86.xop.vpshaq" => "__builtin_ia32_vpshaq", + "llvm.x86.xop.vpshaw" => "__builtin_ia32_vpshaw", + "llvm.x86.xop.vpshlb" => "__builtin_ia32_vpshlb", + "llvm.x86.xop.vpshld" => "__builtin_ia32_vpshld", + "llvm.x86.xop.vpshlq" => "__builtin_ia32_vpshlq", + "llvm.x86.xop.vpshlw" => "__builtin_ia32_vpshlw", + "llvm.x86.xresldtrk" => "__builtin_ia32_xresldtrk", + "llvm.x86.xsusldtrk" => "__builtin_ia32_xsusldtrk", + "llvm.x86.xtest" => "__builtin_ia32_xtest", + // xcore + "llvm.xcore.bitrev" => "__builtin_bitrev", + "llvm.xcore.getid" => "__builtin_getid", + "llvm.xcore.getps" => "__builtin_getps", + "llvm.xcore.setps" => "__builtin_setps", + _ => unimplemented!("***** unsupported LLVM intrinsic {}", name), +} diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs index b074febc52..1b089f08f7 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs @@ -1,22 +1,250 @@ -use gccjit::Function; +use std::borrow::Cow; -use crate::context::CodegenCx; +use gccjit::{Function, FunctionPtrType, RValue, ToRValue}; -pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { - let _gcc_name = - match name { - "llvm.x86.xgetbv" => { - let gcc_name = "__builtin_trap"; - let func = cx.context.get_builtin_function(gcc_name); - cx.functions.borrow_mut().insert(gcc_name.to_string(), func); - return func; +use crate::{context::CodegenCx, builder::Builder}; + +pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc, 'tcx>, gcc_func: FunctionPtrType<'gcc>, mut args: Cow<'b, [RValue<'gcc>]>, func_name: &str) -> Cow<'b, [RValue<'gcc>]> { + // Some LLVM intrinsics do not map 1-to-1 to GCC intrinsics, so we add the missing + // arguments here. + if gcc_func.get_param_count() != args.len() { + match &*func_name { + "__builtin_ia32_pmuldq512_mask" | "__builtin_ia32_pmuludq512_mask" + // FIXME(antoyo): the following intrinsics has 4 (or 5) arguments according to the doc, but is defined with 2 (or 3) arguments in library/stdarch/crates/core_arch/src/x86/avx512f.rs. + | "__builtin_ia32_pmaxsd512_mask" | "__builtin_ia32_pmaxsq512_mask" | "__builtin_ia32_pmaxsq256_mask" + | "__builtin_ia32_pmaxsq128_mask" | "__builtin_ia32_maxps512_mask" | "__builtin_ia32_maxpd512_mask" + | "__builtin_ia32_pmaxud512_mask" | "__builtin_ia32_pmaxuq512_mask" | "__builtin_ia32_pmaxuq256_mask" + | "__builtin_ia32_pmaxuq128_mask" + | "__builtin_ia32_pminsd512_mask" | "__builtin_ia32_pminsq512_mask" | "__builtin_ia32_pminsq256_mask" + | "__builtin_ia32_pminsq128_mask" | "__builtin_ia32_minps512_mask" | "__builtin_ia32_minpd512_mask" + | "__builtin_ia32_pminud512_mask" | "__builtin_ia32_pminuq512_mask" | "__builtin_ia32_pminuq256_mask" + | "__builtin_ia32_pminuq128_mask" | "__builtin_ia32_sqrtps512_mask" | "__builtin_ia32_sqrtpd512_mask" + => { + // TODO: refactor by separating those intrinsics outside of this branch. + let add_before_last_arg = + match &*func_name { + "__builtin_ia32_maxps512_mask" | "__builtin_ia32_maxpd512_mask" + | "__builtin_ia32_minps512_mask" | "__builtin_ia32_minpd512_mask" + | "__builtin_ia32_sqrtps512_mask" | "__builtin_ia32_sqrtpd512_mask" => true, + _ => false, + }; + let new_first_arg_is_zero = + match &*func_name { + "__builtin_ia32_pmaxuq256_mask" | "__builtin_ia32_pmaxuq128_mask" + | "__builtin_ia32_pminuq256_mask" | "__builtin_ia32_pminuq128_mask" => true, + _ => false + }; + let arg3_index = + match &*func_name { + "__builtin_ia32_sqrtps512_mask" | "__builtin_ia32_sqrtpd512_mask" => 1, + _ => 2, + }; + let mut new_args = args.to_vec(); + let arg3_type = gcc_func.get_param_type(arg3_index); + let first_arg = + if new_first_arg_is_zero { + let vector_type = arg3_type.dyncast_vector().expect("vector type"); + let zero = builder.context.new_rvalue_zero(vector_type.get_element_type()); + let num_units = vector_type.get_num_units(); + builder.context.new_rvalue_from_vector(None, arg3_type, &vec![zero; num_units]) + } + else { + builder.current_func().new_local(None, arg3_type, "undefined_for_intrinsic").to_rvalue() + }; + if add_before_last_arg { + new_args.insert(new_args.len() - 1, first_arg); + } + else { + new_args.push(first_arg); + } + let arg4_index = + match &*func_name { + "__builtin_ia32_sqrtps512_mask" | "__builtin_ia32_sqrtpd512_mask" => 2, + _ => 3, + }; + let arg4_type = gcc_func.get_param_type(arg4_index); + let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1); + if add_before_last_arg { + new_args.insert(new_args.len() - 1, minus_one); + } + else { + new_args.push(minus_one); + } + args = new_args.into(); + }, + "__builtin_ia32_pternlogd512_mask" | "__builtin_ia32_pternlogd256_mask" + | "__builtin_ia32_pternlogd128_mask" | "__builtin_ia32_pternlogq512_mask" + | "__builtin_ia32_pternlogq256_mask" | "__builtin_ia32_pternlogq128_mask" => { + let mut new_args = args.to_vec(); + let arg5_type = gcc_func.get_param_type(4); + let minus_one = builder.context.new_rvalue_from_int(arg5_type, -1); + new_args.push(minus_one); + args = new_args.into(); + }, + "__builtin_ia32_vfmaddps512_mask" | "__builtin_ia32_vfmaddpd512_mask" => { + let mut new_args = args.to_vec(); + + let mut last_arg = None; + if args.len() == 4 { + last_arg = new_args.pop(); + } + + let arg4_type = gcc_func.get_param_type(3); + let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1); + new_args.push(minus_one); + + if args.len() == 3 { + // Both llvm.fma.v16f32 and llvm.x86.avx512.vfmadd.ps.512 maps to + // the same GCC intrinsic, but the former has 3 parameters and the + // latter has 4 so it doesn't require this additional argument. + let arg5_type = gcc_func.get_param_type(4); + new_args.push(builder.context.new_rvalue_from_int(arg5_type, 4)); + } + + if let Some(last_arg) = last_arg { + new_args.push(last_arg); + } + + args = new_args.into(); + }, + "__builtin_ia32_addps512_mask" | "__builtin_ia32_addpd512_mask" + | "__builtin_ia32_subps512_mask" | "__builtin_ia32_subpd512_mask" + | "__builtin_ia32_mulps512_mask" | "__builtin_ia32_mulpd512_mask" + | "__builtin_ia32_divps512_mask" | "__builtin_ia32_divpd512_mask" => { + let mut new_args = args.to_vec(); + let last_arg = new_args.pop().expect("last arg"); + let arg3_type = gcc_func.get_param_type(2); + let undefined = builder.current_func().new_local(None, arg3_type, "undefined_for_intrinsic").to_rvalue(); + new_args.push(undefined); + let arg4_type = gcc_func.get_param_type(3); + let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1); + new_args.push(minus_one); + new_args.push(last_arg); + args = new_args.into(); + }, + "__builtin_ia32_vfmaddsubps512_mask" | "__builtin_ia32_vfmaddsubpd512_mask" => { + let mut new_args = args.to_vec(); + let last_arg = new_args.pop().expect("last arg"); + let arg4_type = gcc_func.get_param_type(3); + let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1); + new_args.push(minus_one); + new_args.push(last_arg); + args = new_args.into(); + }, + _ => (), + } + } + + args +} + +pub fn ignore_arg_cast(func_name: &str, index: usize, args_len: usize) -> bool { + // NOTE: these intrinsics have missing parameters before the last one, so ignore the + // last argument type check. + // FIXME(antoyo): find a way to refactor in order to avoid this hack. + match func_name { + "__builtin_ia32_maxps512_mask" | "__builtin_ia32_maxpd512_mask" + | "__builtin_ia32_minps512_mask" | "__builtin_ia32_minpd512_mask" | "__builtin_ia32_sqrtps512_mask" + | "__builtin_ia32_sqrtpd512_mask" | "__builtin_ia32_addps512_mask" | "__builtin_ia32_addpd512_mask" + | "__builtin_ia32_subps512_mask" | "__builtin_ia32_subpd512_mask" + | "__builtin_ia32_mulps512_mask" | "__builtin_ia32_mulpd512_mask" + | "__builtin_ia32_divps512_mask" | "__builtin_ia32_divpd512_mask" + | "__builtin_ia32_vfmaddsubps512_mask" | "__builtin_ia32_vfmaddsubpd512_mask" => { + if index == args_len - 1 { + return true; + } }, - // NOTE: this doc specifies the equivalent GCC builtins: http://huonw.github.io/llvmint/llvmint/x86/index.html - "llvm.x86.sse2.cmp.pd" => "__builtin_ia32_cmppd", - "llvm.x86.sse2.movmsk.pd" => "__builtin_ia32_movmskpd", - "llvm.x86.sse2.pmovmskb.128" => "__builtin_ia32_pmovmskb128", - _ => unimplemented!("unsupported LLVM intrinsic {}", name) - }; - - unimplemented!(); + "__builtin_ia32_vfmaddps512_mask" | "__builtin_ia32_vfmaddpd512_mask" => { + // Since there are two LLVM intrinsics that map to each of these GCC builtins and only + // one of them has a missing parameter before the last one, we check the number of + // arguments to distinguish those cases. + if args_len == 4 && index == args_len - 1 { + return true; + } + }, + _ => (), + } + + false +} + +#[cfg(not(feature="master"))] +pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { + match name { + "llvm.x86.xgetbv" => { + let gcc_name = "__builtin_trap"; + let func = cx.context.get_builtin_function(gcc_name); + cx.functions.borrow_mut().insert(gcc_name.to_string(), func); + return func; + }, + _ => unimplemented!("unsupported LLVM intrinsic {}", name), + } +} + +#[cfg(feature="master")] +pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { + let gcc_name = match name { + "llvm.x86.xgetbv" => "__builtin_ia32_xgetbv", + // NOTE: this doc specifies the equivalent GCC builtins: http://huonw.github.io/llvmint/llvmint/x86/index.html + "llvm.sqrt.v2f64" => "__builtin_ia32_sqrtpd", + "llvm.x86.avx512.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask", + "llvm.x86.avx512.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask", + "llvm.x86.avx512.mask.pmaxs.q.256" => "__builtin_ia32_pmaxsq256_mask", + "llvm.x86.avx512.mask.pmaxs.q.128" => "__builtin_ia32_pmaxsq128_mask", + "llvm.x86.avx512.max.ps.512" => "__builtin_ia32_maxps512_mask", + "llvm.x86.avx512.max.pd.512" => "__builtin_ia32_maxpd512_mask", + "llvm.x86.avx512.mask.pmaxu.q.256" => "__builtin_ia32_pmaxuq256_mask", + "llvm.x86.avx512.mask.pmaxu.q.128" => "__builtin_ia32_pmaxuq128_mask", + "llvm.x86.avx512.mask.pmins.q.256" => "__builtin_ia32_pminsq256_mask", + "llvm.x86.avx512.mask.pmins.q.128" => "__builtin_ia32_pminsq128_mask", + "llvm.x86.avx512.min.ps.512" => "__builtin_ia32_minps512_mask", + "llvm.x86.avx512.min.pd.512" => "__builtin_ia32_minpd512_mask", + "llvm.x86.avx512.mask.pminu.q.256" => "__builtin_ia32_pminuq256_mask", + "llvm.x86.avx512.mask.pminu.q.128" => "__builtin_ia32_pminuq128_mask", + "llvm.fma.v16f32" => "__builtin_ia32_vfmaddps512_mask", + "llvm.fma.v8f64" => "__builtin_ia32_vfmaddpd512_mask", + "llvm.x86.avx512.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", + "llvm.x86.avx512.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", + "llvm.x86.avx512.pternlog.d.512" => "__builtin_ia32_pternlogd512_mask", + "llvm.x86.avx512.pternlog.d.256" => "__builtin_ia32_pternlogd256_mask", + "llvm.x86.avx512.pternlog.d.128" => "__builtin_ia32_pternlogd128_mask", + "llvm.x86.avx512.pternlog.q.512" => "__builtin_ia32_pternlogq512_mask", + "llvm.x86.avx512.pternlog.q.256" => "__builtin_ia32_pternlogq256_mask", + "llvm.x86.avx512.pternlog.q.128" => "__builtin_ia32_pternlogq128_mask", + "llvm.x86.avx512.add.ps.512" => "__builtin_ia32_addps512_mask", + "llvm.x86.avx512.add.pd.512" => "__builtin_ia32_addpd512_mask", + "llvm.x86.avx512.sub.ps.512" => "__builtin_ia32_subps512_mask", + "llvm.x86.avx512.sub.pd.512" => "__builtin_ia32_subpd512_mask", + "llvm.x86.avx512.mul.ps.512" => "__builtin_ia32_mulps512_mask", + "llvm.x86.avx512.mul.pd.512" => "__builtin_ia32_mulpd512_mask", + "llvm.x86.avx512.div.ps.512" => "__builtin_ia32_divps512_mask", + "llvm.x86.avx512.div.pd.512" => "__builtin_ia32_divpd512_mask", + "llvm.x86.avx512.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", + "llvm.x86.avx512.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", + + // The above doc points to unknown builtins for the following, so override them: + "llvm.x86.avx2.gather.d.d" => "__builtin_ia32_gathersiv4si", + "llvm.x86.avx2.gather.d.d.256" => "__builtin_ia32_gathersiv8si", + "llvm.x86.avx2.gather.d.ps" => "__builtin_ia32_gathersiv4sf", + "llvm.x86.avx2.gather.d.ps.256" => "__builtin_ia32_gathersiv8sf", + "llvm.x86.avx2.gather.d.q" => "__builtin_ia32_gathersiv2di", + "llvm.x86.avx2.gather.d.q.256" => "__builtin_ia32_gathersiv4di", + "llvm.x86.avx2.gather.d.pd" => "__builtin_ia32_gathersiv2df", + "llvm.x86.avx2.gather.d.pd.256" => "__builtin_ia32_gathersiv4df", + "llvm.x86.avx2.gather.q.d" => "__builtin_ia32_gatherdiv4si", + "llvm.x86.avx2.gather.q.d.256" => "__builtin_ia32_gatherdiv4si256", + "llvm.x86.avx2.gather.q.ps" => "__builtin_ia32_gatherdiv4sf", + "llvm.x86.avx2.gather.q.ps.256" => "__builtin_ia32_gatherdiv4sf256", + "llvm.x86.avx2.gather.q.q" => "__builtin_ia32_gatherdiv2di", + "llvm.x86.avx2.gather.q.q.256" => "__builtin_ia32_gatherdiv4di", + "llvm.x86.avx2.gather.q.pd" => "__builtin_ia32_gatherdiv2df", + "llvm.x86.avx2.gather.q.pd.256" => "__builtin_ia32_gatherdiv4df", + "" => "", + // NOTE: this file is generated by https://github.com/GuillaumeGomez/llvmint/blob/master/generate_list.py + _ => include!("archs.rs"), + }; + + let func = cx.context.get_target_builtin_function(gcc_name); + cx.functions.borrow_mut().insert(gcc_name.to_string(), func); + func } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 68a05d95ef..5fbdedac0c 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -356,6 +356,16 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { self.context.new_rvalue_from_int(self.int_type, 0) } + fn type_checked_load( + &mut self, + _llvtable: Self::Value, + _vtable_byte_offset: u64, + _typeid: Self::Value, + ) -> Self::Value { + // Unsupported. + self.context.new_rvalue_from_int(self.int_type, 0) + } + fn va_start(&mut self, _va_list: RValue<'gcc>) -> RValue<'gcc> { unimplemented!(); } @@ -967,34 +977,55 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } fn saturating_add(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>, signed: bool, width: u64) -> RValue<'gcc> { - let func = self.current_func.borrow().expect("func"); - + let result_type = lhs.get_type(); if signed { - // Algorithm from: https://stackoverflow.com/a/56531252/389119 - let after_block = func.new_block("after"); - let func_name = - match width { - 8 => "__builtin_add_overflow", - 16 => "__builtin_add_overflow", - 32 => "__builtin_sadd_overflow", - 64 => "__builtin_saddll_overflow", - 128 => "__builtin_add_overflow", - _ => unreachable!(), - }; - let overflow_func = self.context.get_builtin_function(func_name); - let result_type = lhs.get_type(); + // Based on algorithm from: https://stackoverflow.com/a/56531252/389119 + let func = self.current_func.borrow().expect("func"); let res = func.new_local(None, result_type, "saturating_sum"); - let overflow = self.overflow_call(overflow_func, &[lhs, rhs, res.get_address(None)], None); + let supports_native_type = self.is_native_int_type(result_type); + let overflow = + if supports_native_type { + let func_name = + match width { + 8 => "__builtin_add_overflow", + 16 => "__builtin_add_overflow", + 32 => "__builtin_sadd_overflow", + 64 => "__builtin_saddll_overflow", + 128 => "__builtin_add_overflow", + _ => unreachable!(), + }; + let overflow_func = self.context.get_builtin_function(func_name); + self.overflow_call(overflow_func, &[lhs, rhs, res.get_address(None)], None) + } + else { + let func_name = + match width { + 128 => "__rust_i128_addo", + _ => unreachable!(), + }; + let param_a = self.context.new_parameter(None, result_type, "a"); + let param_b = self.context.new_parameter(None, result_type, "b"); + let result_field = self.context.new_field(None, result_type, "result"); + let overflow_field = self.context.new_field(None, self.bool_type, "overflow"); + let return_type = self.context.new_struct_type(None, "result_overflow", &[result_field, overflow_field]); + let func = self.context.new_function(None, FunctionType::Extern, return_type.as_type(), &[param_a, param_b], func_name, false); + let result = self.context.new_call(None, func, &[lhs, rhs]); + let overflow = result.access_field(None, overflow_field); + let int_result = result.access_field(None, result_field); + self.llbb().add_assignment(None, res, int_result); + overflow + }; let then_block = func.new_block("then"); + let after_block = func.new_block("after"); - let unsigned_type = self.context.new_int_type(width as i32 / 8, false); - let shifted = self.context.new_cast(None, lhs, unsigned_type) >> self.context.new_rvalue_from_int(unsigned_type, width as i32 - 1); - let uint_max = self.context.new_unary_op(None, UnaryOp::BitwiseNegate, unsigned_type, - self.context.new_rvalue_from_int(unsigned_type, 0) - ); - let int_max = uint_max >> self.context.new_rvalue_one(unsigned_type); - then_block.add_assignment(None, res, self.context.new_cast(None, shifted + int_max, result_type)); + // Return `result_type`'s maximum or minimum value on overflow + // NOTE: convert the type to unsigned to have an unsigned shift. + let unsigned_type = result_type.to_unsigned(&self.cx); + let shifted = self.gcc_lshr(self.gcc_int_cast(lhs, unsigned_type), self.gcc_int(unsigned_type, width as i64 - 1)); + let uint_max = self.gcc_not(self.gcc_int(unsigned_type, 0)); + let int_max = self.gcc_lshr(uint_max, self.gcc_int(unsigned_type, 1)); + then_block.add_assignment(None, res, self.gcc_int_cast(self.gcc_add(shifted, int_max), result_type)); then_block.end_with_jump(None, after_block); self.llbb().end_with_conditional(None, overflow, then_block, after_block); @@ -1007,19 +1038,18 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } else { // Algorithm from: http://locklessinc.com/articles/sat_arithmetic/ - let res = lhs + rhs; - let res_type = res.get_type(); - let cond = self.context.new_comparison(None, ComparisonOp::LessThan, res, lhs); - let value = self.context.new_unary_op(None, UnaryOp::Minus, res_type, self.context.new_cast(None, cond, res_type)); - res | value + let res = self.gcc_add(lhs, rhs); + let cond = self.gcc_icmp(IntPredicate::IntULT, res, lhs); + let value = self.gcc_neg(self.gcc_int_cast(cond, result_type)); + self.gcc_or(res, value) } } // Algorithm from: https://locklessinc.com/articles/sat_arithmetic/ fn saturating_sub(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>, signed: bool, width: u64) -> RValue<'gcc> { + let result_type = lhs.get_type(); if signed { - // Also based on algorithm from: https://stackoverflow.com/a/56531252/389119 - let result_type = lhs.get_type(); + // Based on algorithm from: https://stackoverflow.com/a/56531252/389119 let func = self.current_func.borrow().expect("func"); let res = func.new_local(None, result_type, "saturating_diff"); let supports_native_type = self.is_native_int_type(result_type); @@ -1059,6 +1089,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let then_block = func.new_block("then"); let after_block = func.new_block("after"); + // Return `result_type`'s maximum or minimum value on overflow // NOTE: convert the type to unsigned to have an unsigned shift. let unsigned_type = result_type.to_unsigned(&self.cx); let shifted = self.gcc_lshr(self.gcc_int_cast(lhs, unsigned_type), self.gcc_int(unsigned_type, width as i64 - 1)); @@ -1076,11 +1107,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { res.to_rvalue() } else { - let res = lhs - rhs; - let comparison = self.context.new_comparison(None, ComparisonOp::LessThanEquals, res, lhs); - let comparison = self.context.new_cast(None, comparison, lhs.get_type()); - let unary_op = self.context.new_unary_op(None, UnaryOp::Minus, comparison.get_type(), comparison); - self.and(res, unary_op) + let res = self.gcc_sub(lhs, rhs); + let comparison = self.gcc_icmp(IntPredicate::IntULE, res, lhs); + let value = self.gcc_neg(self.gcc_int_cast(comparison, result_type)); + self.gcc_and(res, value) } } } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 7d7811c878..2401f33501 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -1,18 +1,24 @@ -use gccjit::{RValue, Type}; +use std::cmp::Ordering; + +use gccjit::{BinaryOp, RValue, Type, ToRValue}; use rustc_codegen_ssa::base::compare_simd_types; use rustc_codegen_ssa::common::{TypeKind, span_invalid_monomorphization_error}; use rustc_codegen_ssa::mir::operand::OperandRef; +use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods}; use rustc_hir as hir; use rustc_middle::span_bug; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, Ty}; use rustc_span::{Span, Symbol, sym}; +use rustc_target::abi::Align; use crate::builder::Builder; +use crate::intrinsic; pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, name: Symbol, callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx, RValue<'gcc>>], ret_ty: Ty<'tcx>, llret_ty: Type<'gcc>, span: Span) -> Result, ()> { // macros for error handling: + #[allow(unused_macro_rules)] macro_rules! emit_error { ($msg: tt) => { emit_error!($msg, ) @@ -52,7 +58,53 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx)); let arg_tys = sig.inputs(); - let name_str = name.as_str(); + + if name == sym::simd_select_bitmask { + require_simd!(arg_tys[1], "argument"); + let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); + + let expected_int_bits = (len.max(8) - 1).next_power_of_two(); + let expected_bytes = len / 8 + ((len % 8 > 0) as u64); + + let mask_ty = arg_tys[0]; + let mut mask = match mask_ty.kind() { + ty::Int(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(), + ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(), + ty::Array(elem, len) + if matches!(elem.kind(), ty::Uint(ty::UintTy::U8)) + && len.try_eval_usize(bx.tcx, ty::ParamEnv::reveal_all()) + == Some(expected_bytes) => + { + let place = PlaceRef::alloca(bx, args[0].layout); + args[0].val.store(bx, place); + let int_ty = bx.type_ix(expected_bytes * 8); + let ptr = bx.pointercast(place.llval, bx.cx.type_ptr_to(int_ty)); + bx.load(int_ty, ptr, Align::ONE) + } + _ => return_error!( + "invalid bitmask `{}`, expected `u{}` or `[u8; {}]`", + mask_ty, + expected_int_bits, + expected_bytes + ), + }; + + let arg1 = args[1].immediate(); + let arg1_type = arg1.get_type(); + let arg1_vector_type = arg1_type.unqualified().dyncast_vector().expect("vector type"); + let arg1_element_type = arg1_vector_type.get_element_type(); + + let mut elements = vec![]; + let one = bx.context.new_rvalue_one(mask.get_type()); + for _ in 0..len { + let element = bx.context.new_cast(None, mask & one, arg1_element_type); + elements.push(element); + mask = mask >> one; + } + let vector_mask = bx.context.new_rvalue_from_vector(None, arg1_type, &elements); + + return Ok(bx.vector_select(vector_mask, arg1, args[2].immediate())); + } // every intrinsic below takes a SIMD vector as its first argument require_simd!(arg_tys[0], "input"); @@ -99,10 +151,28 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, )); } - if let Some(stripped) = name_str.strip_prefix("simd_shuffle") { - let n: u64 = stripped.parse().unwrap_or_else(|_| { - span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") - }); + if let Some(stripped) = name.as_str().strip_prefix("simd_shuffle") { + let n: u64 = + if stripped.is_empty() { + // Make sure this is actually an array, since typeck only checks the length-suffixed + // version of this intrinsic. + match args[2].layout.ty.kind() { + ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => { + len.try_eval_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| { + span_bug!(span, "could not evaluate shuffle index array length") + }) + } + _ => return_error!( + "simd_shuffle index must be an array of `u32`, got `{}`", + args[2].layout.ty + ), + } + } + else { + stripped.parse().unwrap_or_else(|_| { + span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") + }) + }; require_simd!(ret_ty, "return"); @@ -133,6 +203,225 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, )); } + #[cfg(feature="master")] + if name == sym::simd_insert { + require!( + in_elem == arg_tys[2], + "expected inserted type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + arg_tys[2] + ); + let vector = args[0].immediate(); + let index = args[1].immediate(); + let value = args[2].immediate(); + // TODO(antoyo): use a recursive unqualified() here. + let vector_type = vector.get_type().unqualified().dyncast_vector().expect("vector type"); + let element_type = vector_type.get_element_type(); + // NOTE: we cannot cast to an array and assign to its element here because the value might + // not be an l-value. So, call a builtin to set the element. + // TODO(antoyo): perhaps we could create a new vector or maybe there's a GIMPLE instruction for that? + // TODO(antoyo): don't use target specific builtins here. + let func_name = + match in_len { + 2 => { + if element_type == bx.i64_type { + "__builtin_ia32_vec_set_v2di" + } + else { + unimplemented!(); + } + }, + 4 => { + if element_type == bx.i32_type { + "__builtin_ia32_vec_set_v4si" + } + else { + unimplemented!(); + } + }, + 8 => { + if element_type == bx.i16_type { + "__builtin_ia32_vec_set_v8hi" + } + else { + unimplemented!(); + } + }, + _ => unimplemented!("Len: {}", in_len), + }; + let builtin = bx.context.get_target_builtin_function(func_name); + let param1_type = builtin.get_param(0).to_rvalue().get_type(); + // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. + let vector = bx.cx.bitcast_if_needed(vector, param1_type); + let result = bx.context.new_call(None, builtin, &[vector, value, bx.context.new_cast(None, index, bx.int_type)]); + // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. + return Ok(bx.context.new_bitcast(None, result, vector.get_type())); + } + + #[cfg(feature="master")] + if name == sym::simd_extract { + require!( + ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + ret_ty + ); + let vector = args[0].immediate(); + return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue()); + } + + if name == sym::simd_select { + let m_elem_ty = in_elem; + let m_len = in_len; + require_simd!(arg_tys[1], "argument"); + let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); + require!( + m_len == v_len, + "mismatched lengths: mask length `{}` != other vector length `{}`", + m_len, + v_len + ); + match m_elem_ty.kind() { + ty::Int(_) => {} + _ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty), + } + return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate())); + } + + if name == sym::simd_cast { + require_simd!(ret_ty, "return"); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + require!( + in_len == out_len, + "expected return type with length {} (same as input type `{}`), \ + found `{}` with length {}", + in_len, + in_ty, + ret_ty, + out_len + ); + // casting cares about nominal type, not just structural type + if in_elem == out_elem { + return Ok(args[0].immediate()); + } + + enum Style { + Float, + Int(/* is signed? */ bool), + Unsupported, + } + + let (in_style, in_width) = match in_elem.kind() { + // vectors of pointer-sized integers should've been + // disallowed before here, so this unwrap is safe. + ty::Int(i) => ( + Style::Int(true), + i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Uint(u) => ( + Style::Int(false), + u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Float(f) => (Style::Float, f.bit_width()), + _ => (Style::Unsupported, 0), + }; + let (out_style, out_width) = match out_elem.kind() { + ty::Int(i) => ( + Style::Int(true), + i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Uint(u) => ( + Style::Int(false), + u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Float(f) => (Style::Float, f.bit_width()), + _ => (Style::Unsupported, 0), + }; + + let extend = |in_type, out_type| { + let vector_type = bx.context.new_vector_type(out_type, 8); + let vector = args[0].immediate(); + let array_type = bx.context.new_array_type(None, in_type, 8); + // TODO(antoyo): switch to using new_vector_access or __builtin_convertvector for vector casting. + let array = bx.context.new_bitcast(None, vector, array_type); + + let cast_vec_element = |index| { + let index = bx.context.new_rvalue_from_int(bx.int_type, index); + bx.context.new_cast(None, bx.context.new_array_access(None, array, index).to_rvalue(), out_type) + }; + + bx.context.new_rvalue_from_vector(None, vector_type, &[ + cast_vec_element(0), + cast_vec_element(1), + cast_vec_element(2), + cast_vec_element(3), + cast_vec_element(4), + cast_vec_element(5), + cast_vec_element(6), + cast_vec_element(7), + ]) + }; + + match (in_style, out_style) { + (Style::Int(in_is_signed), Style::Int(_)) => { + return Ok(match in_width.cmp(&out_width) { + Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty), + Ordering::Equal => args[0].immediate(), + Ordering::Less => { + if in_is_signed { + match (in_width, out_width) { + // FIXME(antoyo): the function _mm_cvtepi8_epi16 should directly + // call an intrinsic equivalent to __builtin_ia32_pmovsxbw128 so that + // we can generate a call to it. + (8, 16) => extend(bx.i8_type, bx.i16_type), + (8, 32) => extend(bx.i8_type, bx.i32_type), + (8, 64) => extend(bx.i8_type, bx.i64_type), + (16, 32) => extend(bx.i16_type, bx.i32_type), + (32, 64) => extend(bx.i32_type, bx.i64_type), + (16, 64) => extend(bx.i16_type, bx.i64_type), + _ => unimplemented!("in: {}, out: {}", in_width, out_width), + } + } else { + match (in_width, out_width) { + (8, 16) => extend(bx.u8_type, bx.u16_type), + (8, 32) => extend(bx.u8_type, bx.u32_type), + (8, 64) => extend(bx.u8_type, bx.u64_type), + (16, 32) => extend(bx.u16_type, bx.u32_type), + (16, 64) => extend(bx.u16_type, bx.u64_type), + (32, 64) => extend(bx.u32_type, bx.u64_type), + _ => unimplemented!("in: {}, out: {}", in_width, out_width), + } + } + } + }); + } + (Style::Int(_), Style::Float) => { + // TODO: add support for internal functions in libgccjit to get access to IFN_VEC_CONVERT which is + // doing like __builtin_convertvector? + // Or maybe provide convert_vector as an API since it might not easy to get the + // types of internal functions. + unimplemented!(); + } + (Style::Float, Style::Int(_)) => { + unimplemented!(); + } + (Style::Float, Style::Float) => { + unimplemented!(); + } + _ => { /* Unsupported. Fallthrough. */ } + } + require!( + false, + "unsupported cast from `{}` with element `{}` to `{}` with element `{}`", + in_ty, + in_elem, + ret_ty, + out_elem + ); + } + macro_rules! arith_binary { ($($name: ident: $($($p: ident),* => $call: ident),*;)*) => { $(if name == sym::$name { @@ -150,6 +439,102 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, } } + fn simd_simple_float_intrinsic<'gcc, 'tcx>( + name: Symbol, + in_elem: Ty<'_>, + in_ty: Ty<'_>, + in_len: u64, + bx: &mut Builder<'_, 'gcc, 'tcx>, + span: Span, + args: &[OperandRef<'tcx, RValue<'gcc>>], + ) -> Result, ()> { + macro_rules! emit_error { + ($msg: tt, $($fmt: tt)*) => { + span_invalid_monomorphization_error( + bx.sess(), span, + &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg), + name, $($fmt)*)); + } + } + macro_rules! return_error { + ($($fmt: tt)*) => { + { + emit_error!($($fmt)*); + return Err(()); + } + } + } + + let (elem_ty_str, elem_ty) = + if let ty::Float(f) = in_elem.kind() { + let elem_ty = bx.cx.type_float_from_ty(*f); + match f.bit_width() { + 32 => ("f32", elem_ty), + 64 => ("f64", elem_ty), + _ => { + return_error!( + "unsupported element type `{}` of floating-point vector `{}`", + f.name_str(), + in_ty + ); + } + } + } + else { + return_error!("`{}` is not a floating-point type", in_ty); + }; + + let vec_ty = bx.cx.type_vector(elem_ty, in_len); + + let (intr_name, fn_ty) = + match name { + sym::simd_ceil => ("ceil", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fabs => ("fabs", bx.type_func(&[vec_ty], vec_ty)), // TODO(antoyo): pand with 170141183420855150465331762880109871103 + sym::simd_fcos => ("cos", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fexp2 => ("exp2", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fexp => ("exp", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_flog10 => ("log10", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_flog2 => ("log2", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_flog => ("log", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)), + sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)), + sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)), + sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)), + _ => return_error!("unrecognized intrinsic `{}`", name), + }; + let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str); + let function = intrinsic::llvm::intrinsic(llvm_name, &bx.cx); + let function: RValue<'gcc> = unsafe { std::mem::transmute(function) }; + let c = bx.call(fn_ty, function, &args.iter().map(|arg| arg.immediate()).collect::>(), None); + Ok(c) + } + + if std::matches!( + name, + sym::simd_ceil + | sym::simd_fabs + | sym::simd_fcos + | sym::simd_fexp2 + | sym::simd_fexp + | sym::simd_flog10 + | sym::simd_flog2 + | sym::simd_flog + | sym::simd_floor + | sym::simd_fma + | sym::simd_fpow + | sym::simd_fpowi + | sym::simd_fsin + | sym::simd_fsqrt + | sym::simd_round + | sym::simd_trunc + ) { + return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args); + } + arith_binary! { simd_add: Uint, Int => add, Float => fadd; simd_sub: Uint, Int => sub, Float => fsub; @@ -184,5 +569,183 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, simd_neg: Int => neg, Float => fneg; } + #[cfg(feature="master")] + if name == sym::simd_saturating_add || name == sym::simd_saturating_sub { + let lhs = args[0].immediate(); + let rhs = args[1].immediate(); + let is_add = name == sym::simd_saturating_add; + let ptr_bits = bx.tcx().data_layout.pointer_size.bits() as _; + let (signed, elem_width, elem_ty) = match *in_elem.kind() { + ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)), + ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_uint_from_ty(i)), + _ => { + return_error!( + "expected element type `{}` of vector type `{}` \ + to be a signed or unsigned integer type", + arg_tys[0].simd_size_and_type(bx.tcx()).1, + arg_tys[0] + ); + } + }; + let builtin_name = + match (signed, is_add, in_len, elem_width) { + (true, true, 32, 8) => "__builtin_ia32_paddsb256", // TODO(antoyo): cast arguments to unsigned. + (false, true, 32, 8) => "__builtin_ia32_paddusb256", + (true, true, 16, 16) => "__builtin_ia32_paddsw256", + (false, true, 16, 16) => "__builtin_ia32_paddusw256", + (true, false, 16, 16) => "__builtin_ia32_psubsw256", + (false, false, 16, 16) => "__builtin_ia32_psubusw256", + (true, false, 32, 8) => "__builtin_ia32_psubsb256", + (false, false, 32, 8) => "__builtin_ia32_psubusb256", + _ => unimplemented!("signed: {}, is_add: {}, in_len: {}, elem_width: {}", signed, is_add, in_len, elem_width), + }; + let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64); + + let func = bx.context.get_target_builtin_function(builtin_name); + let param1_type = func.get_param(0).to_rvalue().get_type(); + let param2_type = func.get_param(1).to_rvalue().get_type(); + let lhs = bx.cx.bitcast_if_needed(lhs, param1_type); + let rhs = bx.cx.bitcast_if_needed(rhs, param2_type); + let result = bx.context.new_call(None, func, &[lhs, rhs]); + // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. + return Ok(bx.context.new_bitcast(None, result, vec_ty)); + } + + macro_rules! arith_red { + ($name:ident : $vec_op:expr, $float_reduce:ident, $ordered:expr, $op:ident, + $identity:expr) => { + if name == sym::$name { + require!( + ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + ret_ty + ); + return match in_elem.kind() { + ty::Int(_) | ty::Uint(_) => { + let r = bx.vector_reduce_op(args[0].immediate(), $vec_op); + if $ordered { + // if overflow occurs, the result is the + // mathematical result modulo 2^n: + Ok(bx.$op(args[1].immediate(), r)) + } + else { + Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op)) + } + } + ty::Float(_) => { + if $ordered { + // ordered arithmetic reductions take an accumulator + let acc = args[1].immediate(); + Ok(bx.$float_reduce(acc, args[0].immediate())) + } + else { + Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op)) + } + } + _ => return_error!( + "unsupported {} from `{}` with element `{}` to `{}`", + sym::$name, + in_ty, + in_elem, + ret_ty + ), + }; + } + }; + } + + arith_red!( + simd_reduce_add_unordered: BinaryOp::Plus, + vector_reduce_fadd_fast, + false, + add, + 0.0 // TODO: Use this argument. + ); + arith_red!( + simd_reduce_mul_unordered: BinaryOp::Mult, + vector_reduce_fmul_fast, + false, + mul, + 1.0 + ); + + macro_rules! minmax_red { + ($name:ident: $reduction:ident) => { + if name == sym::$name { + require!( + ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + ret_ty + ); + return match in_elem.kind() { + ty::Int(_) | ty::Uint(_) | ty::Float(_) => Ok(bx.$reduction(args[0].immediate())), + _ => return_error!( + "unsupported {} from `{}` with element `{}` to `{}`", + sym::$name, + in_ty, + in_elem, + ret_ty + ), + }; + } + }; + } + + minmax_red!(simd_reduce_min: vector_reduce_min); + minmax_red!(simd_reduce_max: vector_reduce_max); + + macro_rules! bitwise_red { + ($name:ident : $op:expr, $boolean:expr) => { + if name == sym::$name { + let input = if !$boolean { + require!( + ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + ret_ty + ); + args[0].immediate() + } else { + match in_elem.kind() { + ty::Int(_) | ty::Uint(_) => {} + _ => return_error!( + "unsupported {} from `{}` with element `{}` to `{}`", + sym::$name, + in_ty, + in_elem, + ret_ty + ), + } + + // boolean reductions operate on vectors of i1s: + let i1 = bx.type_i1(); + let i1xn = bx.type_vector(i1, in_len as u64); + bx.trunc(args[0].immediate(), i1xn) + }; + return match in_elem.kind() { + ty::Int(_) | ty::Uint(_) => { + let r = bx.vector_reduce_op(input, $op); + Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) }) + } + _ => return_error!( + "unsupported {} from `{}` with element `{}` to `{}`", + sym::$name, + in_ty, + in_elem, + ret_ty + ), + }; + } + }; + } + + bitwise_red!(simd_reduce_and: BinaryOp::BitwiseAnd, false); + bitwise_red!(simd_reduce_or: BinaryOp::BitwiseOr, false); + unimplemented!("simd {}", name); } diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 58996a9db7..5bfdeb8b93 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -203,7 +203,7 @@ impl WriteBackendMethods for GccCodegenBackend { fn run_fat_lto(_cgcx: &CodegenContext, mut modules: Vec>, _cached_modules: Vec<(SerializedModule, WorkProduct)>) -> Result, FatalError> { // TODO(antoyo): implement LTO by sending -flto to libgccjit and adding the appropriate gcc linker plugins. // NOTE: implemented elsewhere. - // TODO: what is implemented elsewhere ^ ? + // TODO(antoyo): what is implemented elsewhere ^ ? let module = match modules.remove(0) { FatLTOInput::InMemory(module) => module, @@ -301,7 +301,22 @@ pub fn target_features(sess: &Session) -> Vec { ) .filter(|_feature| { // TODO(antoyo): implement a way to get enabled feature in libgccjit. - false + // Probably using the equivalent of __builtin_cpu_supports. + #[cfg(feature="master")] + { + _feature.contains("sse") || _feature.contains("avx") + } + #[cfg(not(feature="master"))] + { + false + } + /* + adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512gfni, + avx512ifma, avx512pf, avx512vaes, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpclmulqdq, + avx512vpopcntdq, bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, + sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, xsave, xsavec, xsaveopt, xsaves + */ + //false }) .map(|feature| Symbol::intern(feature)) .collect() diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index e950580852..002b95db36 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/src/type_.rs @@ -3,10 +3,11 @@ use std::convert::TryInto; use gccjit::{RValue, Struct, Type}; use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods}; use rustc_codegen_ssa::common::TypeKind; -use rustc_middle::bug; +use rustc_middle::{bug, ty}; use rustc_middle::ty::layout::TyAndLayout; use rustc_target::abi::{AddressSpace, Align, Integer, Size}; +use crate::common::TypeReflection; use crate::context::CodegenCx; use crate::type_of::LayoutGccExt; @@ -60,6 +61,17 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let ity = Integer::approximate_align(self, align); self.type_from_integer(ity) } + + pub fn type_vector(&self, ty: Type<'gcc>, len: u64) -> Type<'gcc> { + self.context.new_vector_type(ty, len) + } + + pub fn type_float_from_ty(&self, t: ty::FloatTy) -> Type<'gcc> { + match t { + ty::FloatTy::F32 => self.type_f32(), + ty::FloatTy::F64 => self.type_f64(), + } + } } impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { @@ -103,7 +115,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.context.new_function_pointer_type(None, return_type, params, false) } - fn type_struct(&self, fields: &[Type<'gcc>], _packed: bool) -> Type<'gcc> { + fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> { let types = fields.to_vec(); if let Some(typ) = self.struct_types.borrow().get(fields) { return typ.clone(); @@ -111,8 +123,11 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let fields: Vec<_> = fields.iter().enumerate() .map(|(index, field)| self.context.new_field(None, *field, &format!("field{}_TODO", index))) .collect(); - // TODO(antoyo): use packed. let typ = self.context.new_struct_type(None, "struct", &fields).as_type(); + if packed { + #[cfg(feature="master")] + typ.set_packed(); + } self.struct_types.borrow_mut().insert(types, typ); typ } @@ -127,7 +142,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { else if typ.is_compatible_with(self.double_type) { TypeKind::Double } - else if typ.dyncast_vector().is_some() { + else if typ.is_vector() { TypeKind::Vector } else { @@ -141,7 +156,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } fn type_ptr_to_ext(&self, ty: Type<'gcc>, _address_space: AddressSpace) -> Type<'gcc> { - // TODO(antoyo): use address_space + // TODO(antoyo): use address_space, perhaps with TYPE_ADDR_SPACE? ty.make_pointer() } @@ -167,10 +182,10 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn float_width(&self, typ: Type<'gcc>) -> usize { let f32 = self.context.new_type::(); let f64 = self.context.new_type::(); - if typ == f32 { + if typ.is_compatible_with(f32) { 32 } - else if typ == f64 { + else if typ.is_compatible_with(f64) { 64 } else { @@ -197,12 +212,15 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.type_array(self.type_from_integer(unit), size / unit_size) } - pub fn set_struct_body(&self, typ: Struct<'gcc>, fields: &[Type<'gcc>], _packed: bool) { - // TODO(antoyo): use packed. + pub fn set_struct_body(&self, typ: Struct<'gcc>, fields: &[Type<'gcc>], packed: bool) { let fields: Vec<_> = fields.iter().enumerate() .map(|(index, field)| self.context.new_field(None, *field, &format!("field_{}", index))) .collect(); typ.set_fields(None, &fields); + if packed { + #[cfg(feature="master")] + typ.as_type().set_packed(); + } } pub fn type_named_struct(&self, name: &str) -> Struct<'gcc> { @@ -229,6 +247,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.context.new_array_type(None, ty, len) } + + pub fn type_bool(&self) -> Type<'gcc> { + self.context.new_type::() + } } pub fn struct_fields<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout<'tcx>) -> (Vec>, bool) { diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 2c042ba4e3..569ee2925b 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -24,6 +24,30 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { I128 => self.type_u128(), } } + + #[cfg(feature="master")] + pub fn type_int_from_ty(&self, t: ty::IntTy) -> Type<'gcc> { + match t { + ty::IntTy::Isize => self.type_isize(), + ty::IntTy::I8 => self.type_i8(), + ty::IntTy::I16 => self.type_i16(), + ty::IntTy::I32 => self.type_i32(), + ty::IntTy::I64 => self.type_i64(), + ty::IntTy::I128 => self.type_i128(), + } + } + + #[cfg(feature="master")] + pub fn type_uint_from_ty(&self, t: ty::UintTy) -> Type<'gcc> { + match t { + ty::UintTy::Usize => self.type_isize(), + ty::UintTy::U8 => self.type_i8(), + ty::UintTy::U16 => self.type_i16(), + ty::UintTy::U32 => self.type_i32(), + ty::UintTy::U64 => self.type_i64(), + ty::UintTy::U128 => self.type_i128(), + } + } } pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout<'tcx>, defer: &mut Option<(Struct<'gcc>, TyAndLayout<'tcx>)>) -> Type<'gcc> { diff --git a/compiler/rustc_codegen_gcc/test.sh b/compiler/rustc_codegen_gcc/test.sh index 1beeee136d..8b390f95a4 100755 --- a/compiler/rustc_codegen_gcc/test.sh +++ b/compiler/rustc_codegen_gcc/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # TODO(antoyo): rewrite to cargo-make (or just) or something like that to only rebuild the sysroot when needed? @@ -14,25 +14,87 @@ fi export LD_LIBRARY_PATH="$GCC_PATH" export LIBRARY_PATH="$GCC_PATH" -features= - -if [[ "$1" == "--features" ]]; then - shift - features="--features $1" - shift -fi - -if [[ "$1" == "--release" ]]; then +flags= +gcc_master_branch=1 +channel="debug" +func=all +build_only=0 + +while [[ $# -gt 0 ]]; do + case $1 in + --release) + codegen_channel=release + shift + ;; + --release-sysroot) + sysroot_channel=release + shift + ;; + --no-default-features) + gcc_master_branch=0 + flags="$flags --no-default-features" + shift + ;; + --features) + shift + flags="$flags --features $1" + shift + ;; + --release) + channel="release" + shift + ;; + "--test-rustc") + func=test_rustc + shift + ;; + + "--test-libcore") + func=test_libcore + shift + ;; + + "--clean-ui-tests") + func=clean_ui_tests + shift + ;; + + "--std-tests") + func=std_tests + shift + ;; + + "--extended-tests") + func=extended_sysroot_tests + shift + ;; + + "--build-sysroot") + func=build_sysroot + shift + ;; + "--build") + build_only=1 + shift + ;; + *) + echo "Unknown option $1" + exit 1 + ;; + esac +done + +if [[ $channel == "release" ]]; then export CHANNEL='release' - CARGO_INCREMENTAL=1 cargo rustc --release $features + CARGO_INCREMENTAL=1 cargo rustc --release $flags shift else echo $LD_LIBRARY_PATH export CHANNEL='debug' - cargo rustc $features + cargo rustc $flags fi -if [[ "$1" == "--build" ]]; then +if (( $build_only == 1 )); then exit fi @@ -78,7 +140,11 @@ function std_tests() { $RUN_WRAPPER ./target/out/dst_field_align || (echo $?; false) echo "[AOT] std_example" - $RUSTC example/std_example.rs --crate-type bin --target $TARGET_TRIPLE + std_flags="--cfg feature=\"master\"" + if (( $gcc_master_branch == 0 )); then + std_flags="" + fi + $RUSTC example/std_example.rs --crate-type bin --target $TARGET_TRIPLE $std_flags $RUN_WRAPPER ./target/out/std_example --target $TARGET_TRIPLE echo "[AOT] subslice-patterns-const-eval" @@ -97,25 +163,6 @@ function std_tests() { #echo "[BUILD] sysroot in release mode" #./build_sysroot/build_sysroot.sh --release -# TODO(antoyo): uncomment when it works. -#pushd simple-raytracer -#if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then - #echo "[BENCH COMPILE] ebobby/simple-raytracer" - #hyperfine --runs ${RUN_RUNS:-10} --warmup 1 --prepare "rm -r target/*/debug || true" \ - #"RUSTFLAGS='' cargo build --target $TARGET_TRIPLE" \ - #"../cargo.sh build" - - #echo "[BENCH RUN] ebobby/simple-raytracer" - #cp ./target/*/debug/main ./raytracer_cg_gccjit - #hyperfine --runs ${RUN_RUNS:-10} ./raytracer_cg_llvm ./raytracer_cg_gccjit -#else - #echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)" - #echo "[COMPILE] ebobby/simple-raytracer" - #../cargo.sh build - #echo "[BENCH RUN] ebobby/simple-raytracer (skipped)" -#fi -#popd - function test_libcore() { pushd build_sysroot/sysroot_src/library/core/tests echo "[TEST] libcore" @@ -124,19 +171,6 @@ function test_libcore() { popd } -# TODO(antoyo): uncomment when it works. -#pushd regex -#echo "[TEST] rust-lang/regex example shootout-regex-dna" -#../cargo.sh clean -## Make sure `[codegen mono items] start` doesn't poison the diff -#../cargo.sh build --example shootout-regex-dna -#cat examples/regexdna-input.txt | ../cargo.sh run --example shootout-regex-dna | grep -v "Spawned thread" > res.txt -#diff -u res.txt examples/regexdna-output.txt - -#echo "[TEST] rust-lang/regex tests" -#../cargo.sh test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -#popd - #echo #echo "[BENCH COMPILE] mod_bench" @@ -153,6 +187,44 @@ function test_libcore() { #echo "[BENCH RUN] mod_bench" #hyperfine --runs ${RUN_RUNS:-10} ./target/out/mod_bench{,_inline} ./target/out/mod_bench_llvm_* +function extended_sysroot_tests() { + if (( $gcc_master_branch == 0 )); then + return + fi + + pushd rand + cargo clean + echo "[TEST] rust-random/rand" + ../cargo.sh test --workspace + popd + + #pushd simple-raytracer + #echo "[BENCH COMPILE] ebobby/simple-raytracer" + #hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "cargo clean" \ + #"RUSTC=rustc RUSTFLAGS='' cargo build" \ + #"../cargo.sh build" + + #echo "[BENCH RUN] ebobby/simple-raytracer" + #cp ./target/debug/main ./raytracer_cg_gcc + #hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_gcc + #popd + + pushd regex + echo "[TEST] rust-lang/regex example shootout-regex-dna" + cargo clean + export CG_RUSTFLAGS="--cap-lints warn" # newer aho_corasick versions throw a deprecation warning + # Make sure `[codegen mono items] start` doesn't poison the diff + ../cargo.sh build --example shootout-regex-dna + cat examples/regexdna-input.txt \ + | ../cargo.sh run --example shootout-regex-dna \ + | grep -v "Spawned thread" > res.txt + diff -u res.txt examples/regexdna-output.txt + + echo "[TEST] rust-lang/regex tests" + ../cargo.sh test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q + popd +} + function test_rustc() { echo echo "[TEST] rust-lang/rust" @@ -165,23 +237,7 @@ function test_rustc() { git checkout $(rustc -V | cut -d' ' -f3 | tr -d '(') export RUSTFLAGS= - git apply - <( - cfg: Option<&str>, - ) -> test::TestDesc { - let mut ignore = false; - #[cfg(not(bootstrap))] -- let ignore_message: Option = None; -+ let ignore_message: Option<&str> = None; - let mut should_fail = false; - - let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some(); - -EOF + git apply ../rustc_patches/compile_test.patch || true rm config.toml || true @@ -205,7 +261,7 @@ EOF git checkout -- src/test/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed - rm -r src/test/ui/{abi*,extern/,panic-runtime/,panics/,unsized-locals/,proc-macro/,threads-sendsync/,thinlto/,simd*,borrowck/,test*,*lto*.rs} || true + rm -r src/test/ui/{abi*,extern/,panic-runtime/,panics/,unsized-locals/,proc-macro/,threads-sendsync/,thinlto/,borrowck/,test*,*lto*.rs} || true for test in $(rg --files-with-matches "catch_unwind|should_panic|thread|lto" src/test/ui); do rm $test done @@ -222,33 +278,14 @@ function clean_ui_tests() { find rust/build/x86_64-unknown-linux-gnu/test/ui/ -name stamp -exec rm -rf {} \; } -case $1 in - "--test-rustc") - test_rustc - ;; - - "--test-libcore") - test_libcore - ;; - - "--clean-ui-tests") - clean_ui_tests - ;; - - "--std-tests") - std_tests - ;; - - "--build-sysroot") - build_sysroot - ;; - - *) - clean - mini_tests - build_sysroot - std_tests - test_libcore - test_rustc - ;; -esac +function all() { + clean + mini_tests + build_sysroot + std_tests + test_libcore + extended_sysroot_tests + test_rustc +} + +$func diff --git a/compiler/rustc_codegen_gcc/tests/lib.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs similarity index 77% rename from compiler/rustc_codegen_gcc/tests/lib.rs rename to compiler/rustc_codegen_gcc/tests/lang_tests_common.rs index 8ee35b30bc..8e378177e2 100644 --- a/compiler/rustc_codegen_gcc/tests/lib.rs +++ b/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs @@ -1,3 +1,4 @@ +//! The common code for `tests/lang_tests_*.rs` use std::{ env::{self, current_dir}, path::PathBuf, @@ -7,7 +8,15 @@ use std::{ use lang_tester::LangTester; use tempfile::TempDir; -fn main() { +/// Controls the compile options (e.g., optimization level) used to compile +/// test code. +#[allow(dead_code)] // Each test crate picks one variant +pub enum Profile { + Debug, + Release, +} + +pub fn main_inner(profile: Profile) { let tempdir = TempDir::new().expect("temp dir"); let current_dir = current_dir().expect("current dir"); let current_dir = current_dir.to_str().expect("current dir").to_string(); @@ -42,6 +51,15 @@ fn main() { "-o", exe.to_str().expect("to_str"), path.to_str().expect("to_str"), ]); + match profile { + Profile::Debug => {} + Profile::Release => { + compiler.args(&[ + "-C", "opt-level=3", + "-C", "lto=no", + ]); + } + } // Test command 2: run `tempdir/x`. let runtime = Command::new(exe); vec![("Compiler", compiler), ("Run-time", runtime)] diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs new file mode 100644 index 0000000000..96bd74883f --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs @@ -0,0 +1,5 @@ +mod lang_tests_common; + +fn main() { + lang_tests_common::main_inner(lang_tests_common::Profile::Debug); +} diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_release.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_release.rs new file mode 100644 index 0000000000..35d5d60c33 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/lang_tests_release.rs @@ -0,0 +1,5 @@ +mod lang_tests_common; + +fn main() { + lang_tests_common::main_inner(lang_tests_common::Profile::Release); +} diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs index 49376012c4..2b90e4ae8d 100644 --- a/compiler/rustc_codegen_gcc/tests/run/int.rs +++ b/compiler/rustc_codegen_gcc/tests/run/int.rs @@ -3,151 +3,338 @@ // Run-time: // status: 0 -#![feature(arbitrary_self_types, auto_traits, core_intrinsics, lang_items, start, intrinsics)] +#![feature(bench_black_box, const_black_box, core_intrinsics, start)] #![no_std] -mod intrinsics { - extern "rust-intrinsic" { - pub fn abort() -> !; - } +#[panic_handler] +fn panic_handler(_: &core::panic::PanicInfo) -> ! { + core::intrinsics::abort(); } /* - * Core + * Code */ -mod libc { - #[link(name = "c")] - extern "C" { - pub fn puts(s: *const u8) -> i32; +#[start] +fn main(_argc: isize, _argv: *const *const u8) -> isize { + use core::hint::black_box; + + macro_rules! check { + ($ty:ty, $expr:expr) => { + { + const EXPECTED: $ty = $expr; + assert_eq!($expr, EXPECTED); + } + }; } -} -#[panic_handler] -fn panic_handler(_: &core::panic::PanicInfo) -> ! { - unsafe { - core::intrinsics::abort(); + check!(u32, (2220326408_u32 + black_box(1)) >> (32 - 6)); + + /// Generate `check!` tests for integer types at least as wide as 128 bits. + macro_rules! check_ops128 { + () => { + check_ops64!(); + + // Shifts. + check!(T, VAL1 << black_box(64)); + check!(T, VAL1 << black_box(81)); + check!(T, VAL3 << black_box(63)); + check!(T, VAL3 << black_box(64)); + + check!(T, VAL1 >> black_box(64)); + check!(T, VAL2 >> black_box(64)); + check!(T, VAL3 >> black_box(64)); + check!(T, VAL3 >> black_box(81)); + }; } -} -/* - * Code - */ + /// Generate `check!` tests for integer types at least as wide as 64 bits. + macro_rules! check_ops64 { + () => { + check_ops32!(); + + // Shifts. + check!(T, VAL2 << black_box(33)); + check!(T, VAL2 << black_box(49)); + check!(T, VAL2 << black_box(61)); + check!(T, VAL2 << black_box(63)); + + check!(T, VAL3 << black_box(33)); + check!(T, VAL3 << black_box(49)); + check!(T, VAL3 << black_box(61)); + + check!(T, VAL1 >> black_box(33)); + check!(T, VAL1 >> black_box(49)); + check!(T, VAL1 >> black_box(61)); + check!(T, VAL1 >> black_box(63)); + + check!(T, VAL2 >> black_box(33)); + check!(T, VAL2 >> black_box(49)); + check!(T, VAL2 >> black_box(61)); + check!(T, VAL2 >> black_box(63)); + + check!(T, VAL3 >> black_box(33)); + check!(T, VAL3 >> black_box(49)); + check!(T, VAL3 >> black_box(61)); + check!(T, VAL3 >> black_box(63)); + }; + } -#[start] -fn main(argc: isize, _argv: *const *const u8) -> isize { - let var = 134217856_u128; - let var2 = 10475372733397991552_u128; - let var3 = 193236519889708027473620326106273939584_u128; - let var4 = 123236519889708027473620326106273939584_u128; - let var5 = 153236519889708027473620326106273939584_u128; - let var6 = 18446744073709551616_i128; - let var7 = 170141183460469231731687303715884105728_u128; - - // Shifts. - assert_eq!(var << (argc as u128 - 1), var); - assert_eq!(var << argc as u128, 268435712); - assert_eq!(var << (argc + 32) as u128, 1152922604118474752); - assert_eq!(var << (argc + 48) as u128, 75557935783508361347072); - assert_eq!(var << (argc + 60) as u128, 309485304969250248077606912); - assert_eq!(var << (argc + 62) as u128, 1237941219877000992310427648); - assert_eq!(var << (argc + 63) as u128, 2475882439754001984620855296); - assert_eq!(var << (argc + 80) as u128, 324518863143436548128224745357312); - - assert_eq!(var2 << argc as u128, 20950745466795983104); - assert_eq!(var2 << (argc as u128 - 1), var2); - assert_eq!(var2 << (argc + 32) as u128, 89982766606709001335848566784); - assert_eq!(var2 << (argc + 48) as u128, 5897110592337281111546171672756224); - assert_eq!(var2 << (argc + 60) as u128, 24154564986213503432893119171609493504); - assert_eq!(var2 << (argc + 62) as u128, 96618259944854013731572476686437974016); - assert_eq!(var2 << (argc + 63) as u128, 193236519889708027463144953372875948032); - - assert_eq!(var3 << argc as u128, 46190672858477591483866044780779667712); - assert_eq!(var3 << (argc as u128 - 1), var3); - assert_eq!(var3 << (argc + 32) as u128, 21267668304951024224840338247585366016); - assert_eq!(var3 << (argc + 48) as u128, 1335125106377253154015353231953100800); - assert_eq!(var3 << (argc + 60) as u128, 24154564986213503432893119171609493504); - assert_eq!(var3 << (argc + 62) as u128, 96618259944854013731572476686437974016); - assert_eq!(var3 << (argc + 63) as u128, 193236519889708027463144953372875948032); - - assert_eq!((2220326408_u32 + argc as u32) >> (32 - 6), 33); - - assert_eq!(var >> (argc as u128 - 1), var); - assert_eq!(var >> argc as u128, 67108928); - assert_eq!(var >> (argc + 32) as u128, 0); - assert_eq!(var >> (argc + 48) as u128, 0); - assert_eq!(var >> (argc + 60) as u128, 0); - assert_eq!(var >> (argc + 62) as u128, 0); - assert_eq!(var >> (argc + 63) as u128, 0); - - assert_eq!(var2 >> argc as u128, 5237686366698995776); - assert_eq!(var2 >> (argc as u128 - 1), var2); - assert_eq!(var2 >> (argc + 32) as u128, 1219493888); - assert_eq!(var2 >> (argc + 48) as u128, 18608); - assert_eq!(var2 >> (argc + 60) as u128, 4); - assert_eq!(var2 >> (argc + 62) as u128, 1); - assert_eq!(var2 >> (argc + 63) as u128, 0); - - assert_eq!(var3 >> (argc as u128 - 1), var3); - assert_eq!(var3 >> argc as u128, 96618259944854013736810163053136969792); - assert_eq!(var3 >> (argc + 32) as u128, 22495691651677250335181635584); - assert_eq!(var3 >> (argc + 48) as u128, 343257013727985387194544); - assert_eq!(var3 >> (argc + 60) as u128, 83802981867183932420); - assert_eq!(var3 >> (argc + 62) as u128, 20950745466795983105); - assert_eq!(var3 >> (argc + 63) as u128, 10475372733397991552); - assert_eq!(var3 >> (argc + 80) as u128, 79920751444992); - - assert_eq!(var6 >> argc as u128, 9223372036854775808); - assert_eq!((var6 - 1) >> argc as u128, 9223372036854775807); - assert_eq!(var7 >> argc as u128, 85070591730234615865843651857942052864); - - // Casts - assert_eq!((var >> (argc + 32) as u128) as u64, 0); - assert_eq!((var >> argc as u128) as u64, 67108928); - - // Addition. - assert_eq!(var + argc as u128, 134217857); - - assert_eq!(var2 + argc as u128, 10475372733397991553); - assert_eq!(var2 + (var2 + argc as u128) as u128, 20950745466795983105); - - assert_eq!(var3 + argc as u128, 193236519889708027473620326106273939585); - - // Subtraction - assert_eq!(var - argc as u128, 134217855); - - assert_eq!(var2 - argc as u128, 10475372733397991551); - - assert_eq!(var3 - argc as u128, 193236519889708027473620326106273939583); - - // Multiplication - assert_eq!(var * (argc + 1) as u128, 268435712); - assert_eq!(var * (argc as u128 + var2), 1405982069077538020949770368); - - assert_eq!(var2 * (argc + 1) as u128, 20950745466795983104); - assert_eq!(var2 * (argc as u128 + var2), 109733433903618109003204073240861360256); - - assert_eq!(var3 * argc as u128, 193236519889708027473620326106273939584); - - assert_eq!(var4 * (argc + 1) as u128, 246473039779416054947240652212547879168); - - assert_eq!(var5 * (argc + 1) as u128, 306473039779416054947240652212547879168); - - // Division. - assert_eq!(var / (argc + 1) as u128, 67108928); - assert_eq!(var / (argc + 2) as u128, 44739285); - - assert_eq!(var2 / (argc + 1) as u128, 5237686366698995776); - assert_eq!(var2 / (argc + 2) as u128, 3491790911132663850); - - assert_eq!(var3 / (argc + 1) as u128, 96618259944854013736810163053136969792); - assert_eq!(var3 / (argc + 2) as u128, 64412173296569342491206775368757979861); - assert_eq!(var3 / (argc as u128 + var4), 1); - assert_eq!(var3 / (argc as u128 + var2), 18446744073709551615); - - assert_eq!(var4 / (argc + 1) as u128, 61618259944854013736810163053136969792); - assert_eq!(var4 / (argc + 2) as u128, 41078839963236009157873442035424646528); + /// Generate `check!` tests for integer types at least as wide as 32 bits. + macro_rules! check_ops32 { + () => { + // Shifts. + check!(T, VAL2 << black_box(1)); + check!(T, VAL2 << black_box(0)); + + check!(T, VAL3 << black_box(1)); + check!(T, VAL3 << black_box(0)); + + check!(T, VAL1.wrapping_shl(black_box(0))); + check!(T, VAL1.wrapping_shl(black_box(1))); + check!(T, VAL1.wrapping_shl(black_box(33))); + check!(T, VAL1.wrapping_shl(black_box(49))); + check!(T, VAL1.wrapping_shl(black_box(61))); + check!(T, VAL1.wrapping_shl(black_box(63))); + check!(T, VAL1.wrapping_shl(black_box(64))); + check!(T, VAL1.wrapping_shl(black_box(81))); + + check!(Option, VAL1.checked_shl(black_box(0))); + check!(Option, VAL1.checked_shl(black_box(1))); + check!(Option, VAL1.checked_shl(black_box(33))); + check!(Option, VAL1.checked_shl(black_box(49))); + check!(Option, VAL1.checked_shl(black_box(61))); + check!(Option, VAL1.checked_shl(black_box(63))); + check!(Option, VAL1.checked_shl(black_box(64))); + check!(Option, VAL1.checked_shl(black_box(81))); + + check!(T, VAL1 >> black_box(0)); + check!(T, VAL1 >> black_box(1)); + + check!(T, VAL2 >> black_box(1)); + check!(T, VAL2 >> black_box(0)); + + check!(T, VAL3 >> black_box(0)); + check!(T, VAL3 >> black_box(1)); + + check!(T, VAL1.wrapping_shr(black_box(0))); + check!(T, VAL1.wrapping_shr(black_box(1))); + check!(T, VAL1.wrapping_shr(black_box(33))); + check!(T, VAL1.wrapping_shr(black_box(49))); + check!(T, VAL1.wrapping_shr(black_box(61))); + check!(T, VAL1.wrapping_shr(black_box(63))); + check!(T, VAL1.wrapping_shr(black_box(64))); + check!(T, VAL1.wrapping_shr(black_box(81))); + + check!(Option, VAL1.checked_shr(black_box(0))); + check!(Option, VAL1.checked_shr(black_box(1))); + check!(Option, VAL1.checked_shr(black_box(33))); + check!(Option, VAL1.checked_shr(black_box(49))); + check!(Option, VAL1.checked_shr(black_box(61))); + check!(Option, VAL1.checked_shr(black_box(63))); + check!(Option, VAL1.checked_shr(black_box(64))); + check!(Option, VAL1.checked_shr(black_box(81))); + + // Casts + check!(u64, (VAL1 >> black_box(1)) as u64); + + // Addition. + check!(T, VAL1 + black_box(1)); + check!(T, VAL2 + black_box(1)); + check!(T, VAL2 + (VAL2 + black_box(1))); + check!(T, VAL3 + black_box(1)); + + check!(Option, VAL1.checked_add(black_box(1))); + check!(Option, VAL2.checked_add(black_box(1))); + check!(Option, VAL2.checked_add(VAL2 + black_box(1))); + check!(Option, VAL3.checked_add(T::MAX)); + check!(Option, VAL3.checked_add(T::MIN)); + + check!(T, VAL1.wrapping_add(black_box(1))); + check!(T, VAL2.wrapping_add(black_box(1))); + check!(T, VAL2.wrapping_add(VAL2 + black_box(1))); + check!(T, VAL3.wrapping_add(T::MAX)); + check!(T, VAL3.wrapping_add(T::MIN)); + + check!((T, bool), VAL1.overflowing_add(black_box(1))); + check!((T, bool), VAL2.overflowing_add(black_box(1))); + check!((T, bool), VAL2.overflowing_add(VAL2 + black_box(1))); + check!((T, bool), VAL3.overflowing_add(T::MAX)); + check!((T, bool), VAL3.overflowing_add(T::MIN)); + + check!(T, VAL1.saturating_add(black_box(1))); + check!(T, VAL2.saturating_add(black_box(1))); + check!(T, VAL2.saturating_add(VAL2 + black_box(1))); + check!(T, VAL3.saturating_add(T::MAX)); + check!(T, VAL3.saturating_add(T::MIN)); + + // Subtraction + check!(T, VAL1 - black_box(1)); + check!(T, VAL2 - black_box(1)); + check!(T, VAL3 - black_box(1)); + + check!(Option, VAL1.checked_sub(black_box(1))); + check!(Option, VAL2.checked_sub(black_box(1))); + check!(Option, VAL2.checked_sub(VAL2 + black_box(1))); + check!(Option, VAL3.checked_sub(T::MAX)); + check!(Option, VAL3.checked_sub(T::MIN)); + + check!(T, VAL1.wrapping_sub(black_box(1))); + check!(T, VAL2.wrapping_sub(black_box(1))); + check!(T, VAL2.wrapping_sub(VAL2 + black_box(1))); + check!(T, VAL3.wrapping_sub(T::MAX)); + check!(T, VAL3.wrapping_sub(T::MIN)); + + check!((T, bool), VAL1.overflowing_sub(black_box(1))); + check!((T, bool), VAL2.overflowing_sub(black_box(1))); + check!((T, bool), VAL2.overflowing_sub(VAL2 + black_box(1))); + check!((T, bool), VAL3.overflowing_sub(T::MAX)); + check!((T, bool), VAL3.overflowing_sub(T::MIN)); + + check!(T, VAL1.saturating_sub(black_box(1))); + check!(T, VAL2.saturating_sub(black_box(1))); + check!(T, VAL2.saturating_sub(VAL2 + black_box(1))); + check!(T, VAL3.saturating_sub(T::MAX)); + check!(T, VAL3.saturating_sub(T::MIN)); + + // Multiplication + check!(T, VAL1 * black_box(2)); + check!(T, VAL1 * (black_box(1) + VAL2)); + check!(T, VAL2 * black_box(2)); + check!(T, VAL2 * (black_box(1) + VAL2)); + check!(T, VAL3 * black_box(1)); + check!(T, VAL4 * black_box(2)); + check!(T, VAL5 * black_box(2)); + + check!(Option, VAL1.checked_mul(black_box(2))); + check!(Option, VAL1.checked_mul(black_box(1) + VAL2)); + check!(Option, VAL3.checked_mul(VAL3)); + check!(Option, VAL4.checked_mul(black_box(2))); + check!(Option, VAL5.checked_mul(black_box(2))); + + check!(T, VAL1.wrapping_mul(black_box(2))); + check!(T, VAL1.wrapping_mul((black_box(1) + VAL2))); + check!(T, VAL3.wrapping_mul(VAL3)); + check!(T, VAL4.wrapping_mul(black_box(2))); + check!(T, VAL5.wrapping_mul(black_box(2))); + + check!((T, bool), VAL1.overflowing_mul(black_box(2))); + check!((T, bool), VAL1.overflowing_mul(black_box(1) + VAL2)); + check!((T, bool), VAL3.overflowing_mul(VAL3)); + check!((T, bool), VAL4.overflowing_mul(black_box(2))); + check!((T, bool), VAL5.overflowing_mul(black_box(2))); + + check!(T, VAL1.saturating_mul(black_box(2))); + check!(T, VAL1.saturating_mul(black_box(1) + VAL2)); + check!(T, VAL3.saturating_mul(VAL3)); + check!(T, VAL4.saturating_mul(black_box(2))); + check!(T, VAL5.saturating_mul(black_box(2))); + + // Division. + check!(T, VAL1 / black_box(2)); + check!(T, VAL1 / black_box(3)); + + check!(T, VAL2 / black_box(2)); + check!(T, VAL2 / black_box(3)); + + check!(T, VAL3 / black_box(2)); + check!(T, VAL3 / black_box(3)); + check!(T, VAL3 / (black_box(1) + VAL4)); + check!(T, VAL3 / (black_box(1) + VAL2)); + + check!(T, VAL4 / black_box(2)); + check!(T, VAL4 / black_box(3)); + + check!(Option, VAL1.checked_div(black_box(2))); + check!(Option, VAL1.checked_div(black_box(1) + VAL2)); + check!(Option, VAL3.checked_div(VAL3)); + check!(Option, VAL4.checked_div(black_box(2))); + check!(Option, VAL5.checked_div(black_box(2))); + check!(Option, (T::MIN).checked_div(black_box(0 as T).wrapping_sub(1))); + check!(Option, VAL5.checked_div(black_box(0))); // var5 / 0 + + check!(T, VAL1.wrapping_div(black_box(2))); + check!(T, VAL1.wrapping_div(black_box(1) + VAL2)); + check!(T, VAL3.wrapping_div(VAL3)); + check!(T, VAL4.wrapping_div(black_box(2))); + check!(T, VAL5.wrapping_div(black_box(2))); + check!(T, (T::MIN).wrapping_div(black_box(0 as T).wrapping_sub(1))); + + check!((T, bool), VAL1.overflowing_div(black_box(2))); + check!((T, bool), VAL1.overflowing_div(black_box(1) + VAL2)); + check!((T, bool), VAL3.overflowing_div(VAL3)); + check!((T, bool), VAL4.overflowing_div(black_box(2))); + check!((T, bool), VAL5.overflowing_div(black_box(2))); + check!((T, bool), (T::MIN).overflowing_div(black_box(0 as T).wrapping_sub(1))); + + check!(T, VAL1.saturating_div(black_box(2))); + check!(T, VAL1.saturating_div((black_box(1) + VAL2))); + check!(T, VAL3.saturating_div(VAL3)); + check!(T, VAL4.saturating_div(black_box(2))); + check!(T, VAL5.saturating_div(black_box(2))); + check!(T, (T::MIN).saturating_div((0 as T).wrapping_sub(black_box(1)))); + }; + } + + { + type T = u32; + const VAL1: T = 14162_u32; + const VAL2: T = 14556_u32; + const VAL3: T = 323656954_u32; + const VAL4: T = 2023651954_u32; + const VAL5: T = 1323651954_u32; + check_ops32!(); + } + + { + type T = i32; + const VAL1: T = 13456_i32; + const VAL2: T = 10475_i32; + const VAL3: T = 923653954_i32; + const VAL4: T = 993198738_i32; + const VAL5: T = 1023653954_i32; + check_ops32!(); + } + + { + type T = u64; + const VAL1: T = 134217856_u64; + const VAL2: T = 104753732_u64; + const VAL3: T = 12323651988970863954_u64; + const VAL4: T = 7323651988970863954_u64; + const VAL5: T = 8323651988970863954_u64; + check_ops64!(); + } + + { + type T = i64; + const VAL1: T = 134217856_i64; + const VAL2: T = 104753732_i64; + const VAL3: T = 6323651988970863954_i64; + const VAL4: T = 2323651988970863954_i64; + const VAL5: T = 3323651988970863954_i64; + check_ops64!(); + } + + { + type T = u128; + const VAL1: T = 134217856_u128; + const VAL2: T = 10475372733397991552_u128; + const VAL3: T = 193236519889708027473620326106273939584_u128; + const VAL4: T = 123236519889708027473620326106273939584_u128; + const VAL5: T = 153236519889708027473620326106273939584_u128; + check_ops128!(); + } + { + type T = i128; + const VAL1: T = 134217856_i128; + const VAL2: T = 10475372733397991552_i128; + const VAL3: T = 83236519889708027473620326106273939584_i128; + const VAL4: T = 63236519889708027473620326106273939584_i128; + const VAL5: T = 73236519889708027473620326106273939584_i128; + check_ops128!(); + } 0 } diff --git a/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs b/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs index 6477b83982..ea2c5add96 100644 --- a/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs +++ b/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs @@ -1,7 +1,7 @@ // Compiler: // // Run-time: -// stdout: Panicking +// stdout: Success // status: signal #![allow(unused_attributes)] @@ -64,7 +64,9 @@ mod intrinsics { #[no_mangle] pub fn panic(_msg: &str) -> ! { unsafe { - libc::puts("Panicking\0" as *const str as *const u8); + // Panicking is expected iff overflow checking is enabled. + #[cfg(debug_assertions)] + libc::puts("Success\0" as *const str as *const u8); libc::fflush(libc::stdout); intrinsics::abort(); } @@ -124,6 +126,15 @@ impl Add for isize { #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { let int = 9223372036854775807isize; - let int = int + argc; + let int = int + argc; // overflow + + // If overflow checking is disabled, we should reach here. + #[cfg(not(debug_assertions))] + unsafe { + libc::puts("Success\0" as *const str as *const u8); + libc::fflush(libc::stdout); + intrinsics::abort(); + } + int } diff --git a/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py b/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py new file mode 100644 index 0000000000..849c6e9c98 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py @@ -0,0 +1,238 @@ +import json +import os +import re +import sys +import subprocess +from os import walk + + +def run_command(command, cwd=None): + p = subprocess.Popen(command, cwd=cwd) + if p.wait() != 0: + print("command `{}` failed...".format(" ".join(command))) + sys.exit(1) + + +def clone_repository(repo_name, path, repo_url, sub_path=None): + if os.path.exists(path): + while True: + choice = input("There is already a `{}` folder, do you want to update it? [y/N]".format(path)) + if choice == "" or choice.lower() == "n": + print("Skipping repository update.") + return + elif choice.lower() == "y": + print("Updating repository...") + run_command(["git", "pull", "origin"], cwd=path) + return + else: + print("Didn't understand answer...") + print("Cloning {} repository...".format(repo_name)) + if sub_path is None: + run_command(["git", "clone", repo_url, "--depth", "1", path]) + else: + run_command(["git", "clone", repo_url, "--filter=tree:0", "--no-checkout", path]) + run_command(["git", "sparse-checkout", "init"], cwd=path) + run_command(["git", "sparse-checkout", "set", "add", sub_path], cwd=path) + run_command(["git", "checkout"], cwd=path) + + +def append_intrinsic(array, intrinsic_name, translation): + array.append((intrinsic_name, translation)) + + +def extract_instrinsics(intrinsics, file): + print("Extracting intrinsics from `{}`...".format(file)) + with open(file, "r", encoding="utf8") as f: + content = f.read() + + lines = content.splitlines() + pos = 0 + current_arch = None + while pos < len(lines): + line = lines[pos].strip() + if line.startswith("let TargetPrefix ="): + current_arch = line.split('"')[1].strip() + if len(current_arch) == 0: + current_arch = None + elif current_arch is None: + pass + elif line == "}": + current_arch = None + elif line.startswith("def "): + content = "" + while not content.endswith(";") and not content.endswith("}") and pos < len(lines): + line = lines[pos].split(" // ")[0].strip() + content += line + pos += 1 + entries = re.findall('GCCBuiltin<"(\\w+)">', content) + if len(entries) > 0: + intrinsic = content.split("def ")[1].strip().split(":")[0].strip() + intrinsic = intrinsic.split("_") + if len(intrinsic) < 2 or intrinsic[0] != "int": + continue + intrinsic[0] = "llvm" + intrinsic = ".".join(intrinsic) + if current_arch not in intrinsics: + intrinsics[current_arch] = [] + for entry in entries: + append_intrinsic(intrinsics[current_arch], intrinsic, entry) + continue + pos += 1 + continue + print("Done!") + + +def extract_instrinsics_from_llvm(llvm_path, intrinsics): + files = [] + intrinsics_path = os.path.join(llvm_path, "llvm/include/llvm/IR") + for (dirpath, dirnames, filenames) in walk(intrinsics_path): + files.extend([os.path.join(intrinsics_path, f) for f in filenames if f.endswith(".td")]) + + for file in files: + extract_instrinsics(intrinsics, file) + + +def append_translation(json_data, p, array): + it = json_data["index"][p] + content = it["docs"].split('`') + if len(content) != 5: + return + append_intrinsic(array, content[1], content[3]) + + +def extract_instrinsics_from_llvmint(llvmint, intrinsics): + archs = [ + "AMDGPU", + "aarch64", + "arm", + "cuda", + "hexagon", + "mips", + "nvvm", + "ppc", + "ptx", + "x86", + "xcore", + ] + + json_file = os.path.join(llvmint, "target/doc/llvmint.json") + # We need to regenerate the documentation! + run_command( + ["cargo", "rustdoc", "--", "-Zunstable-options", "--output-format", "json"], + cwd=llvmint, + ) + with open(json_file, "r", encoding="utf8") as f: + json_data = json.loads(f.read()) + for p in json_data["paths"]: + it = json_data["paths"][p] + if it["crate_id"] != 0: + # This is from an external crate. + continue + if it["kind"] != "function": + # We're only looking for functions. + continue + # if len(it["path"]) == 2: + # # This is a "general" intrinsic, not bound to a specific arch. + # append_translation(json_data, p, general) + # continue + if len(it["path"]) != 3 or it["path"][1] not in archs: + continue + arch = it["path"][1] + if arch not in intrinsics: + intrinsics[arch] = [] + append_translation(json_data, p, intrinsics[arch]) + + +def fill_intrinsics(intrinsics, from_intrinsics, all_intrinsics): + for arch in from_intrinsics: + if arch not in intrinsics: + intrinsics[arch] = [] + for entry in from_intrinsics[arch]: + if entry[0] in all_intrinsics: + if all_intrinsics[entry[0]] == entry[1]: + # This is a "full" duplicate, both the LLVM instruction and the GCC + # translation are the same. + continue + intrinsics[arch].append((entry[0], entry[1], True)) + else: + intrinsics[arch].append((entry[0], entry[1], False)) + all_intrinsics[entry[0]] = entry[1] + + +def update_intrinsics(llvm_path, llvmint, llvmint2): + intrinsics_llvm = {} + intrinsics_llvmint = {} + all_intrinsics = {} + + extract_instrinsics_from_llvm(llvm_path, intrinsics_llvm) + extract_instrinsics_from_llvmint(llvmint, intrinsics_llvmint) + extract_instrinsics_from_llvmint(llvmint2, intrinsics_llvmint) + + intrinsics = {} + # We give priority to translations from LLVM over the ones from llvmint. + fill_intrinsics(intrinsics, intrinsics_llvm, all_intrinsics) + fill_intrinsics(intrinsics, intrinsics_llvmint, all_intrinsics) + + archs = [arch for arch in intrinsics] + archs.sort() + + output_file = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "../src/intrinsic/archs.rs", + ) + print("Updating content of `{}`...".format(output_file)) + with open(output_file, "w", encoding="utf8") as out: + out.write("// File generated by `rustc_codegen_gcc/tools/generate_intrinsics.py`\n") + out.write("// DO NOT EDIT IT!\n") + out.write("match name {\n") + for arch in archs: + if len(intrinsics[arch]) == 0: + continue + intrinsics[arch].sort(key=lambda x: (x[0], x[2])) + out.write(' // {}\n'.format(arch)) + for entry in intrinsics[arch]: + if entry[2] == True: # if it is a duplicate + out.write(' // [DUPLICATE]: "{}" => "{}",\n'.format(entry[0], entry[1])) + else: + out.write(' "{}" => "{}",\n'.format(entry[0], entry[1])) + out.write(' _ => unimplemented!("***** unsupported LLVM intrinsic {}", name),\n') + out.write("}\n") + print("Done!") + + +def main(): + llvm_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "llvm-project", + ) + llvmint_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "llvmint", + ) + llvmint2_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "llvmint-2", + ) + + # First, we clone the LLVM repository if it's not already here. + clone_repository( + "llvm-project", + llvm_path, + "https://github.com/llvm/llvm-project", + sub_path="llvm/include/llvm/IR", + ) + clone_repository( + "llvmint", + llvmint_path, + "https://github.com/GuillaumeGomez/llvmint", + ) + clone_repository( + "llvmint2", + llvmint2_path, + "https://github.com/antoyo/llvmint", + ) + update_intrinsics(llvm_path, llvmint_path, llvmint2_path) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 67183ff588..b486af1337 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -16,9 +16,9 @@ measureme = "10.0.0" tracing = "0.1" rustc_middle = { path = "../rustc_middle" } rustc-demangle = "0.1.21" -rustc_arena = { path = "../rustc_arena" } rustc_attr = { path = "../rustc_attr" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } +rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fs_util = { path = "../rustc_fs_util" } diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index b9baa87bac..cc8b3a1a4e 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -393,6 +393,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { 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, diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index e994001f96..a53946995e 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -604,7 +604,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> InlineAsmRegClass::X86( X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg - | X86InlineAsmRegClass::kreg0, + | X86InlineAsmRegClass::kreg0 + | X86InlineAsmRegClass::tmm_reg, ) => unreachable!("clobber-only"), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", @@ -692,7 +693,8 @@ fn modifier_to_llvm( InlineAsmRegClass::X86( X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg - | X86InlineAsmRegClass::kreg0, + | X86InlineAsmRegClass::kreg0 + | X86InlineAsmRegClass::tmm_reg, ) => { unreachable!("clobber-only") } @@ -766,7 +768,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' InlineAsmRegClass::X86( X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg - | X86InlineAsmRegClass::kreg0, + | X86InlineAsmRegClass::kreg0 + | X86InlineAsmRegClass::tmm_reg, ) => { unreachable!("clobber-only") } diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 8f6438e85a..da9d8b5fb3 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -15,19 +15,12 @@ use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_session::cstore::{DllCallingConvention, DllImport}; use rustc_session::Session; -struct ArchiveConfig<'a> { - pub sess: &'a Session, - pub dst: PathBuf, - pub src: Option, -} - /// Helper for adding many files to an archive. #[must_use = "must call build() to finish building the archive"] pub struct LlvmArchiveBuilder<'a> { - config: ArchiveConfig<'a>, - removals: Vec, + sess: &'a Session, + dst: PathBuf, additions: Vec, - src_archive: Option>, } enum Addition { @@ -50,10 +43,6 @@ fn is_relevant_child(c: &Child<'_>) -> bool { } } -fn archive_config<'a>(sess: &'a Session, output: &Path, input: Option<&Path>) -> ArchiveConfig<'a> { - ArchiveConfig { sess, dst: output.to_path_buf(), src: input.map(|p| p.to_path_buf()) } -} - /// Map machine type strings to values of LLVM's MachineTypes enum. fn llvm_machine_type(cpu: &str) -> LLVMMachineType { match cpu { @@ -68,37 +57,8 @@ fn llvm_machine_type(cpu: &str) -> LLVMMachineType { impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { /// Creates a new static archive, ready for modifying the archive specified /// by `config`. - fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> LlvmArchiveBuilder<'a> { - let config = archive_config(sess, output, input); - LlvmArchiveBuilder { - config, - removals: Vec::new(), - additions: Vec::new(), - src_archive: None, - } - } - - /// Removes a file from this archive - fn remove_file(&mut self, file: &str) { - self.removals.push(file.to_string()); - } - - /// Lists all files in an archive - fn src_files(&mut self) -> Vec { - if self.src_archive().is_none() { - return Vec::new(); - } - - let archive = self.src_archive.as_ref().unwrap().as_ref().unwrap(); - - archive - .iter() - .filter_map(|child| child.ok()) - .filter(is_relevant_child) - .filter_map(|child| child.name()) - .filter(|name| !self.removals.iter().any(|x| x == name)) - .map(|name| name.to_owned()) - .collect() + fn new(sess: &'a Session, output: &Path) -> LlvmArchiveBuilder<'a> { + LlvmArchiveBuilder { sess, dst: output.to_path_buf(), additions: Vec::new() } } fn add_archive(&mut self, archive: &Path, skip: F) -> io::Result<()> @@ -129,13 +89,10 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { /// Combine the provided files, rlibs, and native libraries into a single /// `Archive`. - fn build(mut self) { - let kind = self.llvm_archive_kind().unwrap_or_else(|kind| { - self.config.sess.fatal(&format!("Don't know how to build archive of type: {}", kind)) - }); - - if let Err(e) = self.build_with_llvm(kind) { - self.config.sess.fatal(&format!("failed to build archive: {}", e)); + fn build(mut self) -> bool { + match self.build_with_llvm() { + Ok(any_members) => any_members, + Err(e) => self.sess.fatal(&format!("failed to build archive: {}", e)), } } @@ -151,7 +108,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { output_path.with_extension("lib") }; - let target = &self.config.sess.target; + let target = &self.sess.target; let mingw_gnu_toolchain = target.vendor == "pc" && target.os == "windows" && target.env == "gnu" @@ -160,7 +117,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { let import_name_and_ordinal_vector: Vec<(String, Option)> = dll_imports .iter() .map(|import: &DllImport| { - if self.config.sess.target.arch == "x86" { + if self.sess.target.arch == "x86" { ( LlvmArchiveBuilder::i686_decorated_name(import, mingw_gnu_toolchain), import.ordinal, @@ -197,11 +154,11 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { match std::fs::write(&def_file_path, def_file_content) { Ok(_) => {} Err(e) => { - self.config.sess.fatal(&format!("Error writing .DEF file: {}", e)); + self.sess.fatal(&format!("Error writing .DEF file: {}", e)); } }; - let dlltool = find_binutils_dlltool(self.config.sess); + let dlltool = find_binutils_dlltool(self.sess); let result = std::process::Command::new(dlltool) .args([ "-d", @@ -215,9 +172,9 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { match result { Err(e) => { - self.config.sess.fatal(&format!("Error calling dlltool: {}", e)); + self.sess.fatal(&format!("Error calling dlltool: {}", e)); } - Ok(output) if !output.status.success() => self.config.sess.fatal(&format!( + Ok(output) if !output.status.success() => self.sess.fatal(&format!( "Dlltool could not create import library: {}\n{}", String::from_utf8_lossy(&output.stdout), String::from_utf8_lossy(&output.stderr) @@ -263,13 +220,13 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { output_path_z.as_ptr(), ffi_exports.as_ptr(), ffi_exports.len(), - llvm_machine_type(&self.config.sess.target.arch) as u16, - !self.config.sess.target.is_like_msvc, + llvm_machine_type(&self.sess.target.arch) as u16, + !self.sess.target.is_like_msvc, ) }; if result == crate::llvm::LLVMRustResult::Failure { - self.config.sess.fatal(&format!( + self.sess.fatal(&format!( "Error creating import library for {}: {}", lib_name, llvm::last_error().unwrap_or("unknown LLVM error".to_string()) @@ -278,7 +235,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { }; self.add_archive(&output_path, |_| false).unwrap_or_else(|e| { - self.config.sess.fatal(&format!( + self.sess.fatal(&format!( "failed to add native library {}: {}", output_path.display(), e @@ -288,46 +245,19 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { } impl<'a> LlvmArchiveBuilder<'a> { - fn src_archive(&mut self) -> Option<&ArchiveRO> { - if let Some(ref a) = self.src_archive { - return a.as_ref(); - } - let src = self.config.src.as_ref()?; - self.src_archive = Some(ArchiveRO::open(src).ok()); - self.src_archive.as_ref().unwrap().as_ref() - } - - fn llvm_archive_kind(&self) -> Result { - let kind = &*self.config.sess.target.archive_format; - kind.parse().map_err(|_| kind) - } + fn build_with_llvm(&mut self) -> io::Result { + let kind = &*self.sess.target.archive_format; + let kind = kind.parse::().map_err(|_| kind).unwrap_or_else(|kind| { + self.sess.fatal(&format!("Don't know how to build archive of type: {}", kind)) + }); - fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> { - let removals = mem::take(&mut self.removals); let mut additions = mem::take(&mut self.additions); let mut strings = Vec::new(); let mut members = Vec::new(); - let dst = CString::new(self.config.dst.to_str().unwrap())?; + let dst = CString::new(self.dst.to_str().unwrap())?; unsafe { - if let Some(archive) = self.src_archive() { - for child in archive.iter() { - let child = child.map_err(string_to_io_error)?; - let Some(child_name) = child.name() else { continue }; - if removals.iter().any(|r| r == child_name) { - continue; - } - - let name = CString::new(child_name)?; - members.push(llvm::LLVMRustArchiveMemberNew( - ptr::null(), - name.as_ptr(), - Some(child.raw), - )); - strings.push(name); - } - } for addition in &mut additions { match addition { Addition::File { path, name_in_archive } => { @@ -389,7 +319,7 @@ impl<'a> LlvmArchiveBuilder<'a> { }; Err(io::Error::new(io::ErrorKind::Other, msg)) } else { - Ok(()) + Ok(!members.is_empty()) }; for member in members { llvm::LLVMRustArchiveMemberFree(member); diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index d0724baf9e..38402e0431 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -354,14 +354,14 @@ fn fat_lto( Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: serialized_bitcode }) } -crate struct Linker<'a>(&'a mut llvm::Linker<'a>); +pub(crate) struct Linker<'a>(&'a mut llvm::Linker<'a>); impl<'a> Linker<'a> { - crate fn new(llmod: &'a llvm::Module) -> Self { + pub(crate) fn new(llmod: &'a llvm::Module) -> Self { unsafe { Linker(llvm::LLVMRustLinkerNew(llmod)) } } - crate fn add(&mut self, bytecode: &[u8]) -> Result<(), ()> { + pub(crate) fn add(&mut self, bytecode: &[u8]) -> Result<(), ()> { unsafe { if llvm::LLVMRustLinkerAdd( self.0, @@ -586,9 +586,21 @@ pub(crate) fn run_pass_manager( // LTO-specific optimization passes that LLVM provides. // // This code is based off the code found in llvm's LTO code generator: - // tools/lto/LTOCodeGenerator.cpp + // llvm/lib/LTO/LTOCodeGenerator.cpp debug!("running the pass manager"); unsafe { + if !llvm::LLVMRustHasModuleFlag( + module.module_llvm.llmod(), + "LTOPostLink".as_ptr().cast(), + 11, + ) { + llvm::LLVMRustAddModuleFlag( + module.module_llvm.llmod(), + llvm::LLVMModFlagBehavior::Error, + "LTOPostLink\0".as_ptr().cast(), + 1, + ); + } if llvm_util::should_use_new_llvm_pass_manager( &config.new_llvm_pass_manager, &cgcx.target_arch, diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 99e30531c2..ab8874d796 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -56,28 +56,24 @@ pub fn write_output_file<'ll>( file_type: llvm::FileType, self_profiler_ref: &SelfProfilerRef, ) -> Result<(), FatalError> { + debug!("write_output_file output={:?} dwo_output={:?}", output, dwo_output); unsafe { let output_c = path_to_c_string(output); - let result = if let Some(dwo_output) = dwo_output { - let dwo_output_c = path_to_c_string(dwo_output); - llvm::LLVMRustWriteOutputFile( - target, - pm, - m, - output_c.as_ptr(), - dwo_output_c.as_ptr(), - file_type, - ) + let dwo_output_c; + let dwo_output_ptr = if let Some(dwo_output) = dwo_output { + dwo_output_c = path_to_c_string(dwo_output); + dwo_output_c.as_ptr() } else { - llvm::LLVMRustWriteOutputFile( - target, - pm, - m, - output_c.as_ptr(), - std::ptr::null(), - file_type, - ) + std::ptr::null() }; + let result = llvm::LLVMRustWriteOutputFile( + target, + pm, + m, + output_c.as_ptr(), + dwo_output_ptr, + file_type, + ); // Record artifact sizes for self-profiling if result == llvm::LLVMRustResult::Success { @@ -340,7 +336,7 @@ fn report_inline_asm( } let level = match level { llvm::DiagnosticLevel::Error => Level::Error { lint: false }, - llvm::DiagnosticLevel::Warning => Level::Warning, + llvm::DiagnosticLevel::Warning => Level::Warning(None), llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note, }; cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, level, source); @@ -467,7 +463,7 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager( let llvm_selfprofiler = llvm_profiler.as_mut().map(|s| s as *mut _ as *mut c_void).unwrap_or(std::ptr::null_mut()); - let extra_passes = config.passes.join(","); + let extra_passes = if !is_lto { config.passes.join(",") } else { "".to_string() }; let llvm_plugins = config.llvm_plugins.join(","); @@ -1040,7 +1036,8 @@ unsafe fn embed_bitcode( // reason (see issue #90326 for historical background). let is_apple = cgcx.opts.target_triple.triple().contains("-ios") || cgcx.opts.target_triple.triple().contains("-darwin") - || cgcx.opts.target_triple.triple().contains("-tvos"); + || cgcx.opts.target_triple.triple().contains("-tvos") + || cgcx.opts.target_triple.triple().contains("-watchos"); if is_apple || cgcx.opts.target_triple.triple().starts_with("wasm") || cgcx.opts.target_triple.triple().starts_with("asmjs") diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 88b87951ec..c41a41980e 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -509,15 +509,20 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { OperandValue::Ref(place.llval, Some(llextra), place.align) } else if place.layout.is_llvm_immediate() { let mut const_llval = None; + let llty = place.layout.llvm_type(self); unsafe { if let Some(global) = llvm::LLVMIsAGlobalVariable(place.llval) { if llvm::LLVMIsGlobalConstant(global) == llvm::True { - const_llval = llvm::LLVMGetInitializer(global); + if let Some(init) = llvm::LLVMGetInitializer(global) { + if self.val_ty(init) == llty { + const_llval = Some(init); + } + } } } } let llval = const_llval.unwrap_or_else(|| { - let load = self.load(place.layout.llvm_type(self), place.llval, place.align); + let load = self.load(llty, place.llval, place.align); if let abi::Abi::Scalar(scalar) = place.layout.abi { scalar_load_metadata(self, load, scalar, place.layout, Size::ZERO); } @@ -1412,7 +1417,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) } } - crate fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value { + pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value { let (ty, f) = self.cx.get_intrinsic(intrinsic); self.call(ty, f, args, None) } diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 4d3f3f318b..5bbbfe9a4a 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -212,11 +212,11 @@ pub fn ptrcast<'ll>(val: &'ll Value, ty: &'ll Type) -> &'ll Value { } impl<'ll> CodegenCx<'ll, '_> { - crate fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value { + pub(crate) fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMConstBitCast(val, ty) } } - crate fn static_addr_of_mut( + pub(crate) fn static_addr_of_mut( &self, cv: &'ll Value, align: Align, @@ -241,7 +241,7 @@ impl<'ll> CodegenCx<'ll, '_> { } } - crate fn get_static(&self, def_id: DefId) -> &'ll Value { + pub(crate) fn get_static(&self, def_id: DefId) -> &'ll Value { let instance = Instance::mono(self.tcx, def_id); if let Some(&g) = self.instances.borrow().get(&instance) { return g; diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index d296ee3b42..c007728095 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -326,11 +326,20 @@ pub unsafe fn create_module<'ll>( ) } + if sess.opts.debugging_opts.virtual_function_elimination { + llvm::LLVMRustAddModuleFlag( + llmod, + llvm::LLVMModFlagBehavior::Error, + "Virtual Function Elim\0".as_ptr().cast(), + 1, + ); + } + llmod } impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { - crate fn new( + pub(crate) fn new( tcx: TyCtxt<'tcx>, codegen_unit: &'tcx CodegenUnit<'tcx>, llvm_module: &'ll crate::ModuleLlvm, @@ -447,7 +456,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { } } - crate fn statics_to_rauw(&self) -> &RefCell> { + pub(crate) fn statics_to_rauw(&self) -> &RefCell> { &self.statics_to_rauw } @@ -599,7 +608,7 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { } impl<'ll> CodegenCx<'ll, '_> { - crate fn get_intrinsic(&self, key: &str) -> (&'ll Type, &'ll Value) { + pub(crate) fn get_intrinsic(&self, key: &str) -> (&'ll Type, &'ll Value) { if let Some(v) = self.intrinsics.borrow().get(key).cloned() { return v; } @@ -656,6 +665,7 @@ impl<'ll> CodegenCx<'ll, '_> { let t_isize = self.type_isize(); let t_f32 = self.type_f32(); let t_f64 = self.type_f64(); + let t_metadata = self.type_metadata(); ifn!("llvm.wasm.trunc.unsigned.i32.f32", fn(t_f32) -> t_i32); ifn!("llvm.wasm.trunc.unsigned.i32.f64", fn(t_f64) -> t_i32); @@ -881,21 +891,22 @@ impl<'ll> CodegenCx<'ll, '_> { ifn!("llvm.instrprof.increment", fn(i8p, t_i64, t_i32, t_i32) -> void); } - ifn!("llvm.type.test", fn(i8p, self.type_metadata()) -> i1); + ifn!("llvm.type.test", fn(i8p, t_metadata) -> i1); + ifn!("llvm.type.checked.load", fn(i8p, t_i32, t_metadata) -> mk_struct! {i8p, i1}); if self.sess().opts.debuginfo != DebugInfo::None { - ifn!("llvm.dbg.declare", fn(self.type_metadata(), self.type_metadata()) -> void); - ifn!("llvm.dbg.value", fn(self.type_metadata(), t_i64, self.type_metadata()) -> void); + ifn!("llvm.dbg.declare", fn(t_metadata, t_metadata) -> void); + ifn!("llvm.dbg.value", fn(t_metadata, t_i64, t_metadata) -> void); } None } - crate fn eh_catch_typeinfo(&self) -> &'ll Value { + pub(crate) fn eh_catch_typeinfo(&self) -> &'ll Value { if let Some(eh_catch_typeinfo) = self.eh_catch_typeinfo.get() { return eh_catch_typeinfo; } let tcx = self.tcx; - assert!(self.sess().target.is_like_emscripten); + assert!(self.sess().target.os == "emscripten"); let eh_catch_typeinfo = match tcx.lang_items().eh_catch_typeinfo() { Some(def_id) => self.get_static(def_id), _ => { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 31a09242c5..5186aee57f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -5,11 +5,14 @@ use crate::llvm; use crate::builder::Builder; use crate::common::CodegenCx; use crate::value::Value; +use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive; use rustc_codegen_ssa::traits::*; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::bug; -use rustc_session::config::DebugInfo; +use rustc_session::config::{CrateType, DebugInfo}; use rustc_span::symbol::sym; +use rustc_span::DebuggerVisualizerType; /// Inserts a side-effect free instruction sequence that makes sure that the /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker. @@ -37,9 +40,33 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, ' section_var.unwrap_or_else(|| { let section_name = b".debug_gdb_scripts\0"; - let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; + let mut section_contents = Vec::new(); + + // Add the pretty printers for the standard library first. + section_contents.extend_from_slice(b"\x01gdb_load_rust_pretty_printers.py\0"); + + // Next, add the pretty printers that were specified via the `#[debugger_visualizer]` attribute. + let visualizers = collect_debugger_visualizers_transitive( + cx.tcx, + DebuggerVisualizerType::GdbPrettyPrinter, + ); + let crate_name = cx.tcx.crate_name(LOCAL_CRATE); + for (index, visualizer) in visualizers.iter().enumerate() { + // The initial byte `4` instructs GDB that the following pretty printer + // is defined inline as opposed to in a standalone file. + section_contents.extend_from_slice(b"\x04"); + let vis_name = format!("pretty-printer-{}-{}\n", crate_name.as_str(), index); + section_contents.extend_from_slice(vis_name.as_bytes()); + section_contents.extend_from_slice(&visualizer.src); + + // The final byte `0` tells GDB that the pretty printer has been + // fully defined and can continue searching for additional + // pretty printers. + section_contents.extend_from_slice(b"\0"); + } unsafe { + let section_contents = section_contents.as_slice(); let llvm_type = cx.type_array(cx.type_i8(), section_contents.len() as u64); let section_var = cx @@ -62,7 +89,32 @@ pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { let omit_gdb_pretty_printer_section = cx.tcx.sess.contains_name(cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section); + // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create + // ODR violations at link time, this section will not be emitted for rlibs since + // each rlib could produce a different set of visualizers that would be embedded + // in the `.debug_gdb_scripts` section. For that reason, we make sure that the + // section is only emitted for leaf crates. + let embed_visualizers = cx.sess().crate_types().iter().any(|&crate_type| match crate_type { + CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::Staticlib => { + // These are crate types for which we will embed pretty printers since they + // are treated as leaf crates. + true + } + CrateType::ProcMacro => { + // We could embed pretty printers for proc macro crates too but it does not + // seem like a good default, since this is a rare use case and we don't + // want to slow down the common case. + false + } + CrateType::Rlib => { + // As per the above description, embedding pretty printers for rlibs could + // lead to ODR violations so we skip this crate type as well. + false + } + }); + !omit_gdb_pretty_printer_section && cx.sess().opts.debuginfo != DebugInfo::None && cx.sess().target.emit_debug_gdb_scripts + && embed_visualizers } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index f2cf3b1ef5..d5f39a4567 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -30,26 +30,28 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::bug; use rustc_middle::mir::{self, GeneratorLayout}; -use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::{self, AdtKind, Instance, ParamEnv, Ty, TyCtxt, COMMON_VTABLE_ENTRIES}; -use rustc_session::config::{self, DebugInfo}; +use rustc_middle::ty::{ + self, AdtKind, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, Visibility, +}; +use rustc_session::config::{self, DebugInfo, Lto}; use rustc_span::symbol::Symbol; -use rustc_span::FileNameDisplayPreference; -use rustc_span::{self, SourceFile, SourceFileHash}; +use rustc_span::FileName; +use rustc_span::{self, FileNameDisplayPreference, SourceFile}; +use rustc_symbol_mangling::typeid_for_trait_ref; use rustc_target::abi::{Align, Size}; use smallvec::smallvec; use tracing::debug; -use libc::{c_longlong, c_uint}; +use libc::{c_char, c_longlong, c_uint}; use std::borrow::Cow; -use std::collections::hash_map::Entry; use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; use std::iter; use std::path::{Path, PathBuf}; use std::ptr; +use tracing::instrument; impl PartialEq for llvm::Metadata { fn eq(&self, other: &Self) -> bool { @@ -527,78 +529,105 @@ fn hex_encode(data: &[u8]) -> String { } pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile { - debug!("file_metadata: file_name: {:?}", source_file.name); - - let hash = Some(&source_file.src_hash); - let file_name = Some(source_file.name.prefer_remapped().to_string()); - let directory = if source_file.is_real_file() && !source_file.is_imported() { - Some( - cx.sess() - .opts - .working_dir - .to_string_lossy(FileNameDisplayPreference::Remapped) - .to_string(), - ) - } else { - // If the path comes from an upstream crate we assume it has been made - // independent of the compiler's working directory one way or another. - None - }; - file_metadata_raw(cx, file_name, directory, hash) -} - -pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { - file_metadata_raw(cx, None, None, None) -} - -fn file_metadata_raw<'ll>( - cx: &CodegenCx<'ll, '_>, - file_name: Option, - directory: Option, - hash: Option<&SourceFileHash>, -) -> &'ll DIFile { - let key = (file_name, directory); - - match debug_context(cx).created_files.borrow_mut().entry(key) { - Entry::Occupied(o) => o.get(), - Entry::Vacant(v) => { - let (file_name, directory) = v.key(); - debug!("file_metadata: file_name: {:?}, directory: {:?}", file_name, directory); - - let file_name = file_name.as_deref().unwrap_or(""); - let directory = directory.as_deref().unwrap_or(""); - - let (hash_kind, hash_value) = match hash { - Some(hash) => { - let kind = match hash.kind { - rustc_span::SourceFileHashAlgorithm::Md5 => llvm::ChecksumKind::MD5, - rustc_span::SourceFileHashAlgorithm::Sha1 => llvm::ChecksumKind::SHA1, - rustc_span::SourceFileHashAlgorithm::Sha256 => llvm::ChecksumKind::SHA256, - }; - (kind, hex_encode(hash.hash_bytes())) + let cache_key = Some((source_file.name_hash, source_file.src_hash)); + return debug_context(cx) + .created_files + .borrow_mut() + .entry(cache_key) + .or_insert_with(|| alloc_new_file_metadata(cx, source_file)); + + #[instrument(skip(cx, source_file), level = "debug")] + fn alloc_new_file_metadata<'ll>( + cx: &CodegenCx<'ll, '_>, + source_file: &SourceFile, + ) -> &'ll DIFile { + debug!(?source_file.name); + + let (directory, file_name) = match &source_file.name { + FileName::Real(filename) => { + let working_directory = &cx.sess().opts.working_dir; + debug!(?working_directory); + + let filename = cx + .sess() + .source_map() + .path_mapping() + .to_embeddable_absolute_path(filename.clone(), working_directory); + + // Construct the absolute path of the file + let abs_path = filename.remapped_path_if_available(); + debug!(?abs_path); + + if let Ok(rel_path) = + abs_path.strip_prefix(working_directory.remapped_path_if_available()) + { + // If the compiler's working directory (which also is the DW_AT_comp_dir of + // the compilation unit) is a prefix of the path we are about to emit, then + // only emit the part relative to the working directory. + // Because of path remapping we sometimes see strange things here: `abs_path` + // might actually look like a relative path + // (e.g. `/src/lib.rs`), so if we emit it without + // taking the working directory into account, downstream tooling will + // interpret it as `//src/lib.rs`, + // which makes no sense. Usually in such cases the working directory will also + // be remapped to `` or some other prefix of the path + // we are remapping, so we end up with + // `//src/lib.rs`. + // By moving the working directory portion into the `directory` part of the + // DIFile, we allow LLVM to emit just the relative path for DWARF, while + // still emitting the correct absolute path for CodeView. + ( + working_directory.to_string_lossy(FileNameDisplayPreference::Remapped), + rel_path.to_string_lossy().into_owned(), + ) + } else { + ("".into(), abs_path.to_string_lossy().into_owned()) } - None => (llvm::ChecksumKind::None, String::new()), - }; + } + other => ("".into(), other.prefer_remapped().to_string_lossy().into_owned()), + }; - let file_metadata = unsafe { - llvm::LLVMRustDIBuilderCreateFile( - DIB(cx), - file_name.as_ptr().cast(), - file_name.len(), - directory.as_ptr().cast(), - directory.len(), - hash_kind, - hash_value.as_ptr().cast(), - hash_value.len(), - ) - }; + let hash_kind = match source_file.src_hash.kind { + rustc_span::SourceFileHashAlgorithm::Md5 => llvm::ChecksumKind::MD5, + rustc_span::SourceFileHashAlgorithm::Sha1 => llvm::ChecksumKind::SHA1, + rustc_span::SourceFileHashAlgorithm::Sha256 => llvm::ChecksumKind::SHA256, + }; + let hash_value = hex_encode(source_file.src_hash.hash_bytes()); - v.insert(file_metadata); - file_metadata + unsafe { + llvm::LLVMRustDIBuilderCreateFile( + DIB(cx), + file_name.as_ptr().cast(), + file_name.len(), + directory.as_ptr().cast(), + directory.len(), + hash_kind, + hash_value.as_ptr().cast(), + hash_value.len(), + ) } } } +pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { + debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| unsafe { + let file_name = ""; + let directory = ""; + let hash_value = ""; + + llvm::LLVMRustDIBuilderCreateFile( + DIB(cx), + file_name.as_ptr().cast(), + file_name.len(), + directory.as_ptr().cast(), + directory.len(), + llvm::ChecksumKind::None, + hash_value.as_ptr().cast(), + hash_value.len(), + ) + }) +} + trait MsvcBasicName { fn msvc_basic_name(self) -> &'static str; } @@ -1337,7 +1366,7 @@ pub fn build_global_var_di_node<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId, glo is_local_to_unit, global, None, - global_align.bytes() as u32, + global_align.bits() as u32, ); } } @@ -1364,7 +1393,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>( tcx.vtable_entries(trait_ref) } else { - COMMON_VTABLE_ENTRIES + TyCtxt::COMMON_VTABLE_ENTRIES }; // All function pointers are described as opaque pointers. This could be improved in the future @@ -1440,6 +1469,84 @@ fn build_vtable_type_di_node<'ll, 'tcx>( .di_node } +fn vcall_visibility_metadata<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + ty: Ty<'tcx>, + trait_ref: Option>, + vtable: &'ll Value, +) { + enum VCallVisibility { + Public = 0, + LinkageUnit = 1, + TranslationUnit = 2, + } + + let Some(trait_ref) = trait_ref else { return }; + + let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty); + let trait_ref_self = cx.tcx.erase_regions(trait_ref_self); + let trait_def_id = trait_ref_self.def_id(); + let trait_vis = cx.tcx.visibility(trait_def_id); + + let cgus = cx.sess().codegen_units(); + let single_cgu = cgus == 1; + + let lto = cx.sess().lto(); + + // Since LLVM requires full LTO for the virtual function elimination optimization to apply, + // only the `Lto::Fat` cases are relevant currently. + let vcall_visibility = match (lto, trait_vis, single_cgu) { + // If there is not LTO and the visibility in public, we have to assume that the vtable can + // be seen from anywhere. With multiple CGUs, the vtable is quasi-public. + (Lto::No | Lto::ThinLocal, Visibility::Public, _) + | (Lto::No, Visibility::Restricted(_) | Visibility::Invisible, false) => { + VCallVisibility::Public + } + // With LTO and a quasi-public visibility, the usages of the functions of the vtable are + // all known by the `LinkageUnit`. + // FIXME: LLVM only supports this optimization for `Lto::Fat` currently. Once it also + // supports `Lto::Thin` the `VCallVisibility` may have to be adjusted for those. + (Lto::Fat | Lto::Thin, Visibility::Public, _) + | ( + Lto::ThinLocal | Lto::Thin | Lto::Fat, + Visibility::Restricted(_) | Visibility::Invisible, + false, + ) => VCallVisibility::LinkageUnit, + // If there is only one CGU, private vtables can only be seen by that CGU/translation unit + // and therefore we know of all usages of functions in the vtable. + (_, Visibility::Restricted(_) | Visibility::Invisible, true) => { + VCallVisibility::TranslationUnit + } + }; + + let trait_ref_typeid = typeid_for_trait_ref(cx.tcx, trait_ref); + + unsafe { + let typeid = llvm::LLVMMDStringInContext( + cx.llcx, + trait_ref_typeid.as_ptr() as *const c_char, + trait_ref_typeid.as_bytes().len() as c_uint, + ); + let v = [cx.const_usize(0), typeid]; + llvm::LLVMRustGlobalAddMetadata( + vtable, + llvm::MD_type as c_uint, + llvm::LLVMValueAsMetadata(llvm::LLVMMDNodeInContext( + cx.llcx, + v.as_ptr(), + v.len() as c_uint, + )), + ); + let vcall_visibility = llvm::LLVMValueAsMetadata(cx.const_u64(vcall_visibility as u64)); + let vcall_visibility_metadata = llvm::LLVMMDNodeInContext2(cx.llcx, &vcall_visibility, 1); + llvm::LLVMGlobalSetMetadata( + vtable, + llvm::MetadataType::MD_vcall_visibility as c_uint, + vcall_visibility_metadata, + ); + } +} + /// Creates debug information for the given vtable, which is for the /// given type. /// @@ -1450,6 +1557,12 @@ pub fn create_vtable_di_node<'ll, 'tcx>( poly_trait_ref: Option>, vtable: &'ll Value, ) { + // FIXME(flip1995): The virtual function elimination optimization only works with full LTO in + // LLVM at the moment. + if cx.sess().opts.debugging_opts.virtual_function_elimination && cx.sess().lto() == Lto::Fat { + vcall_visibility_metadata(cx, ty, poly_trait_ref, vtable); + } + if cx.dbg_cx.is_none() { return; } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 6a164557a4..71699b5cf3 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -31,14 +31,14 @@ use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeFoldable}; use rustc_session::config::{self, DebugInfo}; use rustc_session::Session; use rustc_span::symbol::Symbol; -use rustc_span::{self, BytePos, Pos, SourceFile, SourceFileAndLine, Span}; +use rustc_span::{self, BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span}; use rustc_target::abi::Size; use libc::c_uint; use smallvec::SmallVec; +use std::cell::OnceCell; use std::cell::RefCell; use std::iter; -use std::lazy::OnceCell; use tracing::debug; mod create_scope_map; @@ -61,7 +61,7 @@ pub struct CodegenUnitDebugContext<'ll, 'tcx> { llcontext: &'ll llvm::Context, llmod: &'ll llvm::Module, builder: &'ll mut DIBuilder<'ll>, - created_files: RefCell, Option), &'ll DIFile>>, + created_files: RefCell, &'ll DIFile>>, type_map: metadata::TypeMap<'ll, 'tcx>, namespace_map: RefCell>, diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 4407297c94..9f36474928 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -406,6 +406,16 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { self.call_intrinsic("llvm.type.test", &[bitcast, typeid]) } + fn type_checked_load( + &mut self, + llvtable: &'ll Value, + vtable_byte_offset: u64, + typeid: &'ll Value, + ) -> Self::Value { + let vtable_byte_offset = self.const_i32(vtable_byte_offset as i32); + self.call_intrinsic("llvm.type.checked.load", &[llvtable, vtable_byte_offset, typeid]) + } + fn va_start(&mut self, va_list: &'ll Value) -> &'ll Value { self.call_intrinsic("llvm.va_start", &[va_list]) } @@ -431,7 +441,7 @@ fn try_intrinsic<'ll>( bx.store(bx.const_i32(0), dest, ret_align); } else if wants_msvc_seh(bx.sess()) { codegen_msvc_try(bx, try_func, data, catch_func, dest); - } else if bx.sess().target.is_like_emscripten { + } else if bx.sess().target.os == "emscripten" { codegen_emcc_try(bx, try_func, data, catch_func, dest); } else { codegen_gnu_try(bx, try_func, data, catch_func, dest); @@ -816,7 +826,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( span: Span, ) -> Result<&'ll Value, ()> { // macros for error handling: - #[cfg_attr(not(bootstrap), allow(unused_macro_rules))] + #[allow(unused_macro_rules)] macro_rules! emit_error { ($msg: tt) => { emit_error!($msg, ) @@ -1145,7 +1155,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( span: Span, args: &[OperandRef<'tcx, &'ll Value>], ) -> Result<&'ll Value, ()> { - #[cfg_attr(not(bootstrap), allow(unused_macro_rules))] + #[allow(unused_macro_rules)] macro_rules! emit_error { ($msg: tt) => { emit_error!($msg, ) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 0bead4629a..6713a75673 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -5,12 +5,10 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(crate_visibility_modifier)] #![feature(let_chains)] #![feature(let_else)] #![feature(extern_types)] #![feature(once_cell)] -#![feature(nll)] #![feature(iter_intersperse)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] @@ -305,8 +303,8 @@ impl CodegenBackend for LlvmCodegenBackend { local stack variable in the ABI.) basic - Generate stack canaries in functions with: - - local variables of `[T; N]` type, where `T` is byte-sized and `N` > 8. + Generate stack canaries in functions with local variables of `[T; N]` + type, where `T` is byte-sized and `N` >= 8. none Do not generate stack canaries. diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 13baaddccd..b831423994 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -381,9 +381,8 @@ pub enum AtomicOrdering { impl AtomicOrdering { pub fn from_generic(ao: rustc_codegen_ssa::common::AtomicOrdering) -> Self { match ao { - rustc_codegen_ssa::common::AtomicOrdering::NotAtomic => AtomicOrdering::NotAtomic, rustc_codegen_ssa::common::AtomicOrdering::Unordered => AtomicOrdering::Unordered, - rustc_codegen_ssa::common::AtomicOrdering::Monotonic => AtomicOrdering::Monotonic, + rustc_codegen_ssa::common::AtomicOrdering::Relaxed => AtomicOrdering::Monotonic, rustc_codegen_ssa::common::AtomicOrdering::Acquire => AtomicOrdering::Acquire, rustc_codegen_ssa::common::AtomicOrdering::Release => AtomicOrdering::Release, rustc_codegen_ssa::common::AtomicOrdering::AcquireRelease => { @@ -443,6 +442,7 @@ pub enum MetadataType { MD_nonnull = 11, MD_align = 17, MD_type = 19, + MD_vcall_visibility = 28, MD_noundef = 29, } @@ -775,7 +775,7 @@ pub mod coverageinfo { } impl CounterMappingRegion { - crate fn code_region( + pub(crate) fn code_region( counter: coverage_map::Counter, file_id: u32, start_line: u32, @@ -799,7 +799,7 @@ pub mod coverageinfo { // This function might be used in the future; the LLVM API is still evolving, as is coverage // support. #[allow(dead_code)] - crate fn branch_region( + pub(crate) fn branch_region( counter: coverage_map::Counter, false_counter: coverage_map::Counter, file_id: u32, @@ -824,7 +824,7 @@ pub mod coverageinfo { // This function might be used in the future; the LLVM API is still evolving, as is coverage // support. #[allow(dead_code)] - crate fn expansion_region( + pub(crate) fn expansion_region( file_id: u32, expanded_file_id: u32, start_line: u32, @@ -848,7 +848,7 @@ pub mod coverageinfo { // This function might be used in the future; the LLVM API is still evolving, as is coverage // support. #[allow(dead_code)] - crate fn skipped_region( + pub(crate) fn skipped_region( file_id: u32, start_line: u32, start_col: u32, @@ -871,7 +871,7 @@ pub mod coverageinfo { // This function might be used in the future; the LLVM API is still evolving, as is coverage // support. #[allow(dead_code)] - crate fn gap_region( + pub(crate) fn gap_region( counter: coverage_map::Counter, file_id: u32, start_line: u32, @@ -1068,6 +1068,7 @@ extern "C" { pub fn LLVMReplaceAllUsesWith<'a>(OldVal: &'a Value, NewVal: &'a Value); pub fn LLVMSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Node: &'a Value); pub fn LLVMGlobalSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata); + pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata); pub fn LLVMValueAsMetadata(Node: &Value) -> &Metadata; // Operations on constants of any type @@ -1081,6 +1082,11 @@ extern "C" { Vals: *const &'a Value, Count: c_uint, ) -> &'a Value; + pub fn LLVMMDNodeInContext2<'a>( + C: &'a Context, + Vals: *const &'a Metadata, + Count: size_t, + ) -> &'a Metadata; pub fn LLVMAddNamedMetadataOperand<'a>(M: &'a Module, Name: *const c_char, Val: &'a Value); // Operations on scalar constants @@ -1937,6 +1943,7 @@ extern "C" { name: *const c_char, value: u32, ); + pub fn LLVMRustHasModuleFlag(M: &Module, name: *const c_char, len: size_t) -> bool; pub fn LLVMRustMetadataAsValue<'a>(C: &'a Context, MD: &'a Metadata) -> &'a Value; diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 7b407c94e7..ce6c6e3215 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -218,15 +218,17 @@ pub fn check_tied_features( sess: &Session, features: &FxHashMap<&str, bool>, ) -> Option<&'static [&'static str]> { - for tied in tied_target_features(sess) { - // Tied features must be set to the same value, or not set at all - let mut tied_iter = tied.iter(); - let enabled = features.get(tied_iter.next().unwrap()); - if tied_iter.any(|f| enabled != features.get(f)) { - return Some(tied); + if !features.is_empty() { + for tied in tied_target_features(sess) { + // Tied features must be set to the same value, or not set at all + let mut tied_iter = tied.iter(); + let enabled = features.get(tied_iter.next().unwrap()); + if tied_iter.any(|f| enabled != features.get(f)) { + return Some(tied); + } } } - None + return None; } // Used to generate cfg variables and apply features @@ -440,6 +442,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec Vec>(); - - if diagnostics { - // FIXME(nagisa): figure out how to not allocate a full hashset here. - let featmap = feats.iter().map(|&(flag, feat)| (feat, flag == '+')).collect(); - if let Some(f) = check_tied_features(sess, &featmap) { - sess.err(&format!( - "target features {} must all be enabled or disabled together", - f.join(", ") - )); - } + .flatten(); + features.extend(feats); + + if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) { + sess.err(&format!( + "target features {} must all be enabled or disabled together", + f.join(", ") + )); } - features.extend(feats.into_iter().flat_map(|(enable_disable, feature)| { - // rustc-specific features do not get passed down to LLVM… - if RUSTC_SPECIFIC_FEATURES.contains(&feature) { - return SmallVec::<[_; 2]>::new(); - } - // ... otherwise though we run through `to_llvm_features` when - // passing requests down to LLVM. This means that all in-language - // features also work on the command line instead of having two - // different names when the LLVM name and the Rust name differ. - to_llvm_features(sess, feature) - .into_iter() - .map(|f| format!("{}{}", enable_disable, f)) - .collect() - })); features } diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 21b77f7dea..cf2d3c423c 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -39,33 +39,33 @@ impl fmt::Debug for Type { } impl<'ll> CodegenCx<'ll, '_> { - crate fn type_named_struct(&self, name: &str) -> &'ll Type { + pub(crate) fn type_named_struct(&self, name: &str) -> &'ll Type { let name = SmallCStr::new(name); unsafe { llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) } } - crate fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) { + pub(crate) fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) { unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) } } - crate fn type_void(&self) -> &'ll Type { + pub(crate) fn type_void(&self) -> &'ll Type { unsafe { llvm::LLVMVoidTypeInContext(self.llcx) } } - crate fn type_metadata(&self) -> &'ll Type { + pub(crate) fn type_metadata(&self) -> &'ll Type { unsafe { llvm::LLVMRustMetadataTypeInContext(self.llcx) } } ///x Creates an integer type with the given number of bits, e.g., i24 - crate fn type_ix(&self, num_bits: u64) -> &'ll Type { + pub(crate) fn type_ix(&self, num_bits: u64) -> &'ll Type { unsafe { llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint) } } - crate fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type { + pub(crate) fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type { unsafe { llvm::LLVMVectorType(ty, len as c_uint) } } - crate fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> { + pub(crate) fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> { unsafe { let n_args = llvm::LLVMCountParamTypes(ty) as usize; let mut args = Vec::with_capacity(n_args); @@ -75,11 +75,11 @@ impl<'ll> CodegenCx<'ll, '_> { } } - crate fn type_bool(&self) -> &'ll Type { + pub(crate) fn type_bool(&self) -> &'ll Type { self.type_i8() } - crate fn type_int_from_ty(&self, t: ty::IntTy) -> &'ll Type { + pub(crate) fn type_int_from_ty(&self, t: ty::IntTy) -> &'ll Type { match t { ty::IntTy::Isize => self.type_isize(), ty::IntTy::I8 => self.type_i8(), @@ -90,7 +90,7 @@ impl<'ll> CodegenCx<'ll, '_> { } } - crate fn type_uint_from_ty(&self, t: ty::UintTy) -> &'ll Type { + pub(crate) fn type_uint_from_ty(&self, t: ty::UintTy) -> &'ll Type { match t { ty::UintTy::Usize => self.type_isize(), ty::UintTy::U8 => self.type_i8(), @@ -101,14 +101,14 @@ impl<'ll> CodegenCx<'ll, '_> { } } - crate fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type { + pub(crate) fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type { match t { ty::FloatTy::F32 => self.type_f32(), ty::FloatTy::F64 => self.type_f64(), } } - crate fn type_pointee_for_align(&self, align: Align) -> &'ll Type { + pub(crate) fn type_pointee_for_align(&self, align: Align) -> &'ll Type { // FIXME(eddyb) We could find a better approximation if ity.align < align. let ity = Integer::approximate_align(self, align); self.type_from_integer(ity) @@ -116,7 +116,7 @@ impl<'ll> CodegenCx<'ll, '_> { /// Return a LLVM type that has at most the required alignment, /// and exactly the required size, as a best-effort padding array. - crate fn type_padding_filler(&self, size: Size, align: Align) -> &'ll Type { + pub(crate) fn type_padding_filler(&self, size: Size, align: Align) -> &'ll Type { let unit = Integer::approximate_align(self, align); let size = size.bytes(); let unit_size = unit.size().bytes(); @@ -124,11 +124,11 @@ impl<'ll> CodegenCx<'ll, '_> { self.type_array(self.type_from_integer(unit), size / unit_size) } - crate fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { + pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) } } - crate fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type { + pub(crate) fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type { unsafe { llvm::LLVMRustArrayType(ty, len) } } } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 93b10a07e4..2fa66b2687 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -14,8 +14,9 @@ tracing = "0.1" libc = "0.2.50" jobserver = "0.1.22" tempfile = "3.2" -thorin-dwp = "0.2" +thorin-dwp = "0.3" pathdiff = "0.2.0" +serde_json = "1.0.59" snap = "1" smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } regex = "1.4" @@ -41,6 +42,6 @@ rustc_target = { path = "../rustc_target" } rustc_session = { path = "../rustc_session" } [dependencies.object] -version = "0.28.4" +version = "0.29.0" default-features = false features = ["read_core", "elf", "macho", "pe", "unaligned", "archive", "write"] diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index a2f74b9421..553486ae8e 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -42,17 +42,15 @@ pub(super) fn find_library( } pub trait ArchiveBuilder<'a> { - fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self; + fn new(sess: &'a Session, output: &Path) -> Self; fn add_file(&mut self, path: &Path); - fn remove_file(&mut self, name: &str); - fn src_files(&mut self) -> Vec; fn add_archive(&mut self, archive: &Path, skip: F) -> io::Result<()> where F: FnMut(&str) -> bool + 'static; - fn build(self); + fn build(self) -> bool; fn inject_dll_import_lib( &mut self, diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs index 17071ba1b5..6c29692bd3 100644 --- a/compiler/rustc_codegen_ssa/src/back/command.rs +++ b/compiler/rustc_codegen_ssa/src/back/command.rs @@ -105,12 +105,7 @@ impl Command { } Program::Lld(ref p, flavor) => { let mut c = process::Command::new(p); - c.arg("-flavor").arg(match flavor { - LldFlavor::Wasm => "wasm", - LldFlavor::Ld => "gnu", - LldFlavor::Link => "link", - LldFlavor::Ld64 => "darwin", - }); + c.arg("-flavor").arg(flavor.as_str()); if let LldFlavor::Wasm = flavor { // LLVM expects host-specific formatting for @file // arguments, but we always generate posix formatted files diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 04ec1e7f3c..ea83877bde 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -5,7 +5,7 @@ use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_errors::{ErrorGuaranteed, Handler}; use rustc_fs_util::fix_windows_verbatim_for_gcc; -use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc_hir::def_id::CrateNum; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip}; @@ -18,6 +18,7 @@ use rustc_session::utils::NativeLibKind; /// need out of the shared crate context before we get rid of it. use rustc_session::{filesearch, Session}; use rustc_span::symbol::Symbol; +use rustc_span::DebuggerVisualizerFile; use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo}; use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target}; @@ -37,10 +38,11 @@ use regex::Regex; use tempfile::Builder as TempFileBuilder; use std::borrow::Borrow; +use std::cell::OnceCell; +use std::collections::BTreeSet; use std::ffi::OsString; use std::fs::{File, OpenOptions}; use std::io::{BufWriter, Write}; -use std::lazy::OnceCell; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::process::{ExitStatus, Output, Stdio}; @@ -268,7 +270,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>( let lib_search_paths = archive_search_paths(sess); - let mut ab = ::new(sess, out_filename, None); + let mut ab = ::new(sess, out_filename); let trailing_metadata = match flavor { RlibFlavor::Normal => { @@ -1001,10 +1003,14 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( let strip = strip_value(sess); if sess.target.is_like_osx { - match strip { - Strip::Debuginfo => strip_symbols_in_osx(sess, &out_filename, Some("-S")), - Strip::Symbols => strip_symbols_in_osx(sess, &out_filename, None), - Strip::None => {} + match (strip, crate_type) { + (Strip::Debuginfo, _) => strip_symbols_in_osx(sess, &out_filename, Some("-S")), + // Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988) + (Strip::Symbols, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro) => { + strip_symbols_in_osx(sess, &out_filename, Some("-x")) + } + (Strip::Symbols, _) => strip_symbols_in_osx(sess, &out_filename, None), + (Strip::None, _) => {} } } } @@ -1950,7 +1956,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( add_local_native_libraries(cmd, sess, codegen_results); } - // Upstream rust libraries and their nobundle static libraries + // Upstream rust libraries and their non-bundled static libraries add_upstream_rust_crates::(cmd, sess, codegen_results, crate_type, tmpdir); // Upstream dynamic native libraries linked with `#[link]` attributes at and `-l` @@ -2025,7 +2031,7 @@ fn add_order_independent_options( add_link_script(cmd, sess, tmpdir, crate_type); - if sess.target.is_like_fuchsia && crate_type == CrateType::Executable { + if sess.target.os == "fuchsia" && crate_type == CrateType::Executable { let prefix = if sess.opts.debugging_opts.sanitizer.contains(SanitizerSet::ADDRESS) { "asan/" } else { @@ -2045,7 +2051,7 @@ fn add_order_independent_options( cmd.no_crt_objects(); } - if sess.target.is_like_emscripten { + if sess.target.os == "emscripten" { cmd.arg("-s"); cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort { "DISABLE_EXCEPTION_CATCHING=1" @@ -2099,14 +2105,16 @@ fn add_order_independent_options( // Pass optimization flags down to the linker. cmd.optimize(); - let debugger_visualizer_paths = if sess.target.is_like_msvc { - collect_debugger_visualizers(tmpdir, sess, &codegen_results.crate_info) - } else { - Vec::new() - }; + // Gather the set of NatVis files, if any, and write them out to a temp directory. + let natvis_visualizers = collect_natvis_visualizers( + tmpdir, + sess, + &codegen_results.crate_info.local_crate_name, + &codegen_results.crate_info.natvis_debugger_visualizers, + ); - // Pass debuginfo and strip flags down to the linker. - cmd.debuginfo(strip_value(sess), &debugger_visualizer_paths); + // Pass debuginfo, NatVis debugger visualizers and strip flags down to the linker. + cmd.debuginfo(strip_value(sess), &natvis_visualizers); // We want to prevent the compiler from accidentally leaking in any system libraries, // so by default we tell linkers not to link to any default libraries. @@ -2125,43 +2133,33 @@ fn add_order_independent_options( add_rpath_args(cmd, sess, codegen_results, out_filename); } -// Write the debugger visualizer files for each crate to the temp directory and gather the file paths. -fn collect_debugger_visualizers( +// Write the NatVis debugger visualizer files for each crate to the temp directory and gather the file paths. +fn collect_natvis_visualizers( tmpdir: &Path, sess: &Session, - crate_info: &CrateInfo, + crate_name: &Symbol, + natvis_debugger_visualizers: &BTreeSet, ) -> Vec { - let mut visualizer_paths = Vec::new(); - let debugger_visualizers = &crate_info.debugger_visualizers; - let mut index = 0; + let mut visualizer_paths = Vec::with_capacity(natvis_debugger_visualizers.len()); - for (&cnum, visualizers) in debugger_visualizers { - let crate_name = if cnum == LOCAL_CRATE { - crate_info.local_crate_name.as_str() - } else { - crate_info.crate_name[&cnum].as_str() - }; - - for visualizer in visualizers { - let visualizer_out_file = tmpdir.join(format!("{}-{}.natvis", crate_name, index)); + for (index, visualizer) in natvis_debugger_visualizers.iter().enumerate() { + let visualizer_out_file = tmpdir.join(format!("{}-{}.natvis", crate_name.as_str(), index)); - match fs::write(&visualizer_out_file, &visualizer.src) { - Ok(()) => { - visualizer_paths.push(visualizer_out_file.clone()); - index += 1; - } - Err(error) => { - sess.warn( - format!( - "Unable to write debugger visualizer file `{}`: {} ", - visualizer_out_file.display(), - error - ) - .as_str(), - ); - } - }; - } + match fs::write(&visualizer_out_file, &visualizer.src) { + Ok(()) => { + visualizer_paths.push(visualizer_out_file); + } + Err(error) => { + sess.warn( + format!( + "Unable to write debugger visualizer file `{}`: {} ", + visualizer_out_file.display(), + error + ) + .as_str(), + ); + } + }; } visualizer_paths } @@ -2224,7 +2222,7 @@ fn add_local_native_libraries( // be added explicitly if necessary, see the error in `fn link_rlib`) compiled // as an executable due to `--test`. Use whole-archive implicitly, like before // the introduction of native lib modifiers. - || (bundle != Some(false) && sess.opts.test) + || (whole_archive == None && bundle != Some(false) && sess.opts.test) { cmd.link_whole_staticlib( name, @@ -2243,7 +2241,7 @@ fn add_local_native_libraries( } } -/// # Linking Rust crates and their nobundle static libraries +/// # Linking Rust crates and their non-bundled static libraries /// /// Rust crates are not considered at all when creating an rlib output. All dependencies will be /// linked when producing the final output (instead of the intermediate rlib version). @@ -2468,17 +2466,19 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( let name = &name[3..name.len() - 5]; // chop off lib/.rlib sess.prof.generic_activity_with_arg("link_altering_rlib", name).run(|| { - let mut archive = ::new(sess, &dst, Some(cratepath)); - - let mut any_objects = false; - for f in archive.src_files() { + let canonical_name = name.replace('-', "_"); + let upstream_rust_objects_already_included = + are_upstream_rust_objects_already_included(sess); + let is_builtins = sess.target.no_builtins + || !codegen_results.crate_info.is_no_builtins.contains(&cnum); + + let mut archive = ::new(sess, &dst); + if let Err(e) = archive.add_archive(cratepath, move |f| { if f == METADATA_FILENAME { - archive.remove_file(&f); - continue; + return true; } let canonical = f.replace('-', "_"); - let canonical_name = name.replace('-', "_"); let is_rust_object = canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f); @@ -2492,23 +2492,20 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // file, then we don't need the object file as it's part of the // LTO module. Note that `#![no_builtins]` is excluded from LTO, // though, so we let that object file slide. - let skip_because_lto = are_upstream_rust_objects_already_included(sess) - && is_rust_object - && (sess.target.no_builtins - || !codegen_results.crate_info.is_no_builtins.contains(&cnum)); + let skip_because_lto = + upstream_rust_objects_already_included && is_rust_object && is_builtins; if skip_because_cfg_say_so || skip_because_lto { - archive.remove_file(&f); - } else { - any_objects = true; + return true; } - } - if !any_objects { - return; + false + }) { + sess.fatal(&format!("failed to build archive from rlib: {}", e)); + } + if archive.build() { + link_upstream(&dst); } - archive.build(); - link_upstream(&dst); }); } @@ -2608,7 +2605,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { let os = &sess.target.os; let llvm_target = &sess.target.llvm_target; if sess.target.vendor != "apple" - || !matches!(os.as_ref(), "ios" | "tvos") + || !matches!(os.as_ref(), "ios" | "tvos" | "watchos") || flavor != LinkerFlavor::Gcc { return; @@ -2618,11 +2615,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { ("x86_64", "tvos") => "appletvsimulator", ("arm", "ios") => "iphoneos", ("aarch64", "ios") if llvm_target.contains("macabi") => "macosx", - ("aarch64", "ios") if llvm_target.contains("sim") => "iphonesimulator", + ("aarch64", "ios") if llvm_target.ends_with("-simulator") => "iphonesimulator", ("aarch64", "ios") => "iphoneos", ("x86", "ios") => "iphonesimulator", ("x86_64", "ios") if llvm_target.contains("macabi") => "macosx", ("x86_64", "ios") => "iphonesimulator", + ("x86_64", "watchos") => "watchsimulator", + ("arm64_32", "watchos") => "watchos", + ("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator", + ("aarch64", "watchos") => "watchos", + ("arm", "watchos") => "watchos", _ => { sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os)); return; @@ -2669,6 +2671,11 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result { "macosx10.15" if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") => {} + "watchos" + if sdkroot.contains("WatchSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "watchsimulator" + if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {} // Ignore `SDKROOT` if it's not a valid path. _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {} _ => return Ok(sdkroot), @@ -2698,37 +2705,20 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let LinkerFlavor::Gcc = flavor { match ld_impl { LdImpl::Lld => { - if sess.target.lld_flavor == LldFlavor::Ld64 { - let tools_path = sess.get_tools_search_paths(false); - let ld64_exe = tools_path - .into_iter() - .map(|p| p.join("gcc-ld")) - .map(|p| { - p.join(if sess.host.is_like_windows { "ld64.exe" } else { "ld64" }) - }) - .find(|p| p.exists()) - .unwrap_or_else(|| sess.fatal("rust-lld (as ld64) not found")); - cmd.cmd().arg({ - let mut arg = OsString::from("-fuse-ld="); - arg.push(ld64_exe); - arg - }); - } else { - let tools_path = sess.get_tools_search_paths(false); - let lld_path = tools_path - .into_iter() - .map(|p| p.join("gcc-ld")) - .find(|p| { - p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }) - .exists() - }) - .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found")); - cmd.cmd().arg({ - let mut arg = OsString::from("-B"); - arg.push(lld_path); - arg - }); - } + let tools_path = sess.get_tools_search_paths(false); + let gcc_ld_dir = tools_path + .into_iter() + .map(|p| p.join("gcc-ld")) + .find(|p| { + p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists() + }) + .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found")); + cmd.arg({ + let mut arg = OsString::from("-B"); + arg.push(gcc_ld_dir); + arg + }); + cmd.arg(format!("-Wl,-rustc-lld-flavor={}", sess.target.lld_flavor.as_str())); } } } else { diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 2a71377d2f..b5b63942e2 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -14,7 +14,6 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind}; use rustc_middle::ty::TyCtxt; -use rustc_serialize::{json, Encoder}; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; use rustc_session::Session; use rustc_span::symbol::Symbol; @@ -183,7 +182,7 @@ pub trait Linker { fn optimize(&mut self); fn pgo_gen(&mut self); fn control_flow_guard(&mut self); - fn debuginfo(&mut self, strip: Strip, debugger_visualizers: &[PathBuf]); + fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]); fn no_crt_objects(&mut self); fn no_default_libraries(&mut self); fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]); @@ -915,7 +914,7 @@ impl<'a> Linker for MsvcLinker<'a> { self.cmd.arg("/guard:cf"); } - fn debuginfo(&mut self, strip: Strip, debugger_visualizers: &[PathBuf]) { + fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]) { match strip { Strip::None => { // This will cause the Microsoft linker to generate a PDB file @@ -944,7 +943,7 @@ impl<'a> Linker for MsvcLinker<'a> { } // This will cause the Microsoft linker to embed .natvis info for all crates into the PDB file - for path in debugger_visualizers { + for path in natvis_debugger_visualizers { let mut arg = OsString::from("/NATVIS:"); arg.push(path); self.cmd.arg(arg); @@ -1121,8 +1120,6 @@ impl<'a> Linker for EmLinker<'a> { OptLevel::Size => "-Os", OptLevel::SizeMin => "-Oz", }); - // Unusable until https://github.com/rust-lang/rust/issues/38454 is resolved - self.cmd.args(&["--memory-init-file", "0"]); } fn pgo_gen(&mut self) { @@ -1135,15 +1132,15 @@ impl<'a> Linker for EmLinker<'a> { // Preserve names or generate source maps depending on debug info self.cmd.arg(match self.sess.opts.debuginfo { DebugInfo::None => "-g0", - DebugInfo::Limited => "-g3", - DebugInfo::Full => "-g4", + DebugInfo::Limited => "--profiling-funcs", + DebugInfo::Full => "-g", }); } fn no_crt_objects(&mut self) {} fn no_default_libraries(&mut self) { - self.cmd.args(&["-s", "DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[]"]); + self.cmd.arg("-nodefaultlibs"); } fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { @@ -1152,21 +1149,12 @@ impl<'a> Linker for EmLinker<'a> { self.cmd.arg("-s"); let mut arg = OsString::from("EXPORTED_FUNCTIONS="); - let mut encoded = String::new(); - - { - let mut encoder = json::Encoder::new(&mut encoded); - let res = encoder.emit_seq(symbols.len(), |encoder| { - for (i, sym) in symbols.iter().enumerate() { - encoder.emit_seq_elt(i, |encoder| encoder.emit_str(&("_".to_owned() + sym)))?; - } - Ok(()) - }); - if let Err(e) = res { - self.sess.fatal(&format!("failed to encode exported symbols: {}", e)); - } - } + let encoded = serde_json::to_string( + &symbols.iter().map(|sym| "_".to_owned() + sym).collect::>(), + ) + .unwrap(); debug!("{}", encoded); + arg.push(encoded); self.cmd.arg(arg); diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 6aa96f9f40..3dd607adee 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -130,7 +130,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option { let arch = match sess.target.options.cpu.as_ref() { "mips1" => elf::EF_MIPS_ARCH_1, @@ -149,7 +149,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option { // copied from `mips64el-linux-gnuabi64-gcc foo.c -c` @@ -160,17 +160,26 @@ pub(crate) fn create_object_file(sess: &Session) -> Option { // copied from `riscv64-linux-gnu-gcc foo.c -c`, note though // that the `+d` target feature represents whether the double // float abi is enabled. let e_flags = elf::EF_RISCV_RVC | elf::EF_RISCV_FLOAT_ABI_DOUBLE; - file.flags = FileFlags::Elf { e_flags }; + e_flags } - _ => {} + _ => 0, + }; + // adapted from LLVM's `MCELFObjectTargetWriter::getOSABI` + let os_abi = match sess.target.options.os.as_ref() { + "hermit" => elf::ELFOSABI_STANDALONE, + "freebsd" => elf::ELFOSABI_FREEBSD, + "solaris" => elf::ELFOSABI_SOLARIS, + _ => elf::ELFOSABI_NONE, }; + let abi_version = 0; + file.flags = FileFlags::Elf { os_abi, abi_version, e_flags }; Some(file) } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 88293dec01..632f07c5c2 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -494,12 +494,12 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( let _timer = sess.timer("copy_all_cgu_workproducts_to_incr_comp_cache_dir"); for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) { - let path = module.object.as_ref().cloned(); - - if let Some((id, product)) = - copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, &path) - { - work_products.insert(id, product); + if let Some(path) = &module.object { + if let Some((id, product)) = + copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, path) + { + work_products.insert(id, product); + } } } @@ -853,35 +853,31 @@ fn execute_copy_from_cache_work_item( module: CachedModuleCodegen, module_config: &ModuleConfig, ) -> WorkItemResult { + assert!(module_config.emit_obj != EmitObj::None); + let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap(); - let mut object = None; - if let Some(saved_file) = module.source.saved_file { - let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name)); - object = Some(obj_out.clone()); - let source_file = in_incr_comp_dir(&incr_comp_session_dir, &saved_file); - debug!( - "copying pre-existing module `{}` from {:?} to {}", - module.name, - source_file, - obj_out.display() - ); - if let Err(err) = link_or_copy(&source_file, &obj_out) { - let diag_handler = cgcx.create_diag_handler(); - diag_handler.err(&format!( - "unable to copy {} to {}: {}", - source_file.display(), - obj_out.display(), - err - )); - } + let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name)); + let source_file = in_incr_comp_dir(&incr_comp_session_dir, &module.source.saved_file); + debug!( + "copying pre-existing module `{}` from {:?} to {}", + module.name, + source_file, + obj_out.display() + ); + if let Err(err) = link_or_copy(&source_file, &obj_out) { + let diag_handler = cgcx.create_diag_handler(); + diag_handler.err(&format!( + "unable to copy {} to {}: {}", + source_file.display(), + obj_out.display(), + err + )); } - assert_eq!(object.is_some(), module_config.emit_obj != EmitObj::None); - WorkItemResult::Compiled(CompiledModule { name: module.name, kind: ModuleKind::Regular, - object, + object: Some(obj_out), dwarf_object: None, bytecode: None, }) @@ -1765,7 +1761,7 @@ impl SharedEmitterMain { let mut err = match level { Level::Error { lint: false } => sess.struct_err(msg).forget_guarantee(), - Level::Warning => sess.struct_warn(msg), + Level::Warning(_) => sess.struct_warn(msg), Level::Note => sess.struct_note_without_error(msg), _ => bug!("Invalid inline asm diagnostic level"), }; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 7b7e09208a..7e2e85ead5 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -15,8 +15,9 @@ use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; +use rustc_data_structures::sync::par_iter; #[cfg(parallel_compiler)] -use rustc_data_structures::sync::{par_iter, ParallelIterator}; +use rustc_data_structures::sync::ParallelIterator; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; @@ -30,11 +31,13 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::cgu_reuse_tracker::CguReuse; -use rustc_session::config::{self, EntryFnType, OutputType}; +use rustc_session::config::{self, CrateType, EntryFnType, OutputType}; use rustc_session::Session; use rustc_span::symbol::sym; +use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType}; use rustc_target::abi::{Align, VariantIdx}; +use std::collections::BTreeSet; use std::convert::TryFrom; use std::ops::{Deref, DerefMut}; use std::time::{Duration, Instant}; @@ -213,11 +216,12 @@ pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let mut result = None; for i in 0..src_layout.fields.count() { let src_f = src_layout.field(bx.cx(), i); - assert_eq!(src_layout.fields.offset(i).bytes(), 0); - assert_eq!(dst_layout.fields.offset(i).bytes(), 0); if src_f.is_zst() { continue; } + + assert_eq!(src_layout.fields.offset(i).bytes(), 0); + assert_eq!(dst_layout.fields.offset(i).bytes(), 0); assert_eq!(src_layout.size, src_f.size); let dst_f = dst_layout.field(bx.cx(), i); @@ -486,6 +490,29 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } +/// This function returns all of the debugger visualizers specified for the +/// current crate as well as all upstream crates transitively that match the +/// `visualizer_type` specified. +pub fn collect_debugger_visualizers_transitive( + tcx: TyCtxt<'_>, + visualizer_type: DebuggerVisualizerType, +) -> BTreeSet { + tcx.debugger_visualizers(LOCAL_CRATE) + .iter() + .chain( + tcx.crates(()) + .iter() + .filter(|&cnum| { + let used_crate_source = tcx.used_crate_source(*cnum); + used_crate_source.rlib.is_some() || used_crate_source.rmeta.is_some() + }) + .flat_map(|&cnum| tcx.debugger_visualizers(cnum)), + ) + .filter(|visualizer| visualizer.visualizer_type == visualizer_type) + .cloned() + .collect::>() +} + pub fn codegen_crate( backend: B, tcx: TyCtxt<'_>, @@ -607,6 +634,14 @@ pub fn codegen_crate( second_half.iter().rev().interleave(first_half).copied().collect() }; + // Calculate the CGU reuse + let cgu_reuse = tcx.sess.time("find_cgu_reuse", || { + codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::>() + }); + + let mut total_codegen_time = Duration::new(0, 0); + let start_rss = tcx.sess.time_passes().then(|| get_resident_set_size()); + // The non-parallel compiler can only translate codegen units to LLVM IR // on a single thread, leading to a staircase effect where the N LLVM // threads have to wait on the single codegen threads to generate work @@ -617,8 +652,7 @@ pub fn codegen_crate( // This likely is a temporary measure. Once we don't have to support the // non-parallel compiler anymore, we can compile CGUs end-to-end in // parallel and get rid of the complicated scheduling logic. - #[cfg(parallel_compiler)] - let pre_compile_cgus = |cgu_reuse: &[CguReuse]| { + let mut pre_compiled_cgus = if cfg!(parallel_compiler) { tcx.sess.time("compile_first_CGU_batch", || { // Try to find one CGU to compile per thread. let cgus: Vec<_> = cgu_reuse @@ -638,48 +672,31 @@ pub fn codegen_crate( }) .collect(); - (pre_compiled_cgus, start_time.elapsed()) + total_codegen_time += start_time.elapsed(); + + pre_compiled_cgus }) + } else { + FxHashMap::default() }; - #[cfg(not(parallel_compiler))] - let pre_compile_cgus = |_: &[CguReuse]| (FxHashMap::default(), Duration::new(0, 0)); - - let mut cgu_reuse = Vec::new(); - let mut pre_compiled_cgus: Option> = None; - let mut total_codegen_time = Duration::new(0, 0); - let start_rss = tcx.sess.time_passes().then(|| get_resident_set_size()); - for (i, cgu) in codegen_units.iter().enumerate() { ongoing_codegen.wait_for_signal_to_codegen_item(); ongoing_codegen.check_for_errors(tcx.sess); - // Do some setup work in the first iteration - if pre_compiled_cgus.is_none() { - // Calculate the CGU reuse - cgu_reuse = tcx.sess.time("find_cgu_reuse", || { - codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect() - }); - // Pre compile some CGUs - let (compiled_cgus, codegen_time) = pre_compile_cgus(&cgu_reuse); - pre_compiled_cgus = Some(compiled_cgus); - total_codegen_time += codegen_time; - } - let cgu_reuse = cgu_reuse[i]; tcx.sess.cgu_reuse_tracker.set_actual_reuse(cgu.name().as_str(), cgu_reuse); match cgu_reuse { CguReuse::No => { - let (module, cost) = - if let Some(cgu) = pre_compiled_cgus.as_mut().unwrap().remove(&i) { - cgu - } else { - let start_time = Instant::now(); - let module = backend.compile_codegen_unit(tcx, cgu.name()); - total_codegen_time += start_time.elapsed(); - module - }; + let (module, cost) = if let Some(cgu) = pre_compiled_cgus.remove(&i) { + cgu + } else { + let start_time = Instant::now(); + let module = backend.compile_codegen_unit(tcx, cgu.name()); + total_codegen_time += start_time.elapsed(); + module + }; // This will unwind if there are errors, which triggers our `AbortCodegenOnDrop` // guard. Unfortunately, just skipping the `submit_codegened_module_to_llvm` makes // compilation hang on post-monomorphization errors. @@ -700,7 +717,7 @@ pub fn codegen_crate( &ongoing_codegen.coordinator_send, CachedModuleCodegen { name: cgu.name().to_string(), - source: cgu.work_product(tcx), + source: cgu.previous_work_product(tcx), }, ); true @@ -711,7 +728,7 @@ pub fn codegen_crate( &ongoing_codegen.coordinator_send, CachedModuleCodegen { name: cgu.name().to_string(), - source: cgu.work_product(tcx), + source: cgu.previous_work_product(tcx), }, ); true @@ -847,13 +864,8 @@ impl CrateInfo { missing_lang_items: Default::default(), dependency_formats: tcx.dependency_formats(()).clone(), windows_subsystem, - debugger_visualizers: Default::default(), + natvis_debugger_visualizers: Default::default(), }; - let debugger_visualizers = tcx.debugger_visualizers(LOCAL_CRATE).clone(); - if !debugger_visualizers.is_empty() { - info.debugger_visualizers.insert(LOCAL_CRATE, debugger_visualizers); - } - let lang_items = tcx.lang_items(); let crates = tcx.crates(()); @@ -891,14 +903,29 @@ impl CrateInfo { let missing = missing.iter().cloned().filter(|&l| lang_items::required(tcx, l)).collect(); info.missing_lang_items.insert(cnum, missing); + } - // Only include debugger visualizer files from crates that will be statically linked. - if used_crate_source.rlib.is_some() || used_crate_source.rmeta.is_some() { - let debugger_visualizers = tcx.debugger_visualizers(cnum).clone(); - if !debugger_visualizers.is_empty() { - info.debugger_visualizers.insert(cnum, debugger_visualizers); - } + let embed_visualizers = tcx.sess.crate_types().iter().any(|&crate_type| match crate_type { + CrateType::Executable | CrateType::Dylib | CrateType::Cdylib => { + // These are crate types for which we invoke the linker and can embed + // NatVis visualizers. + true + } + CrateType::ProcMacro => { + // We could embed NatVis for proc macro crates too (to improve the debugging + // experience for them) but it does not seem like a good default, since + // this is a rare use case and we don't want to slow down the common case. + false } + CrateType::Staticlib | CrateType::Rlib => { + // We don't invoke the linker for these, so we don't need to collect the NatVis for them. + false + } + }); + + if tcx.sess.target.is_like_msvc && embed_visualizers { + info.natvis_debugger_visualizers = + collect_debugger_visualizers_transitive(tcx, DebuggerVisualizerType::Natvis); } info diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 1574b30497..8ca1a6084c 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -11,6 +11,7 @@ use rustc_span::Span; use crate::base; use crate::traits::*; +#[derive(Copy, Clone)] pub enum IntPredicate { IntEQ, IntNE, @@ -24,6 +25,7 @@ pub enum IntPredicate { IntSLE, } +#[derive(Copy, Clone)] pub enum RealPredicate { RealPredicateFalse, RealOEQ, @@ -43,6 +45,7 @@ pub enum RealPredicate { RealPredicateTrue, } +#[derive(Copy, Clone)] pub enum AtomicRmwBinOp { AtomicXchg, AtomicAdd, @@ -57,17 +60,17 @@ pub enum AtomicRmwBinOp { AtomicUMin, } +#[derive(Copy, Clone)] pub enum AtomicOrdering { - NotAtomic, Unordered, - Monotonic, - // Consume, // Not specified yet. + Relaxed, Acquire, Release, AcquireRelease, SequentiallyConsistent, } +#[derive(Copy, Clone)] pub enum SynchronizationScope { SingleThread, CrossThread, diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index ae43464791..8755d91818 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -180,7 +180,7 @@ fn push_debuginfo_type_name<'tcx>( if cpp_like_debuginfo { output.push_str("array$<"); push_debuginfo_type_name(tcx, inner_type, true, output, visited); - match len.val() { + match len.kind() { ty::ConstKind::Param(param) => write!(output, ",{}>", param.name).unwrap(), _ => write!(output, ",{}>", len.eval_usize(tcx, ty::ParamEnv::reveal_all())) .unwrap(), @@ -188,7 +188,7 @@ fn push_debuginfo_type_name<'tcx>( } else { output.push('['); push_debuginfo_type_name(tcx, inner_type, true, output, visited); - match len.val() { + match len.kind() { ty::ConstKind::Param(param) => write!(output, "; {}]", param.name).unwrap(), _ => write!(output, "; {}]", len.eval_usize(tcx, ty::ParamEnv::reveal_all())) .unwrap(), @@ -679,7 +679,7 @@ fn push_generic_params_internal<'tcx>( } fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut String) { - match ct.val() { + match ct.kind() { ty::ConstKind::Param(param) => { write!(output, "{}", param.name) } @@ -703,15 +703,19 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S // but we get a deterministic, virtually unique value for the constant. let hcx = &mut tcx.create_stable_hashing_context(); let mut hasher = StableHasher::new(); - hcx.while_hashing_spans(false, |hcx| ct.val().hash_stable(hcx, &mut hasher)); + let ct = ct.eval(tcx, ty::ParamEnv::reveal_all()); + hcx.while_hashing_spans(false, |hcx| ct.to_valtree().hash_stable(hcx, &mut hasher)); // Let's only emit 64 bits of the hash value. That should be plenty for // avoiding collisions and will make the emitted type names shorter. - let hash: u64 = hasher.finish(); + // Note: Don't use `StableHashResult` impl of `u64` here directly, since that + // would lead to endianness problems. + let hash: u128 = hasher.finish(); + let hash_short = (hash.to_le() as u64).to_le(); if cpp_like_debuginfo(tcx) { - write!(output, "CONST${:x}", hash) + write!(output, "CONST${:x}", hash_short) } else { - write!(output, "{{CONST#{:x}}}", hash) + write!(output, "{{CONST#{:x}}}", hash_short) } } }, diff --git a/compiler/rustc_codegen_ssa/src/glue.rs b/compiler/rustc_codegen_ssa/src/glue.rs index 694f5434e9..e6f402ef19 100644 --- a/compiler/rustc_codegen_ssa/src/glue.rs +++ b/compiler/rustc_codegen_ssa/src/glue.rs @@ -39,7 +39,12 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // The info in this case is the length of the str, so the size is that // times the unit size. ( - bx.mul(info.unwrap(), bx.const_usize(unit.size.bytes())), + // All slice sizes must fit into `isize`, so this multiplication cannot (signed) wrap. + // NOTE: ideally, we want the effects of both `unchecked_smul` and `unchecked_umul` + // (resulting in `mul nsw nuw` in LLVM IR), since we know that the multiplication + // cannot signed wrap, and that both operands are non-negative. But at the time of writing, + // `BuilderMethods` can't do this, and it doesn't seem to enable any further optimizations. + bx.unchecked_smul(info.unwrap(), bx.const_usize(unit.size.bytes())), bx.const_usize(unit.align.abi.bytes()), ) } diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 9e1fe588c5..6c30923bc3 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -3,7 +3,6 @@ #![feature(try_blocks)] #![feature(let_else)] #![feature(once_cell)] -#![feature(nll)] #![feature(associated_type_bounds)] #![feature(strict_provenance)] #![feature(int_roundings)] @@ -30,12 +29,14 @@ use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_middle::ty::query::{ExternProviders, Providers}; -use rustc_serialize::{opaque, Decodable, Decoder, Encoder}; +use rustc_serialize::opaque::{MemDecoder, MemEncoder}; +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT}; use rustc_session::cstore::{self, CrateSource}; use rustc_session::utils::NativeLibKind; use rustc_span::symbol::Symbol; use rustc_span::DebuggerVisualizerFile; +use std::collections::BTreeSet; use std::path::{Path, PathBuf}; pub mod back; @@ -157,7 +158,7 @@ pub struct CrateInfo { pub missing_lang_items: FxHashMap>, pub dependency_formats: Lrc, pub windows_subsystem: Option, - pub debugger_visualizers: FxHashMap>, + pub natvis_debugger_visualizers: BTreeSet, } #[derive(Encodable, Decodable)] @@ -203,16 +204,14 @@ const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION"); impl CodegenResults { pub fn serialize_rlink(codegen_results: &CodegenResults) -> Vec { - let mut encoder = opaque::Encoder::new(vec![]); - encoder.emit_raw_bytes(RLINK_MAGIC).unwrap(); + let mut encoder = MemEncoder::new(); + encoder.emit_raw_bytes(RLINK_MAGIC); // `emit_raw_bytes` is used to make sure that the version representation does not depend on // Encoder's inner representation of `u32`. - encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes()).unwrap(); - encoder.emit_str(RUSTC_VERSION.unwrap()).unwrap(); - - let mut encoder = rustc_serialize::opaque::Encoder::new(encoder.into_inner()); - rustc_serialize::Encodable::encode(codegen_results, &mut encoder).unwrap(); - encoder.into_inner() + encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes()); + encoder.emit_str(RUSTC_VERSION.unwrap()); + Encodable::encode(codegen_results, &mut encoder); + encoder.finish() } pub fn deserialize_rlink(data: Vec) -> Result { @@ -232,7 +231,7 @@ impl CodegenResults { return Err(".rlink file was produced with encoding version {version_array}, but the current version is {RLINK_VERSION}".to_string()); } - let mut decoder = opaque::Decoder::new(&data[4..], 0); + let mut decoder = MemDecoder::new(&data[4..], 0); let rustc_version = decoder.read_str(); let current_version = RUSTC_VERSION.unwrap(); if rustc_version != current_version { diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 00f101595f..5203ebfad7 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -1,6 +1,8 @@ use crate::traits::*; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, subst::GenericArgKind, ExistentialPredicate, Ty, TyCtxt}; +use rustc_session::config::Lto; +use rustc_symbol_mangling::typeid_for_trait_ref; use rustc_target::abi::call::FnAbi; #[derive(Copy, Clone, Debug)] @@ -15,20 +17,32 @@ impl<'a, 'tcx> VirtualIndex { self, bx: &mut Bx, llvtable: Bx::Value, + ty: Ty<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, ) -> Bx::Value { // Load the data pointer from the object. - debug!("get_fn({:?}, {:?})", llvtable, self); - + debug!("get_fn({llvtable:?}, {ty:?}, {self:?})"); let llty = bx.fn_ptr_backend_type(fn_abi); let llvtable = bx.pointercast(llvtable, bx.type_ptr_to(llty)); - let ptr_align = bx.tcx().data_layout.pointer_align.abi; - let gep = bx.inbounds_gep(llty, llvtable, &[bx.const_usize(self.0)]); - let ptr = bx.load(llty, gep, ptr_align); - bx.nonnull_metadata(ptr); - // Vtable loads are invariant. - bx.set_invariant_load(ptr); - ptr + + if bx.cx().sess().opts.debugging_opts.virtual_function_elimination + && bx.cx().sess().lto() == Lto::Fat + { + let typeid = + bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), get_trait_ref(bx.tcx(), ty))); + let vtable_byte_offset = self.0 * bx.data_layout().pointer_size.bytes(); + let type_checked_load = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); + let func = bx.extract_value(type_checked_load, 0); + bx.pointercast(func, llty) + } else { + let ptr_align = bx.tcx().data_layout.pointer_align.abi; + let gep = bx.inbounds_gep(llty, llvtable, &[bx.const_usize(self.0)]); + let ptr = bx.load(llty, gep, ptr_align); + bx.nonnull_metadata(ptr); + // Vtable loads are invariant. + bx.set_invariant_load(ptr); + ptr + } } pub fn get_usize>( @@ -50,6 +64,24 @@ impl<'a, 'tcx> VirtualIndex { } } +fn get_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> { + for arg in ty.peel_refs().walk() { + if let GenericArgKind::Type(ty) = arg.unpack() { + if let ty::Dynamic(trait_refs, _) = ty.kind() { + return trait_refs[0].map_bound(|trait_ref| match trait_ref { + ExistentialPredicate::Trait(tr) => tr, + ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx), + ExistentialPredicate::AutoTrait(_) => { + bug!("auto traits don't have functions") + } + }); + } + } + } + + bug!("expected a `dyn Trait` ty, found {ty:?}") +} + /// Creates a dynamic vtable for the given type and vtable origin. /// This is used only for objects. /// diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index fa39e8dd24..80dab115fa 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -328,7 +328,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec> FunctionCx<'a, 'tcx, Bx> { args = &args[..1]; ( meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE) - .get_fn(&mut bx, vtable, &fn_abi), + .get_fn(&mut bx, vtable, ty, &fn_abi), fn_abi, ) } @@ -519,8 +519,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { intrinsic: Option, instance: Option>, source_info: mir::SourceInfo, - destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>, + target: Option, cleanup: Option, + strict_validity: bool, ) -> bool { // Emit a panic or a no-op for `assert_*` intrinsics. // These are intrinsics that compile to panics so that we can get a message @@ -543,8 +544,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = bx.layout_of(ty); let do_panic = match intrinsic { Inhabited => layout.abi.is_uninhabited(), - ZeroValid => !layout.might_permit_raw_init(bx, /*zero:*/ true), - UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false), + ZeroValid => !layout.might_permit_raw_init(bx, InitKind::Zero, strict_validity), + UninitValid => !layout.might_permit_raw_init(bx, InitKind::Uninit, strict_validity), }; if do_panic { let msg_str = with_no_visible_paths!({ @@ -576,12 +577,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_abi, llfn, &[msg.0, msg.1, location], - destination.as_ref().map(|(_, bb)| (ReturnDest::Nothing, *bb)), + target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)), cleanup, ); } else { // a NOP - let target = destination.as_ref().unwrap().1; + let target = target.unwrap(); helper.funclet_br(self, bx, target) } true @@ -597,7 +598,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { terminator: &mir::Terminator<'tcx>, func: &mir::Operand<'tcx>, args: &[mir::Operand<'tcx>], - destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>, + destination: mir::Place<'tcx>, + target: Option, cleanup: Option, fn_span: Span, ) { @@ -624,7 +626,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if let Some(ty::InstanceDef::DropGlue(_, None)) = def { // Empty drop glue; a no-op. - let &(_, target) = destination.as_ref().unwrap(); + let target = target.unwrap(); helper.funclet_br(self, &mut bx, target); return; } @@ -653,9 +655,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; if intrinsic == Some(sym::transmute) { - if let Some(destination_ref) = destination.as_ref() { - let &(dest, target) = destination_ref; - self.codegen_transmute(&mut bx, &args[0], dest); + if let Some(target) = target { + self.codegen_transmute(&mut bx, &args[0], destination); helper.funclet_br(self, &mut bx, target); } else { // If we are trying to transmute to an uninhabited type, @@ -676,8 +677,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { intrinsic, instance, source_info, - destination, + target, cleanup, + self.cx.tcx().sess.opts.debugging_opts.strict_init_checks, ) { return; } @@ -687,15 +689,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let mut llargs = Vec::with_capacity(arg_count); // Prepare the return value destination - let ret_dest = if let Some((dest, _)) = *destination { + let ret_dest = if target.is_some() { let is_intrinsic = intrinsic.is_some(); - self.make_return_dest(&mut bx, dest, &fn_abi.ret, &mut llargs, is_intrinsic) + self.make_return_dest(&mut bx, destination, &fn_abi.ret, &mut llargs, is_intrinsic) } else { ReturnDest::Nothing }; if intrinsic == Some(sym::caller_location) { - if let Some((_, target)) = destination.as_ref() { + if let Some(target) = target { let location = self .get_caller_location(&mut bx, mir::SourceInfo { span: fn_span, ..source_info }); @@ -703,7 +705,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { location.val.store(&mut bx, tmp); } self.store_return(&mut bx, ret_dest, &fn_abi.ret, location.immediate()); - helper.funclet_br(self, &mut bx, *target); + helper.funclet_br(self, &mut bx, target); } return; } @@ -766,7 +768,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.store_return(&mut bx, ret_dest, &fn_abi.ret, dst.llval); } - if let Some((_, target)) = *destination { + if let Some(target) = target { helper.funclet_br(self, &mut bx, target); } else { bx.unreachable(); @@ -817,9 +819,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // the data pointer as the first argument match op.val { Pair(data_ptr, meta) => { - llfn = Some( - meth::VirtualIndex::from_index(idx).get_fn(&mut bx, meta, &fn_abi), - ); + llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( + &mut bx, + meta, + op.layout.ty, + &fn_abi, + )); llargs.push(data_ptr); continue 'make_args; } @@ -827,7 +832,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } else if let Ref(data_ptr, Some(meta), _) = op.val { // by-value dynamic dispatch - llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(&mut bx, meta, &fn_abi)); + llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( + &mut bx, + meta, + op.layout.ty, + &fn_abi, + )); llargs.push(data_ptr); continue; } else { @@ -913,7 +923,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_abi, fn_ptr, &llargs, - destination.as_ref().map(|&(_, target)| (ret_dest, target)), + target.as_ref().map(|&target| (ret_dest, target)), cleanup, ); @@ -930,7 +940,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_abi, fn_ptr, &llargs, - destination.as_ref().map(|&(_, target)| (ret_dest, target)), + target.as_ref().map(|&target| (ret_dest, target)), cleanup, ); } @@ -1083,7 +1093,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::TerminatorKind::Call { ref func, ref args, - ref destination, + destination, + target, cleanup, from_hir_call: _, fn_span, @@ -1095,6 +1106,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { func, args, destination, + target, cleanup, fn_span, ); diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 479b2b05f4..9a995fbf65 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -29,7 +29,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::ConstantKind::Ty(ct) => ct, mir::ConstantKind::Val(val, _) => return Ok(val), }; - match ct.val() { + match ct.kind() { ty::ConstKind::Unevaluated(ct) => self .cx .tcx() @@ -38,7 +38,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); err }), - ty::ConstKind::Value(value) => Ok(value), + ty::ConstKind::Value(val) => Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val))), err => span_bug!( constant.span, "encountered bad ConstKind after monomorphizing: {:?}", @@ -58,14 +58,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant .map(|val| { let field_ty = ty.builtin_index().unwrap(); - let c = ty::Const::from_value(bx.tcx(), val, ty); + let c = mir::ConstantKind::from_value(val, ty); let values: Vec<_> = bx .tcx() - .destructure_const(ty::ParamEnv::reveal_all().and(c)) + .destructure_mir_constant(ty::ParamEnv::reveal_all(), c) .fields .iter() .map(|field| { - if let Some(prim) = field.val().try_to_scalar() { + if let Some(prim) = field.try_to_scalar() { let layout = bx.layout_of(field_ty); let Abi::Scalar(scalar) = layout.abi else { bug!("from_const: invalid ByVal layout: {:#?}", layout); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 6d6d3ae01f..0ed4c3f1d9 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -388,17 +388,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { 2 => (SequentiallyConsistent, SequentiallyConsistent), 3 => match split[2] { "unordered" => (Unordered, Unordered), - "relaxed" => (Monotonic, Monotonic), + "relaxed" => (Relaxed, Relaxed), "acq" => (Acquire, Acquire), - "rel" => (Release, Monotonic), + "rel" => (Release, Relaxed), "acqrel" => (AcquireRelease, Acquire), - "failrelaxed" if is_cxchg => (SequentiallyConsistent, Monotonic), + "failrelaxed" if is_cxchg => (SequentiallyConsistent, Relaxed), "failacq" if is_cxchg => (SequentiallyConsistent, Acquire), _ => bx.sess().fatal("unknown ordering in atomic intrinsic"), }, 4 => match (split[2], split[3]) { - ("acq", "failrelaxed") if is_cxchg => (Acquire, Monotonic), - ("acqrel", "failrelaxed") if is_cxchg => (AcquireRelease, Monotonic), + ("acq", "failrelaxed") if is_cxchg => (Acquire, Relaxed), + ("acqrel", "failrelaxed") if is_cxchg => (AcquireRelease, Relaxed), _ => bx.sess().fatal("unknown ordering in atomic intrinsic"), }, _ => bx.sess().fatal("Atomic intrinsic not in correct format"), diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 08be4c0a7b..2e655ae94c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -118,22 +118,20 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { } pub fn deref>(self, cx: &Cx) -> PlaceRef<'tcx, V> { + if self.layout.ty.is_box() { + bug!("dereferencing {:?} in codegen", self.layout.ty); + } + let projected_ty = self .layout .ty .builtin_deref(true) .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)) .ty; + let (llptr, llextra) = match self.val { OperandValue::Immediate(llptr) => (llptr, None), - OperandValue::Pair(llptr, llextra) => { - // if the box's allocator isn't a ZST, then "llextra" is actually the allocator - if self.layout.ty.is_box() && !self.layout.field(cx, 1).is_zst() { - (llptr, None) - } else { - (llptr, Some(llextra)) - } - } + OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self), }; let layout = cx.layout_of(projected_ty); diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index b6a7bcae93..5b88635982 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -446,35 +446,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref }, ); - // a box with a non-zst allocator should not be directly dereferenced - if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() { - // Extract `Box` -> `Unique` -> `NonNull` -> `*const T` - let ptr = - cg_base.extract_field(bx, 0).extract_field(bx, 0).extract_field(bx, 0); - - ptr.deref(bx.cx()) - } else { - cg_base.deref(bx.cx()) - } + cg_base.deref(bx.cx()) } else { bug!("using operand local {:?} as place", place_ref); } } }; for elem in place_ref.projection[base..].iter() { - cg_base = match elem.clone() { - mir::ProjectionElem::Deref => { - // a box with a non-zst allocator should not be directly dereferenced - if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() { - // Project `Box` -> `Unique` -> `NonNull` -> `*const T` - let ptr = - cg_base.project_field(bx, 0).project_field(bx, 0).project_field(bx, 0); - - bx.load_operand(ptr).deref(bx.cx()) - } else { - bx.load_operand(cg_base).deref(bx.cx()) - } - } + cg_base = match *elem { + mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()), mir::ProjectionElem::Field(ref field, _) => { cg_base.project_field(bx, field.index()) } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index fd29c9e281..81c1897694 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -181,6 +181,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let cast = bx.cx().layout_of(self.monomorphize(mir_cast_ty)); let val = match *kind { + mir::CastKind::PointerExposeAddress => { + assert!(bx.cx().is_backend_immediate(cast)); + let llptr = operand.immediate(); + let llcast_ty = bx.cx().immediate_backend_type(cast); + let lladdr = bx.ptrtoint(llptr, llcast_ty); + OperandValue::Immediate(lladdr) + } mir::CastKind::Pointer(PointerCast::ReifyFnPointer) => { match *operand.layout.ty.kind() { ty::FnDef(def_id, substs) => { @@ -262,7 +269,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::CastKind::Pointer( PointerCast::MutToConstPointer | PointerCast::ArrayToPointer, ) - | mir::CastKind::Misc => { + | mir::CastKind::Misc + // Since int2ptr can have arbitrary integer types as input (so we have to do + // sign extension and all that), it is currently best handled in the same code + // path as the other integer-to-X casts. + | mir::CastKind::PointerFromExposedAddress => { assert!(bx.cx().is_backend_immediate(cast)); let ll_t_out = bx.cx().immediate_backend_type(cast); if operand.layout.abi.is_uninhabited() { @@ -362,9 +373,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Ptr(_)) => { bx.pointercast(llval, ll_t_out) } - (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => { - bx.ptrtoint(llval, ll_t_out) - } (CastTy::Int(_), CastTy::Ptr(_)) => { let usize_llval = bx.intcast(llval, bx.cx().type_isize(), signed); bx.inttoptr(usize_llval, ll_t_out) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index ba1e186222..bfdef2dc0e 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -246,6 +246,9 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("simd128", None), ("atomics", Some(sym::wasm_target_feature)), ("nontrapping-fptoint", Some(sym::wasm_target_feature)), + ("bulk-memory", Some(sym::wasm_target_feature)), + ("mutable-globals", Some(sym::wasm_target_feature)), + ("reference-types", Some(sym::wasm_target_feature)), ]; const BPF_ALLOWED_FEATURES: &[(&str, Option)] = &[("alu32", Some(sym::bpf_target_feature))]; diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index 02be6cd360..7755e67938 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -22,6 +22,14 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes { fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value; /// Trait method used to test whether a given pointer is associated with a type identifier. fn type_test(&mut self, pointer: Self::Value, typeid: Self::Value) -> Self::Value; + /// Trait method used to load a function while testing if it is associated with a type + /// identifier. + fn type_checked_load( + &mut self, + llvtable: Self::Value, + vtable_byte_offset: u64, + typeid: Self::Value, + ) -> Self::Value; /// Trait method used to inject `va_start` on the "spoofed" `VaListImpl` in /// Rust defined C-variadic functions. fn va_start(&mut self, val: Self::Value) -> Self::Value; diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index 4ed908a383..32e8233a04 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -24,3 +24,4 @@ rustc_session = { path = "../rustc_session" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_span = { path = "../rustc_span" } +rustc_type_ir = { path = "../rustc_type_ir" } diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 3bd092263c..3eeb0138b3 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -140,6 +140,7 @@ impl<'tcx> ConstEvalErr<'tcx> { /// /// If `lint_root.is_some()` report it as a lint, else report it as a hard error. /// (Except that for some errors, we ignore all that -- see `must_error` below.) + #[instrument(skip(self, tcx, decorate, lint_root), level = "debug")] fn struct_generic( &self, tcx: TyCtxtAt<'tcx>, @@ -190,6 +191,7 @@ impl<'tcx> ConstEvalErr<'tcx> { decorate(err); }; + debug!("self.error: {:?}", self.error); // Special handling for certain errors match &self.error { // Don't emit a new diagnostic for these errors diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 5c56e6ee5f..b7e5e7aea4 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -60,7 +60,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( ecx.push_stack_frame( cid.instance, body, - Some(&ret.into()), + &ret.into(), StackPopCleanup::Root { cleanup: false }, )?; @@ -135,7 +135,7 @@ pub(super) fn op_to_const<'tcx>( } 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_const, i.e., if this is (a field of) something that we + // 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() @@ -196,7 +196,7 @@ pub(super) fn op_to_const<'tcx>( } #[instrument(skip(tcx), level = "debug")] -fn turn_into_const_value<'tcx>( +pub(crate) fn turn_into_const_value<'tcx>( tcx: TyCtxt<'tcx>, constant: ConstAlloc<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, @@ -222,6 +222,7 @@ fn turn_into_const_value<'tcx>( const_val } +#[instrument(skip(tcx), level = "debug")] pub fn eval_to_const_value_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, @@ -256,6 +257,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>( tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key)) } +#[instrument(skip(tcx), level = "debug")] pub fn eval_to_allocation_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 1f291db55b..f1674d04f8 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -4,13 +4,12 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{DefIdTree, TyCtxt}; use rustc_span::symbol::Symbol; -use rustc_target::spec::abi::Abi; /// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { if tcx.is_const_fn_raw(def_id) { let const_stab = tcx.lookup_const_stability(def_id)?; - if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None } + if const_stab.is_const_unstable() { Some(const_stab.feature) } else { None } } else { None } @@ -18,13 +17,14 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { let parent_id = tcx.local_parent(def_id); - tcx.def_kind(parent_id) == DefKind::Impl - && tcx.impl_constness(parent_id) == hir::Constness::Const + tcx.def_kind(parent_id) == DefKind::Impl && tcx.constness(parent_id) == hir::Constness::Const } -/// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether -/// said intrinsic has a `rustc_const_{un,}stable` attribute. -fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness { +/// Checks whether an item is considered to be `const`. If it is a constructor, it is const. If +/// it is a trait impl/function, return if it has a `const` modifier. If it is an intrinsic, +/// report whether said intrinsic has a `rustc_const_{un,}stable` attribute. Otherwise, return +/// `Constness::NotConst`. +fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness { let def_id = def_id.expect_local(); let node = tcx.hir().get_by_def_id(def_id); @@ -34,10 +34,7 @@ fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness { hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other // foreign items cannot be evaluated at compile-time. - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - let is_const = if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = - tcx.hir().get_foreign_abi(hir_id) - { + let is_const = if tcx.is_intrinsic(def_id) { tcx.lookup_const_stability(def_id).is_some() } else { false @@ -81,5 +78,5 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } pub fn provide(providers: &mut Providers) { - *providers = Providers { impl_constness, is_promotable_const_fn, ..*providers }; + *providers = Providers { constness, is_promotable_const_fn, ..*providers }; } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index c5a11aacea..ac529bf152 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -163,7 +163,7 @@ impl interpret::AllocMap for FxHashMap { } } -crate type CompileTimeEvalContext<'mir, 'tcx> = +pub(crate) type CompileTimeEvalContext<'mir, 'tcx> = InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>; #[derive(Debug, PartialEq, Eq, Copy, Clone)] @@ -265,7 +265,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, instance: ty::Instance<'tcx>, _abi: Abi, args: &[OpTy<'tcx>], - _ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>, + _dest: &PlaceTy<'tcx>, + _ret: Option, _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); @@ -276,8 +277,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, // sensitive check here. But we can at least rule out functions that are not const // at all. if !ecx.tcx.is_const_fn_raw(def.did) { - // allow calling functions marked with #[default_method_body_is_const]. - if !ecx.tcx.has_attr(def.did, sym::default_method_body_is_const) { + // allow calling functions inside a trait marked with #[const_trait]. + if !ecx.tcx.is_const_default_method(def.did) { // We certainly do *not* want to actually call the fn // though, so be sure we return here. throw_unsup_format!("calling non-const function `{}`", instance) @@ -293,6 +294,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, new_instance, _abi, args, + _dest, _ret, _unwind, )? @@ -307,17 +309,18 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], - ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>, + dest: &PlaceTy<'tcx, Self::PointerTag>, + target: Option, _unwind: StackPopUnwind, ) -> InterpResult<'tcx> { // Shared intrinsics. - if ecx.emulate_intrinsic(instance, args, ret)? { + if ecx.emulate_intrinsic(instance, args, dest, target)? { return Ok(()); } let intrinsic_name = ecx.tcx.item_name(instance.def_id()); // CTFE-specific intrinsics. - let Some((dest, ret)) = ret else { + let Some(ret) = target else { return Err(ConstEvalErrKind::NeedsRfc(format!( "calling intrinsic `{}`", intrinsic_name diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 96c18d488e..a1d2e5cf3e 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,11 +1,11 @@ // Not in interpret to make sure we do not use private implementation details -use std::convert::TryFrom; - use rustc_hir::Mutability; use rustc_middle::mir; +use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{source_map::DUMMY_SP, symbol::Symbol}; +use rustc_target::abi::VariantIdx; use crate::interpret::{ intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta, @@ -22,7 +22,7 @@ pub use error::*; pub use eval_queries::*; pub use fn_queries::*; pub use machine::*; -pub(crate) use valtrees::{const_to_valtree, valtree_to_const_value}; +pub(crate) use valtrees::{const_to_valtree_inner, valtree_to_const_value}; pub(crate) fn const_caller_location( tcx: TyCtxt<'_>, @@ -38,67 +38,194 @@ pub(crate) fn const_caller_location( ConstValue::Scalar(Scalar::from_maybe_pointer(loc_place.ptr, &tcx)) } -/// This function should never fail for validated constants. However, it is also invoked from the -/// pretty printer which might attempt to format invalid constants and in that case it might fail. +// We forbid type-level constants that contain more than `VALTREE_MAX_NODES` nodes. +const VALTREE_MAX_NODES: usize = 100000; + +pub(crate) enum ValTreeCreationError { + NodesOverflow, + NonSupportedType, + Other, +} +pub(crate) type ValTreeCreationResult<'tcx> = Result, ValTreeCreationError>; + +/// Evaluates a constant and turns it into a type-level constant value. +pub(crate) fn eval_to_valtree<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + cid: GlobalId<'tcx>, +) -> EvalToValTreeResult<'tcx> { + let const_alloc = tcx.eval_to_allocation_raw(param_env.and(cid))?; + + // FIXME Need to provide a span to `eval_to_valtree` + let ecx = mk_eval_cx( + tcx, DUMMY_SP, param_env, + // It is absolutely crucial for soundness that + // we do not read from static items or other mutable memory. + false, + ); + let place = ecx.raw_const_to_mplace(const_alloc).unwrap(); + debug!(?place); + + let mut num_nodes = 0; + let valtree_result = const_to_valtree_inner(&ecx, &place, &mut num_nodes); + + match valtree_result { + Ok(valtree) => Ok(Some(valtree)), + Err(err) => { + let did = cid.instance.def_id(); + let s = cid.display(tcx); + match err { + ValTreeCreationError::NodesOverflow => { + let msg = format!("maximum number of nodes exceeded in constant {}", &s); + let mut diag = match tcx.hir().span_if_local(did) { + Some(span) => tcx.sess.struct_span_err(span, &msg), + None => tcx.sess.struct_err(&msg), + }; + diag.emit(); + + Ok(None) + } + ValTreeCreationError::NonSupportedType | ValTreeCreationError::Other => Ok(None), + } + } + } +} + +/// Tries to destructure constants of type Array or Adt into the constants +/// of its fields. pub(crate) fn try_destructure_const<'tcx>( + tcx: TyCtxt<'tcx>, + const_: ty::Const<'tcx>, +) -> Option> { + if let ty::ConstKind::Value(valtree) = const_.kind() { + let branches = match valtree { + ty::ValTree::Branch(b) => b, + _ => return None, + }; + + let (fields, variant) = match const_.ty().kind() { + ty::Array(inner_ty, _) | ty::Slice(inner_ty) => { + // construct the consts for the elements of the array/slice + let field_consts = branches + .iter() + .map(|b| { + tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Value(*b), ty: *inner_ty }) + }) + .collect::>(); + debug!(?field_consts); + + (field_consts, None) + } + ty::Adt(def, _) if def.variants().is_empty() => bug!("unreachable"), + ty::Adt(def, substs) => { + let variant_idx = if def.is_enum() { + VariantIdx::from_u32(branches[0].unwrap_leaf().try_to_u32().ok()?) + } else { + VariantIdx::from_u32(0) + }; + let fields = &def.variant(variant_idx).fields; + let mut field_consts = Vec::with_capacity(fields.len()); + + // Note: First element inValTree corresponds to variant of enum + let mut valtree_idx = if def.is_enum() { 1 } else { 0 }; + for field in fields { + let field_ty = field.ty(tcx, substs); + let field_valtree = branches[valtree_idx]; // first element of branches is variant + let field_const = tcx.mk_const(ty::ConstS { + kind: ty::ConstKind::Value(field_valtree), + ty: field_ty, + }); + field_consts.push(field_const); + valtree_idx += 1; + } + debug!(?field_consts); + + (field_consts, Some(variant_idx)) + } + ty::Tuple(elem_tys) => { + let fields = elem_tys + .iter() + .enumerate() + .map(|(i, elem_ty)| { + let elem_valtree = branches[i]; + tcx.mk_const(ty::ConstS { + kind: ty::ConstKind::Value(elem_valtree), + ty: elem_ty, + }) + }) + .collect::>(); + + (fields, None) + } + _ => bug!("cannot destructure constant {:?}", const_), + }; + + let fields = tcx.arena.alloc_from_iter(fields.into_iter()); + + Some(ty::DestructuredConst { variant, fields }) + } else { + None + } +} + +#[instrument(skip(tcx), level = "debug")] +pub(crate) fn try_destructure_mir_constant<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - val: ty::Const<'tcx>, -) -> InterpResult<'tcx, mir::DestructuredConst<'tcx>> { - trace!("destructure_const: {:?}", val); + val: mir::ConstantKind<'tcx>, +) -> InterpResult<'tcx, mir::DestructuredMirConstant<'tcx>> { + trace!("destructure_mir_constant: {:?}", val); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.const_to_op(val, None)?; + let op = ecx.mir_const_to_op(&val, None)?; // We go to `usize` as we cannot allocate anything bigger anyway. let (field_count, variant, down) = match val.ty().kind() { - ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op), - // Checks if we have any variants, to avoid downcasting to a non-existing variant (when - // there are no variants `read_discriminant` successfully returns a non-existing variant - // index). - ty::Adt(def, _) if def.variants().is_empty() => throw_ub!(Unreachable), + ty::Array(_, len) => (len.eval_usize(tcx, param_env) as usize, None, op), + ty::Adt(def, _) if def.variants().is_empty() => { + throw_ub!(Unreachable) + } ty::Adt(def, _) => { let variant = ecx.read_discriminant(&op)?.1; let down = ecx.operand_downcast(&op, variant)?; - (def.variant(variant).fields.len(), Some(variant), down) + (def.variants()[variant].fields.len(), Some(variant), down) } ty::Tuple(substs) => (substs.len(), None, op), - _ => bug!("cannot destructure constant {:?}", val), + _ => bug!("cannot destructure mir constant {:?}", val), }; - let fields = (0..field_count) + let fields_iter = (0..field_count) .map(|i| { let field_op = ecx.operand_field(&down, i)?; let val = op_to_const(&ecx, &field_op); - Ok(ty::Const::from_value(tcx, val, field_op.layout.ty)) + Ok(mir::ConstantKind::Val(val, field_op.layout.ty)) }) .collect::>>()?; - let fields = tcx.arena.alloc_from_iter(fields); + let fields = tcx.arena.alloc_from_iter(fields_iter); - Ok(mir::DestructuredConst { variant, fields }) + Ok(mir::DestructuredMirConstant { variant, fields }) } #[instrument(skip(tcx), level = "debug")] -pub(crate) fn deref_const<'tcx>( +pub(crate) fn deref_mir_constant<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - val: ty::Const<'tcx>, -) -> ty::Const<'tcx> { - trace!("deref_const: {:?}", val); + val: mir::ConstantKind<'tcx>, +) -> mir::ConstantKind<'tcx> { let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.const_to_op(val, None).unwrap(); + let op = ecx.mir_const_to_op(&val, None).unwrap(); let mplace = ecx.deref_operand(&op).unwrap(); if let Some(alloc_id) = mplace.ptr.provenance { assert_eq!( - tcx.get_global_alloc(alloc_id).unwrap().unwrap_memory().inner().mutability, + tcx.get_global_alloc(alloc_id).unwrap().unwrap_memory().0.0.mutability, Mutability::Not, - "deref_const cannot be used with mutable allocations as \ + "deref_mir_constant cannot be used with mutable allocations as \ that could allow pattern matching to observe mutable statics", ); } let ty = match mplace.meta { MemPlaceMeta::None => mplace.layout.ty, - MemPlaceMeta::Poison => bug!("poison metadata in `deref_const`: {:#?}", mplace), + MemPlaceMeta::Poison => bug!("poison metadata in `deref_mir_constant`: {:#?}", mplace), // In case of unsized types, figure out the real type behind. MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() { ty::Str => bug!("there's no sized equivalent of a `str`"), @@ -111,5 +238,5 @@ pub(crate) fn deref_const<'tcx>( }, }; - tcx.mk_const(ty::ConstS { val: ty::ConstKind::Value(op_to_const(&ecx, &mplace.into())), ty }) + mir::ConstantKind::Val(op_to_const(&ecx, &mplace.into()), ty) } diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index f57f25c19f..4849a07e3b 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -1,41 +1,23 @@ use super::eval_queries::{mk_eval_cx, op_to_const}; use super::machine::CompileTimeEvalContext; +use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES}; use crate::interpret::{ intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta, MemoryKind, PlaceTy, Scalar, ScalarMaybeUninit, }; -use rustc_middle::mir::interpret::ConstAlloc; +use crate::interpret::{MPlaceTy, Value}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_span::source_map::DUMMY_SP; use rustc_target::abi::{Align, VariantIdx}; -use crate::interpret::MPlaceTy; -use crate::interpret::Value; - -/// Convert an evaluated constant to a type level constant -#[instrument(skip(tcx), level = "debug")] -pub(crate) fn const_to_valtree<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - raw: ConstAlloc<'tcx>, -) -> Option> { - let ecx = mk_eval_cx( - tcx, DUMMY_SP, param_env, - // It is absolutely crucial for soundness that - // we do not read from static items or other mutable memory. - false, - ); - let place = ecx.raw_const_to_mplace(raw).unwrap(); - const_to_valtree_inner(&ecx, &place) -} - #[instrument(skip(ecx), level = "debug")] fn branches<'tcx>( ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: &MPlaceTy<'tcx>, n: usize, variant: Option, -) -> Option> { + num_nodes: &mut usize, +) -> ValTreeCreationResult<'tcx> { let place = match variant { Some(variant) => ecx.mplace_downcast(&place, variant).unwrap(), None => *place, @@ -43,82 +25,116 @@ fn branches<'tcx>( let variant = variant.map(|variant| Some(ty::ValTree::Leaf(ScalarInt::from(variant.as_u32())))); debug!(?place, ?variant); - let fields = (0..n).map(|i| { + let mut fields = Vec::with_capacity(n); + for i in 0..n { let field = ecx.mplace_field(&place, i).unwrap(); - const_to_valtree_inner(ecx, &field) - }); - // For enums, we preped their variant index before the variant's fields so we can figure out + let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?; + fields.push(Some(valtree)); + } + + // For enums, we prepend their variant index before the variant's fields so we can figure out // the variant again when just seeing a valtree. - let branches = variant.into_iter().chain(fields); - Some(ty::ValTree::Branch(ecx.tcx.arena.alloc_from_iter(branches.collect::>>()?))) + let branches = variant + .into_iter() + .chain(fields.into_iter()) + .collect::>>() + .expect("should have already checked for errors in ValTree creation"); + + // Have to account for ZSTs here + if branches.len() == 0 { + *num_nodes += 1; + } + + Ok(ty::ValTree::Branch(ecx.tcx.arena.alloc_from_iter(branches))) } #[instrument(skip(ecx), level = "debug")] fn slice_branches<'tcx>( ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: &MPlaceTy<'tcx>, -) -> Option> { + num_nodes: &mut usize, +) -> ValTreeCreationResult<'tcx> { let n = place .len(&ecx.tcx.tcx) .unwrap_or_else(|_| panic!("expected to use len of place {:?}", place)); - let branches = (0..n).map(|i| { + + let mut elems = Vec::with_capacity(n as usize); + for i in 0..n { let place_elem = ecx.mplace_index(place, i).unwrap(); - const_to_valtree_inner(ecx, &place_elem) - }); + let valtree = const_to_valtree_inner(ecx, &place_elem, num_nodes)?; + elems.push(valtree); + } - Some(ty::ValTree::Branch(ecx.tcx.arena.alloc_from_iter(branches.collect::>>()?))) + Ok(ty::ValTree::Branch(ecx.tcx.arena.alloc_from_iter(elems))) } #[instrument(skip(ecx), level = "debug")] -fn const_to_valtree_inner<'tcx>( +pub(crate) fn const_to_valtree_inner<'tcx>( ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: &MPlaceTy<'tcx>, -) -> Option> { - match place.layout.ty.kind() { - ty::FnDef(..) => Some(ty::ValTree::zst()), + num_nodes: &mut usize, +) -> ValTreeCreationResult<'tcx> { + let ty = place.layout.ty; + debug!("ty kind: {:?}", ty.kind()); + + if *num_nodes >= VALTREE_MAX_NODES { + return Err(ValTreeCreationError::NodesOverflow); + } + + match ty.kind() { + ty::FnDef(..) => { + *num_nodes += 1; + Ok(ty::ValTree::zst()) + } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { - let val = ecx.read_immediate(&place.into()).unwrap(); + let Ok(val) = ecx.read_immediate(&place.into()) else { + return Err(ValTreeCreationError::Other); + }; let val = val.to_scalar().unwrap(); - Some(ty::ValTree::Leaf(val.assert_int())) + *num_nodes += 1; + + Ok(ty::ValTree::Leaf(val.assert_int())) } // Raw pointers are not allowed in type level constants, as we cannot properly test them for // equality at compile-time (see `ptr_guaranteed_eq`/`_ne`). // Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to // agree with runtime equality tests. - ty::FnPtr(_) | ty::RawPtr(_) => None, + ty::FnPtr(_) | ty::RawPtr(_) => Err(ValTreeCreationError::NonSupportedType), ty::Ref(_, _, _) => { - let derefd_place = ecx.deref_operand(&place.into()).unwrap_or_else(|e| bug!("couldn't deref {:?}, error: {:?}", place, e)); + let Ok(derefd_place)= ecx.deref_operand(&place.into()) else { + return Err(ValTreeCreationError::Other); + }; debug!(?derefd_place); - const_to_valtree_inner(ecx, &derefd_place) + const_to_valtree_inner(ecx, &derefd_place, num_nodes) } ty::Str | ty::Slice(_) | ty::Array(_, _) => { - let valtree = slice_branches(ecx, place); - debug!(?valtree); - - valtree + slice_branches(ecx, place, num_nodes) } // Trait objects are not allowed in type level constants, as we have no concept for // resolving their backing type, even if we can do that at const eval time. We may // hypothetically be able to allow `dyn StructuralEq` trait objects in the future, // but it is unclear if this is useful. - ty::Dynamic(..) => None, + ty::Dynamic(..) => Err(ValTreeCreationError::NonSupportedType), - ty::Tuple(substs) => branches(ecx, place, substs.len(), None), + ty::Tuple(elem_tys) => { + branches(ecx, place, elem_tys.len(), None, num_nodes) + } ty::Adt(def, _) => { if def.is_union() { - return None + return Err(ValTreeCreationError::NonSupportedType); } else if def.variants().is_empty() { bug!("uninhabited types should have errored and never gotten converted to valtree") } - let variant = ecx.read_discriminant(&place.into()).unwrap().1; - - branches(ecx, place, def.variant(variant).fields.len(), def.is_enum().then_some(variant)) + let Ok((_, variant)) = ecx.read_discriminant(&place.into()) else { + return Err(ValTreeCreationError::Other); + }; + branches(ecx, place, def.variant(variant).fields.len(), def.is_enum().then_some(variant), num_nodes) } ty::Never @@ -136,7 +152,7 @@ fn const_to_valtree_inner<'tcx>( // FIXME(oli-obk): we can probably encode closures just like structs | ty::Closure(..) | ty::Generator(..) - | ty::GeneratorWitness(..) => None, + | ty::GeneratorWitness(..) => Err(ValTreeCreationError::NonSupportedType), } } @@ -216,17 +232,16 @@ fn create_pointee_place<'tcx>( // Get the size of the memory behind the DST let dst_size = unsized_inner_ty_size.checked_mul(num_elems as u64, &tcx).unwrap(); - let ptr = ecx - .allocate_ptr( - size_of_sized_part.checked_add(dst_size, &tcx).unwrap(), - Align::from_bytes(1).unwrap(), - MemoryKind::Stack, - ) - .unwrap(); + let size = size_of_sized_part.checked_add(dst_size, &tcx).unwrap(); + let align = Align::from_bytes(size.bytes().next_power_of_two()).unwrap(); + let ptr = ecx.allocate_ptr(size, align, MemoryKind::Stack).unwrap(); debug!(?ptr); - let mut place = MPlaceTy::from_aligned_ptr(ptr.into(), layout); - place.meta = MemPlaceMeta::Meta(Scalar::from_u64(num_elems as u64)); + let place = MPlaceTy::from_aligned_ptr_with_meta( + ptr.into(), + layout, + MemPlaceMeta::Meta(Scalar::from_machine_usize(num_elems as u64, &tcx)), + ); debug!(?place); place @@ -237,7 +252,7 @@ fn create_pointee_place<'tcx>( /// Converts a `ValTree` to a `ConstValue`, which is needed after mir /// construction has finished. -// FIXME Merge `valtree_to_const_value` and `fill_place_recursively` into one function +// FIXME Merge `valtree_to_const_value` and `valtree_into_mplace` into one function #[instrument(skip(tcx), level = "debug")] pub fn valtree_to_const_value<'tcx>( tcx: TyCtxt<'tcx>, @@ -275,7 +290,7 @@ pub fn valtree_to_const_value<'tcx>( }; debug!(?place); - fill_place_recursively(&mut ecx, &mut place, valtree); + valtree_into_mplace(&mut ecx, &mut place, valtree); dump_place(&ecx, place.into()); intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap(); @@ -315,9 +330,8 @@ pub fn valtree_to_const_value<'tcx>( } } -// FIXME Needs a better/correct name #[instrument(skip(ecx), level = "debug")] -fn fill_place_recursively<'tcx>( +fn valtree_into_mplace<'tcx>( ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>, place: &mut MPlaceTy<'tcx>, valtree: ty::ValTree<'tcx>, @@ -349,14 +363,15 @@ fn fill_place_recursively<'tcx>( let mut pointee_place = create_pointee_place(ecx, *inner_ty, valtree); debug!(?pointee_place); - fill_place_recursively(ecx, &mut pointee_place, valtree); + valtree_into_mplace(ecx, &mut pointee_place, valtree); dump_place(ecx, pointee_place.into()); intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place).unwrap(); let imm = match inner_ty.kind() { ty::Slice(_) | ty::Str => { let len = valtree.unwrap_branch().len(); - let len_scalar = ScalarMaybeUninit::Scalar(Scalar::from_u64(len as u64)); + let len_scalar = + ScalarMaybeUninit::Scalar(Scalar::from_machine_usize(len as u64, &tcx)); Immediate::ScalarPair( ScalarMaybeUninit::from_maybe_pointer((*pointee_place).ptr, &tcx), @@ -427,7 +442,10 @@ fn fill_place_recursively<'tcx>( place .offset( offset, - MemPlaceMeta::Meta(Scalar::from_u64(num_elems as u64)), + MemPlaceMeta::Meta(Scalar::from_machine_usize( + num_elems as u64, + &tcx, + )), inner_layout, &tcx, ) @@ -437,7 +455,7 @@ fn fill_place_recursively<'tcx>( }; debug!(?place_inner); - fill_place_recursively(ecx, &mut place_inner, *inner_valtree); + valtree_into_mplace(ecx, &mut place_inner, *inner_valtree); dump_place(&ecx, place_inner.into()); } diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 92eeafc5df..fb484fba9f 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -1,3 +1,4 @@ +use std::assert_matches::assert_matches; use std::convert::TryFrom; use rustc_apfloat::ieee::{Double, Single}; @@ -8,6 +9,7 @@ use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut}; use rustc_target::abi::{Integer, Variants}; +use rustc_type_ir::sty::TyKind::*; use super::{ util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy, @@ -29,6 +31,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.unsize_into(src, cast_ty, dest)?; } + PointerExposeAddress => { + let src = self.read_immediate(src)?; + let res = self.pointer_expose_address_cast(&src, cast_ty)?; + self.write_immediate(res, dest)?; + } + + PointerFromExposedAddress => { + let src = self.read_immediate(src)?; + let res = self.pointer_from_exposed_address_cast(&src, cast_ty)?; + self.write_immediate(res, dest)?; + } + Misc => { let src = self.read_immediate(src)?; let res = self.misc_cast(&src, cast_ty)?; @@ -102,7 +116,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { src: &ImmTy<'tcx, M::PointerTag>, cast_ty: Ty<'tcx>, ) -> InterpResult<'tcx, Immediate> { - use rustc_middle::ty::TyKind::*; + use rustc_type_ir::sty::TyKind::*; trace!("Casting {:?}: {:?} to {:?}", *src, src.layout.ty, cast_ty); match src.layout.ty.kind() { @@ -173,26 +187,44 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // # The remaining source values are scalar and "int-like". let scalar = src.to_scalar()?; + Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into()) + } - // If we are casting from a pointer to something - // that is not a pointer, mark the pointer as exposed - if src.layout.ty.is_any_ptr() && !cast_ty.is_any_ptr() { - let ptr = self.scalar_to_ptr(scalar)?; - - match ptr.into_pointer_or_addr() { - Ok(ptr) => { - M::expose_ptr(self, ptr)?; - } - Err(_) => { - // do nothing, exposing an invalid pointer - // has no meaning - } - }; - } + pub fn pointer_expose_address_cast( + &mut self, + src: &ImmTy<'tcx, M::PointerTag>, + cast_ty: Ty<'tcx>, + ) -> InterpResult<'tcx, Immediate> { + assert_matches!(src.layout.ty.kind(), ty::RawPtr(_) | ty::FnPtr(_)); + assert!(cast_ty.is_integral()); + let scalar = src.to_scalar()?; + let ptr = self.scalar_to_ptr(scalar)?; + match ptr.into_pointer_or_addr() { + Ok(ptr) => M::expose_ptr(self, ptr)?, + Err(_) => {} // do nothing, exposing an invalid pointer has no meaning + }; Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into()) } + pub fn pointer_from_exposed_address_cast( + &mut self, + src: &ImmTy<'tcx, M::PointerTag>, + cast_ty: Ty<'tcx>, + ) -> InterpResult<'tcx, Immediate> { + assert!(src.layout.ty.is_integral()); + assert_matches!(cast_ty.kind(), ty::RawPtr(_)); + + // First cast to usize. + let scalar = src.to_scalar()?; + let addr = self.cast_from_int_like(scalar, src.layout, self.tcx.types.usize)?; + let addr = addr.to_machine_usize(self)?; + + // Then turn address into pointer. + let ptr = M::ptr_from_addr_cast(&self, addr)?; + Ok(Scalar::from_maybe_pointer(ptr, self).into()) + } + pub fn cast_from_int_like( &self, scalar: Scalar, // input value (there is no ScalarTy so we separate data+layout) @@ -205,7 +237,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let v = scalar.to_bits(src_layout.size)?; let v = if signed { self.sign_extend(v, src_layout) } else { v }; trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty); - use rustc_middle::ty::TyKind::*; Ok(match *cast_ty.kind() { Int(_) | Uint(_) => { @@ -218,19 +249,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Scalar::from_uint(v, size) } - RawPtr(_) => { - assert!(src_layout.ty.is_integral()); - - let size = self.pointer_size(); - let addr = u64::try_from(size.truncate(v)).unwrap(); - - let ptr = M::ptr_from_addr_cast(&self, addr); - if addr == 0 { - assert!(ptr.provenance.is_none(), "null pointer can never have an AllocId"); - } - Scalar::from_maybe_pointer(ptr, self) - } - Float(FloatTy::F32) if signed => Scalar::from_f32(Single::from_i128(v as i128).value), Float(FloatTy::F64) if signed => Scalar::from_f64(Double::from_i128(v as i128).value), Float(FloatTy::F32) => Scalar::from_f32(Single::from_u128(v).value), @@ -250,7 +268,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { where F: Float + Into> + FloatConvert + FloatConvert, { - use rustc_middle::ty::TyKind::*; + use rustc_type_ir::sty::TyKind::*; match *dest_ty.kind() { // float -> uint Uint(t) => { diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index dfb81a2afc..1c1bbd370b 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::layout::{ use rustc_middle::ty::{ self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, }; -use rustc_mir_dataflow::storage::AlwaysLiveLocals; +use rustc_mir_dataflow::storage::always_live_locals; use rustc_query_system::ich::StableHashingContext; use rustc_session::Limit; use rustc_span::{Pos, Span}; @@ -105,7 +105,7 @@ pub struct Frame<'mir, 'tcx, Tag: Provenance = AllocId, Extra = ()> { /// The location where the result of the current stack frame should be written to, /// and its layout in the caller. - pub return_place: Option>, + pub return_place: PlaceTy<'tcx, Tag>, /// The list of locals for this stack frame, stored in order as /// `[return_ptr, arguments..., variables..., temporaries...]`. @@ -126,7 +126,9 @@ pub struct Frame<'mir, 'tcx, Tag: Provenance = AllocId, Extra = ()> { /// this frame (can happen e.g. during frame initialization, and during unwinding on /// frames without cleanup code). /// We basically abuse `Result` as `Either`. - pub(super) loc: Result, + /// + /// Needs to be public because ConstProp does unspeakable things to it. + pub loc: Result, } /// What we store about a frame in an interpreter backtrace. @@ -320,6 +322,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOfHelpers<'tcx> for InterpC #[inline] fn layout_tcx_at_span(&self) -> Span { + // Using the cheap root span for performance. self.tcx.span } @@ -520,13 +523,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { frame .instance .try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value) - .or_else(|e| { + .map_err(|e| { self.tcx.sess.delay_span_bug( self.cur_span(), format!("failed to normalize {}", e.get_type_for_failure()).as_str(), ); - Err(InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric)) + InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric) }) } @@ -676,7 +679,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &mut self, instance: ty::Instance<'tcx>, body: &'mir mir::Body<'tcx>, - return_place: Option<&PlaceTy<'tcx, M::PointerTag>>, + return_place: &PlaceTy<'tcx, M::PointerTag>, return_to_block: StackPopCleanup, ) -> InterpResult<'tcx> { trace!("body: {:#?}", body); @@ -685,7 +688,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { body, loc: Err(body.span), // Span used for errors caused during preamble. return_to_block, - return_place: return_place.copied(), + return_place: *return_place, // empty local array, we fill it in below, after we are inside the stack frame and // all methods actually know about the frame locals: IndexVec::new(), @@ -715,7 +718,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now mark those locals as dead that we do not want to initialize // Mark locals that use `Storage*` annotations as dead on function entry. - let always_live = AlwaysLiveLocals::new(self.body()); + let always_live = always_live_locals(self.body()); for local in locals.indices() { if !always_live.contains(local) { locals[local].value = LocalValue::Dead; @@ -807,14 +810,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); if !unwinding { - // Copy the return value to the caller's stack frame. - if let Some(ref return_place) = frame.return_place { - let op = self.access_local(&frame, mir::RETURN_PLACE, None)?; - self.copy_op_transmute(&op, return_place)?; - trace!("{:?}", self.dump_place(**return_place)); - } else { - throw_ub!(Unreachable); - } + let op = self.access_local(&frame, mir::RETURN_PLACE, None)?; + self.copy_op_transmute(&op, &frame.return_place)?; + trace!("{:?}", self.dump_place(*frame.return_place)); } let return_to_block = frame.return_to_block; @@ -928,7 +926,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env }; let param_env = param_env.with_const(); - let val = self.tcx.eval_to_allocation_raw(param_env.and(gid))?; + // Use a precise span for better cycle errors. + let val = self.tcx.at(self.cur_span()).eval_to_allocation_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) } @@ -1014,11 +1013,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug } } - write!( - fmt, - ": {:?}", - self.ecx.dump_allocs(allocs.into_iter().filter_map(|x| x).collect()) - ) + write!(fmt, ": {:?}", self.ecx.dump_allocs(allocs.into_iter().flatten().collect())) } Place::Ptr(mplace) => match mplace.ptr.provenance.and_then(Provenance::get_alloc_id) { Some(alloc_id) => write!( @@ -1055,7 +1050,7 @@ where body.hash_stable(hcx, hasher); instance.hash_stable(hcx, hasher); return_to_block.hash_stable(hcx, hasher); - return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher); + return_place.hash_stable(hcx, hasher); locals.hash_stable(hcx, hasher); loc.hash_stable(hcx, hasher); extra.hash_stable(hcx, hasher); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 59ea40dc2f..e51c51cf45 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; -use rustc_target::abi::{Abi, Align, Primitive, Size}; +use rustc_target::abi::{Abi, Align, InitKind, Primitive, Size}; use super::{ util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy, @@ -44,7 +44,7 @@ fn numeric_intrinsic(name: Symbol, bits: u128, kind: Primitive) -> Scalar( +pub(crate) fn eval_nullary_intrinsic<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, def_id: DefId, @@ -115,13 +115,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &mut self, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, M::PointerTag>], - ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>, + dest: &PlaceTy<'tcx, M::PointerTag>, + ret: Option, ) -> InterpResult<'tcx, bool> { let substs = instance.substs; let intrinsic_name = self.tcx.item_name(instance.def_id()); // First handle intrinsics without return place. - let (dest, ret) = match ret { + let ret = match ret { None => match intrinsic_name { sym::transmute => throw_ub_format!("transmuting to uninhabited type"), sym::abort => M::abort(self, "the program aborted execution".to_owned())?, @@ -168,7 +169,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::needs_drop => self.tcx.types.bool, sym::type_id => self.tcx.types.u64, sym::type_name => self.tcx.mk_static_str(), - _ => bug!("already checked for nullary intrinsics"), + _ => bug!(), }; let val = self.tcx.const_eval_global_id(self.param_env, gid, Some(self.tcx.span))?; @@ -214,7 +215,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::add_with_overflow => BinOp::Add, sym::sub_with_overflow => BinOp::Sub, sym::mul_with_overflow => BinOp::Mul, - _ => bug!("Already checked for int ops"), + _ => bug!(), }; self.binop_with_overflow(bin_op, &lhs, &rhs, dest)?; } @@ -250,7 +251,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::unchecked_mul => BinOp::Mul, sym::unchecked_div => BinOp::Div, sym::unchecked_rem => BinOp::Rem, - _ => bug!("Already checked for int ops"), + _ => bug!(), }; let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, &l, &r)?; if overflowed { @@ -312,78 +313,82 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let a = self.read_pointer(&args[0])?; let b = self.read_pointer(&args[1])?; - // Special case: if both scalars are *equal integers* - // and not null, we pretend there is an allocation of size 0 right there, - // and their offset is 0. (There's never a valid object at null, making it an - // exception from the exception.) - // This is the dual to the special exception for offset-by-0 - // in the inbounds pointer offset operation (see `ptr_offset_inbounds` below). - match (self.ptr_try_get_alloc_id(a), self.ptr_try_get_alloc_id(b)) { - (Err(a), Err(b)) if a == b && a != 0 => { - // Both are the same non-null integer. - self.write_scalar(Scalar::from_machine_isize(0, self), dest)?; - } - (Err(offset), _) | (_, Err(offset)) => { - throw_ub!(DanglingIntPointer(offset, CheckInAllocMsg::OffsetFromTest)); - } - (Ok((a_alloc_id, a_offset, _)), Ok((b_alloc_id, b_offset, _))) => { - // Both are pointers. They must be into the same allocation. - if a_alloc_id != b_alloc_id { - throw_ub_format!( - "{} cannot compute offset of pointers into different allocations.", - intrinsic_name, - ); + let usize_layout = self.layout_of(self.tcx.types.usize)?; + let isize_layout = self.layout_of(self.tcx.types.isize)?; + + // Get offsets for both that are at least relative to the same base. + let (a_offset, b_offset) = + match (self.ptr_try_get_alloc_id(a), self.ptr_try_get_alloc_id(b)) { + (Err(a), Err(b)) => { + // Neither poiner points to an allocation. + // If these are inequal or null, this *will* fail the deref check below. + (a, b) } - // And they must both be valid for zero-sized accesses ("in-bounds or one past the end"). - self.check_ptr_access_align( - a, - Size::ZERO, - Align::ONE, - CheckInAllocMsg::OffsetFromTest, - )?; - self.check_ptr_access_align( - b, - Size::ZERO, - Align::ONE, - CheckInAllocMsg::OffsetFromTest, - )?; - - if intrinsic_name == sym::ptr_offset_from_unsigned && a_offset < b_offset { + (Err(_), _) | (_, Err(_)) => { + // We managed to find a valid allocation for one pointer, but not the other. + // That means they are definitely not pointing to the same allocation. throw_ub_format!( - "{} cannot compute a negative offset, but {} < {}", - intrinsic_name, - a_offset.bytes(), - b_offset.bytes(), + "{} called on pointers into different allocations", + intrinsic_name ); } - - // Compute offset. - let usize_layout = self.layout_of(self.tcx.types.usize)?; - let isize_layout = self.layout_of(self.tcx.types.isize)?; - let ret_layout = if intrinsic_name == sym::ptr_offset_from { - isize_layout - } else { - usize_layout - }; - - // The subtraction is always done in `isize` to enforce - // the "no more than `isize::MAX` apart" requirement. - let a_offset = ImmTy::from_uint(a_offset.bytes(), isize_layout); - let b_offset = ImmTy::from_uint(b_offset.bytes(), isize_layout); - let (val, overflowed, _ty) = - self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?; - if overflowed { - throw_ub_format!("Pointers were too far apart for {}", intrinsic_name); + (Ok((a_alloc_id, a_offset, _)), Ok((b_alloc_id, b_offset, _))) => { + // Found allocation for both. They must be into the same allocation. + if a_alloc_id != b_alloc_id { + throw_ub_format!( + "{} called on pointers into different allocations", + intrinsic_name + ); + } + // Use these offsets for distance calculation. + (a_offset.bytes(), b_offset.bytes()) } - - let pointee_layout = self.layout_of(substs.type_at(0))?; - // This re-interprets an isize at ret_layout, but we already checked - // that if ret_layout is usize, then the result must be non-negative. - let val = ImmTy::from_scalar(val, ret_layout); - let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout); - self.exact_div(&val, &size, dest)?; + }; + + // Compute distance. + let distance = { + // The subtraction is always done in `isize` to enforce + // the "no more than `isize::MAX` apart" requirement. + let a_offset = ImmTy::from_uint(a_offset, isize_layout); + let b_offset = ImmTy::from_uint(b_offset, isize_layout); + let (val, overflowed, _ty) = + self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?; + if overflowed { + throw_ub_format!("pointers were too far apart for {}", intrinsic_name); } + val.to_machine_isize(self)? + }; + + // Check that the range between them is dereferenceable ("in-bounds or one past the + // end of the same allocation"). This is like the check in ptr_offset_inbounds. + let min_ptr = if distance >= 0 { b } else { a }; + self.check_ptr_access_align( + min_ptr, + Size::from_bytes(distance.unsigned_abs()), + Align::ONE, + CheckInAllocMsg::OffsetFromTest, + )?; + + if intrinsic_name == sym::ptr_offset_from_unsigned && distance < 0 { + throw_ub_format!( + "{} called when first pointer has smaller offset than second: {} < {}", + intrinsic_name, + a_offset, + b_offset, + ); } + + // Perform division by size to compute return value. + let ret_layout = if intrinsic_name == sym::ptr_offset_from_unsigned { + usize_layout + } else { + isize_layout + }; + let pointee_layout = self.layout_of(substs.type_at(0))?; + // If ret_layout is unsigned, we checked that so is the distance, so we are good. + let val = ImmTy::from_int(distance, ret_layout); + let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout); + self.exact_div(&val, &size, dest)?; } sym::transmute => { @@ -407,7 +412,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { )?; } if intrinsic_name == sym::assert_zero_valid - && !layout.might_permit_raw_init(self, /*zero:*/ true) + && !layout.might_permit_raw_init( + self, + InitKind::Zero, + self.tcx.sess.opts.debugging_opts.strict_init_checks, + ) { M::abort( self, @@ -418,7 +427,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { )?; } if intrinsic_name == sym::assert_uninit_valid - && !layout.might_permit_raw_init(self, /*zero:*/ false) + && !layout.might_permit_raw_init( + self, + InitKind::Uninit, + self.tcx.sess.opts.debugging_opts.strict_init_checks, + ) { M::abort( self, @@ -566,11 +579,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // memory between these pointers must be accessible. Note that we do not require the // pointers to be properly aligned (unlike a read/write operation). let min_ptr = if offset_bytes >= 0 { ptr } else { offset_ptr }; - let size = offset_bytes.unsigned_abs(); // This call handles checking for integer/null pointers. self.check_ptr_access_align( min_ptr, - Size::from_bytes(size), + Size::from_bytes(offset_bytes.unsigned_abs()), Align::ONE, CheckInAllocMsg::PointerArithmeticTest, )?; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 5ece19d7fb..23ae2db643 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -15,7 +15,7 @@ use crate::interpret::{ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a /// frame which is not `#[track_caller]`. - crate fn find_closest_untracked_caller_location(&self) -> Span { + pub(crate) fn find_closest_untracked_caller_location(&self) -> Span { for frame in self.stack().iter().rev() { debug!("find_closest_untracked_caller_location: checking frame {:?}", frame.instance); @@ -70,11 +70,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - bug!("no non-`#[track_caller]` frame found") + span_bug!(self.cur_span(), "no non-`#[track_caller]` frame found") } /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers. - crate fn alloc_caller_location( + pub(crate) fn alloc_caller_location( &mut self, filename: Symbol, line: u32, @@ -113,7 +113,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { location } - crate fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) { + pub(crate) fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) { let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo()); ( diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs index 447797f915..f9847742f0 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs @@ -189,7 +189,7 @@ impl Write for AbsolutePathPrinter<'_> { } /// Directly returns an `Allocation` containing an absolute path representation of the given type. -crate fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> { +pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> { let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes()); tcx.intern_const_alloc(alloc) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index a79751ccb5..080cabe033 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -133,9 +133,11 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Whether to enforce the validity invariant fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; - /// Whether to enforce validity (e.g., initialization and not having ptr provenance) - /// of integers and floats. - fn enforce_number_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; + /// Whether to enforce integers and floats being initialized. + fn enforce_number_init(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; + + /// Whether to enforce integers and floats not having provenance. + fn enforce_number_no_provenance(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; /// Whether function calls should be [ABI](Abi)-checked. fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { @@ -167,7 +169,8 @@ pub trait Machine<'mir, 'tcx>: Sized { instance: ty::Instance<'tcx>, abi: Abi, args: &[OpTy<'tcx, Self::PointerTag>], - ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, + destination: &PlaceTy<'tcx, Self::PointerTag>, + target: Option, unwind: StackPopUnwind, ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>>; @@ -178,7 +181,8 @@ pub trait Machine<'mir, 'tcx>: Sized { fn_val: Self::ExtraFnVal, abi: Abi, args: &[OpTy<'tcx, Self::PointerTag>], - ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, + destination: &PlaceTy<'tcx, Self::PointerTag>, + target: Option, unwind: StackPopUnwind, ) -> InterpResult<'tcx>; @@ -188,7 +192,8 @@ pub trait Machine<'mir, 'tcx>: Sized { ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Self::PointerTag>], - ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, + destination: &PlaceTy<'tcx, Self::PointerTag>, + target: Option, unwind: StackPopUnwind, ) -> InterpResult<'tcx>; @@ -289,11 +294,10 @@ pub trait Machine<'mir, 'tcx>: Sized { fn ptr_from_addr_cast( ecx: &InterpCx<'mir, 'tcx, Self>, addr: u64, - ) -> Pointer>; + ) -> InterpResult<'tcx, Pointer>>; - // FIXME: Transmuting an integer to a pointer should just always return a `None` - // provenance, but that causes problems with function pointers in Miri. /// Hook for returning a pointer from a transmute-like operation on an addr. + /// This is only needed to support Miri's (unsound) "allow-ptr-int-transmute" flag. fn ptr_from_addr_transmute( ecx: &InterpCx<'mir, 'tcx, Self>, addr: u64, @@ -330,12 +334,14 @@ pub trait Machine<'mir, 'tcx>: Sized { /// allocation (because a copy had to be done to add tags or metadata), machine memory will /// cache the result. (This relies on `AllocMap::get_or` being able to add the /// owned allocation to the map even when the map is shared.) + /// + /// This must only fail if `alloc` contains relocations. fn init_allocation_extra<'b>( ecx: &InterpCx<'mir, 'tcx, Self>, id: AllocId, alloc: Cow<'b, Allocation>, kind: Option>, - ) -> Cow<'b, Allocation>; + ) -> InterpResult<'tcx, Cow<'b, Allocation>>; /// Hook for performing extra checks on a memory read access. /// @@ -453,17 +459,23 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { } #[inline(always)] - fn enforce_number_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool { + fn enforce_number_init(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool { true } + #[inline(always)] + fn enforce_number_no_provenance(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool { + false + } + #[inline(always)] fn call_extra_fn( _ecx: &mut InterpCx<$mir, $tcx, Self>, fn_val: !, _abi: Abi, _args: &[OpTy<$tcx>], - _ret: Option<(&PlaceTy<$tcx>, mir::BasicBlock)>, + _destination: &PlaceTy<$tcx, Self::PointerTag>, + _target: Option, _unwind: StackPopUnwind, ) -> InterpResult<$tcx> { match fn_val {} @@ -475,9 +487,9 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { _id: AllocId, alloc: Cow<'b, Allocation>, _kind: Option>, - ) -> Cow<'b, Allocation> { + ) -> InterpResult<$tcx, Cow<'b, Allocation>> { // We do not use a tag so we can just cheaply forward the allocation - alloc + Ok(alloc) } fn extern_static_base_pointer( @@ -508,8 +520,10 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { fn ptr_from_addr_cast( _ecx: &InterpCx<$mir, $tcx, Self>, addr: u64, - ) -> Pointer> { - Pointer::new(None, Size::from_bytes(addr)) + ) -> InterpResult<$tcx, Pointer>> { + // Allow these casts, but make the pointer not dereferenceable. + // (I.e., they behave like transmutation.) + Ok(Pointer::new(None, Size::from_bytes(addr))) } #[inline(always)] diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 33162a01ed..d46f2f38d3 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -197,9 +197,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { size: Size, align: Align, kind: MemoryKind, - ) -> InterpResult<'static, Pointer> { + ) -> InterpResult<'tcx, Pointer> { let alloc = Allocation::uninit(size, align, M::PANIC_ON_ALLOC_FAIL)?; - Ok(self.allocate_raw_ptr(alloc, kind)) + // We can `unwrap` since `alloc` contains no pointers. + Ok(self.allocate_raw_ptr(alloc, kind).unwrap()) } pub fn allocate_bytes_ptr( @@ -210,23 +211,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { mutability: Mutability, ) -> Pointer { let alloc = Allocation::from_bytes(bytes, align, mutability); - self.allocate_raw_ptr(alloc, kind) + // We can `unwrap` since `alloc` contains no pointers. + self.allocate_raw_ptr(alloc, kind).unwrap() } + /// This can fail only of `alloc` contains relocations. pub fn allocate_raw_ptr( &mut self, alloc: Allocation, kind: MemoryKind, - ) -> Pointer { + ) -> InterpResult<'tcx, Pointer> { let id = self.tcx.reserve_alloc_id(); debug_assert_ne!( Some(kind), M::GLOBAL_KIND.map(MemoryKind::Machine), "dynamically allocating global memory" ); - let alloc = M::init_allocation_extra(self, id, Cow::Owned(alloc), Some(kind)); + let alloc = M::init_allocation_extra(self, id, Cow::Owned(alloc), Some(kind))?; self.memory.alloc_map.insert(id, (kind, alloc.into_owned())); - M::tag_alloc_base_pointer(self, Pointer::from(id)) + Ok(M::tag_alloc_base_pointer(self, Pointer::from(id))) } pub fn reallocate_ptr( @@ -402,7 +405,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { msg: CheckInAllocMsg, alloc_size: impl FnOnce(AllocId, Size, M::TagExtra) -> InterpResult<'tcx, (Size, Align, T)>, ) -> InterpResult<'tcx, Option> { - fn check_offset_align(offset: u64, align: Align) -> InterpResult<'static> { + fn check_offset_align<'tcx>(offset: u64, align: Align) -> InterpResult<'tcx> { if offset % align.bytes() == 0 { Ok(()) } else { @@ -441,6 +444,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { msg, }) } + // Ensure we never consider the null pointer dereferencable. + if M::PointerTag::OFFSET_IS_ADDR { + assert_ne!(ptr.addr(), Size::ZERO); + } // Test align. Check this last; if both bounds and alignment are violated // we want the error to be about the bounds. if let Some(align) = align { @@ -500,18 +507,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_unsup!(ReadExternStatic(def_id)); } - (self.tcx.eval_static_initializer(def_id)?, Some(def_id)) + // Use a precise span for better cycle errors. + (self.tcx.at(self.cur_span()).eval_static_initializer(def_id)?, Some(def_id)) } }; M::before_access_global(*self.tcx, &self.machine, id, alloc, def_id, is_write)?; // We got tcx memory. Let the machine initialize its "extra" stuff. - let alloc = M::init_allocation_extra( + M::init_allocation_extra( self, id, // always use the ID we got as input, not the "hidden" one. Cow::Borrowed(alloc.inner()), M::GLOBAL_KIND.map(MemoryKind::Machine), - ); - Ok(alloc) + ) } /// Gives raw access to the `Allocation`, without bounds or alignment checks. @@ -654,7 +661,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, id: AllocId, liveness: AllocCheck, - ) -> InterpResult<'static, (Size, Align)> { + ) -> InterpResult<'tcx, (Size, Align)> { // # Regular allocations // Don't use `self.get_raw` here as that will // a) cause cycles in case `id` refers to a static @@ -904,11 +911,15 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRefMut<'a, 'tcx, Tag, Extra> { } impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> { - pub fn read_scalar(&self, range: AllocRange) -> InterpResult<'tcx, ScalarMaybeUninit> { + pub fn read_scalar( + &self, + range: AllocRange, + read_provenance: bool, + ) -> InterpResult<'tcx, ScalarMaybeUninit> { let range = self.range.subrange(range); let res = self .alloc - .read_scalar(&self.tcx, range) + .read_scalar(&self.tcx, range, read_provenance) .map_err(|e| e.to_interp_error(self.alloc_id))?; debug!( "read_scalar in {} at {:#x}, size {}: {:?}", @@ -920,14 +931,30 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> { Ok(res) } - pub fn read_ptr_sized(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit> { - self.read_scalar(alloc_range(offset, self.tcx.data_layout().pointer_size)) + pub fn read_integer( + &self, + offset: Size, + size: Size, + ) -> InterpResult<'tcx, ScalarMaybeUninit> { + self.read_scalar(alloc_range(offset, size), /*read_provenance*/ false) + } + + pub fn read_pointer(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit> { + self.read_scalar( + alloc_range(offset, self.tcx.data_layout().pointer_size), + /*read_provenance*/ true, + ) } - pub fn check_bytes(&self, range: AllocRange, allow_uninit_and_ptr: bool) -> InterpResult<'tcx> { + pub fn check_bytes( + &self, + range: AllocRange, + allow_uninit: bool, + allow_ptr: bool, + ) -> InterpResult<'tcx> { Ok(self .alloc - .check_bytes(&self.tcx, self.range.subrange(range), allow_uninit_and_ptr) + .check_bytes(&self.tcx, self.range.subrange(range), allow_uninit, allow_ptr) .map_err(|e| e.to_interp_error(self.alloc_id))?) } } @@ -1144,11 +1171,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Err(ptr) => ptr.into(), Ok(bits) => { let addr = u64::try_from(bits).unwrap(); - let ptr = M::ptr_from_addr_transmute(&self, addr); - if addr == 0 { - assert!(ptr.provenance.is_none(), "null pointer can never have an AllocId"); - } - ptr + M::ptr_from_addr_transmute(&self, addr) } }, ) diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 69d6c8470a..2b73ad568e 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -29,5 +29,5 @@ pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy}; pub use self::validity::{CtfeValidationMode, RefTracking}; pub use self::visitor::{MutValueVisitor, Value, ValueVisitor}; -crate use self::intrinsics::eval_nullary_intrinsic; +pub(crate) use self::intrinsics::eval_nullary_intrinsic; use eval_context::{from_known_layout, mir_assign_valid_types}; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 5c85c86107..6b05a49575 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -15,8 +15,8 @@ use rustc_target::abi::{VariantIdx, Variants}; use super::{ alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, GlobalId, - InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, Place, PlaceTy, Pointer, Provenance, - Scalar, ScalarMaybeUninit, + InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, Place, PlaceTy, Pointer, + PointerArithmetic, Provenance, Scalar, ScalarMaybeUninit, }; /// An `Immediate` represents a single immediate self-contained Rust value. @@ -284,11 +284,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Abi::Scalar(s) if force => Some(s.primitive()), _ => None, }; - if let Some(_s) = scalar_layout { + let read_provenance = |s: abi::Primitive, size| { + // Should be just `s.is_ptr()`, but we support a Miri flag that accepts more + // questionable ptr-int transmutes. + let number_may_have_provenance = !M::enforce_number_no_provenance(self); + s.is_ptr() || (number_may_have_provenance && size == self.pointer_size()) + }; + if let Some(s) = scalar_layout { //FIXME(#96185): let size = s.size(self); //FIXME(#96185): assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size"); let size = mplace.layout.size; //FIXME(#96185): remove this line - let scalar = alloc.read_scalar(alloc_range(Size::ZERO, size))?; + let scalar = + alloc.read_scalar(alloc_range(Size::ZERO, size), read_provenance(s, size))?; return Ok(Some(ImmTy { imm: scalar.into(), layout: mplace.layout })); } let scalar_pair_layout = match mplace.layout.abi { @@ -306,8 +313,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let (a_size, b_size) = (a.size(self), b.size(self)); let b_offset = a_size.align_to(b.align(self).abi); assert!(b_offset.bytes() > 0); // in `operand_field` we use the offset to tell apart the fields - let a_val = alloc.read_scalar(alloc_range(Size::ZERO, a_size))?; - let b_val = alloc.read_scalar(alloc_range(b_offset, b_size))?; + let a_val = + alloc.read_scalar(alloc_range(Size::ZERO, a_size), read_provenance(a, a_size))?; + let b_val = + alloc.read_scalar(alloc_range(b_offset, b_size), read_provenance(b, b_size))?; return Ok(Some(ImmTy { imm: Immediate::ScalarPair(a_val, b_val), layout: mplace.layout, @@ -613,10 +622,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// "universe" (param_env). pub fn const_to_op( &self, - val: ty::Const<'tcx>, + c: ty::Const<'tcx>, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { - match val.val() { + match c.kind() { ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric), ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => { throw_inval!(AlreadyReported(reported)) @@ -626,9 +635,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) } ty::ConstKind::Infer(..) | ty::ConstKind::Placeholder(..) => { - span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", val) + span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c) + } + ty::ConstKind::Value(valtree) => { + let ty = c.ty(); + let const_val = self.tcx.valtree_to_const_val((ty, valtree)); + self.const_val_to_op(const_val, ty, layout) } - ty::ConstKind::Value(val_val) => self.const_val_to_op(val_val, val.ty(), layout), } } @@ -643,7 +656,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - crate fn const_val_to_op( + pub(crate) fn const_val_to_op( &self, val_val: ConstValue<'tcx>, ty: Ty<'tcx>, diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 6dae9dc72b..85ee88e9e4 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -154,14 +154,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let result = match bin_op { Shl => l.checked_shl(r).unwrap(), Shr => l.checked_shr(r).unwrap(), - _ => bug!("it has already been checked that this is a shift op"), + _ => bug!(), }; result as u128 } else { match bin_op { Shl => l.checked_shl(r).unwrap(), Shr => l.checked_shr(r).unwrap(), - _ => bug!("it has already been checked that this is a shift op"), + _ => bug!(), } }; let truncated = self.truncate(result, left_layout); diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 95d6f43139..3dbcba72ba 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -115,12 +115,6 @@ impl<'tcx, Tag: Provenance> std::ops::Deref for MPlaceTy<'tcx, Tag> { } } -impl<'tcx, Tag: Provenance> std::ops::DerefMut for MPlaceTy<'tcx, Tag> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.mplace - } -} - impl<'tcx, Tag: Provenance> From> for PlaceTy<'tcx, Tag> { #[inline(always)] fn from(mplace: MPlaceTy<'tcx, Tag>) -> Self { @@ -196,6 +190,18 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> { MPlaceTy { mplace: MemPlace::from_ptr(ptr, layout.align.abi), layout } } + #[inline] + pub fn from_aligned_ptr_with_meta( + ptr: Pointer>, + layout: TyAndLayout<'tcx>, + meta: MemPlaceMeta, + ) -> Self { + let mut mplace = MemPlace::from_ptr(ptr, layout.align.abi); + mplace.meta = meta; + + MPlaceTy { mplace, layout } + } + #[inline] pub(crate) fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { if self.layout.is_unsized() { @@ -307,6 +313,11 @@ where ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { let val = self.read_immediate(src)?; trace!("deref to {} on {:?}", val.layout.ty, *val); + + if val.layout.ty.is_box() { + bug!("dereferencing {:?}", val.layout.ty); + } + let mplace = self.ref_to_mplace(&val)?; self.check_mplace_access(mplace, CheckInAllocMsg::DerefTest)?; Ok(mplace) @@ -495,7 +506,7 @@ where /// Project into an mplace #[instrument(skip(self), level = "debug")] - pub(crate) fn mplace_projection( + pub(super) fn mplace_projection( &self, base: &MPlaceTy<'tcx, M::PointerTag>, proj_elem: mir::PlaceElem<'tcx>, @@ -863,8 +874,6 @@ where Ok(src_val) => { assert!(!src.layout.is_unsized(), "cannot have unsized immediates"); // Yay, we got a value that we can write directly. - // FIXME: Add a check to make sure that if `src` is indirect, - // it does not overlap with `dest`. return self.write_immediate_no_validate(*src_val, dest); } Err(mplace) => mplace, @@ -884,7 +893,7 @@ where }); assert_eq!(src.meta, dest.meta, "Can only copy between equally-sized instances"); - self.mem_copy(src.ptr, src.align, dest.ptr, dest.align, size, /*nonoverlapping*/ true) + self.mem_copy(src.ptr, src.align, dest.ptr, dest.align, size, /*nonoverlapping*/ false) } /// Copies the data from an operand to a place. The layouts may disagree, but they must @@ -900,16 +909,12 @@ where } // We still require the sizes to match. if src.layout.size != dest.layout.size { - // FIXME: This should be an assert instead of an error, but if we transmute within an - // array length computation, `typeck` may not have yet been run and errored out. In fact - // most likely we *are* running `typeck` right now. Investigate whether we can bail out - // on `typeck_results().has_errors` at all const eval entry points. - debug!("Size mismatch when transmuting!\nsrc: {:#?}\ndest: {:#?}", src, dest); - self.tcx.sess.delay_span_bug( + span_bug!( self.cur_span(), - "size-changing transmute, should have been caught by transmute checking", + "size-changing transmute, should have been caught by transmute checking: {:#?}\ndest: {:#?}", + src, + dest ); - throw_inval!(TransmuteSizeDiff(src.layout.ty, dest.layout.ty)); } // Unsized copies rely on interpreting `src.meta` with `dest.layout`, we want // to avoid that here. @@ -1005,7 +1010,7 @@ where &mut self, layout: TyAndLayout<'tcx>, kind: MemoryKind, - ) -> InterpResult<'static, MPlaceTy<'tcx, M::PointerTag>> { + ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { let ptr = self.allocate_ptr(layout.size, layout.align.abi, kind)?; Ok(MPlaceTy::from_aligned_ptr(ptr.into(), layout)) } diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index e6dfdf54a3..98f69456e4 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -55,33 +55,32 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let basic_block = &self.body().basic_blocks()[loc.block]; - let old_frames = self.frame_idx(); - if let Some(stmt) = basic_block.statements.get(loc.statement_index) { - assert_eq!(old_frames, self.frame_idx()); + let old_frames = self.frame_idx(); self.statement(stmt)?; + // 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; return Ok(true); } M::before_terminator(self)?; let terminator = basic_block.terminator(); - assert_eq!(old_frames, self.frame_idx()); self.terminator(terminator)?; Ok(true) } /// Runs the interpretation logic for the given `mir::Statement` at the current frame and - /// statement counter. This also moves the statement counter forward. + /// statement counter. + /// + /// This does NOT move the statement counter forward, the caller has to do that! pub fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> InterpResult<'tcx> { info!("{:?}", stmt); use rustc_middle::mir::StatementKind::*; - // Some statements (e.g., box) push new stack frames. - // We have to record the stack frame number *before* executing the statement. - let frame_idx = self.frame_idx(); - match &stmt.kind { Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?, @@ -144,7 +143,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Nop => {} } - self.stack_mut()[frame_idx].loc.as_mut().unwrap().statement_index += 1; Ok(()) } @@ -158,6 +156,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { place: mir::Place<'tcx>, ) -> InterpResult<'tcx> { let dest = self.eval_place(place)?; + // FIXME: ensure some kind of non-aliasing between LHS and RHS? + // Also see https://github.com/rust-lang/rust/issues/68364. use rustc_middle::mir::Rvalue::*; match *rvalue { @@ -298,6 +298,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(()) } + /// Evaluate the given terminator. Will also adjust the stack frame and statement position accordingly. fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> InterpResult<'tcx> { info!("{:?}", terminator.kind); diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index c2664565f1..57d06b48ca 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -57,7 +57,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.go_to_block(target_block); } - Call { ref func, ref args, destination, ref cleanup, from_hir_call: _, fn_span: _ } => { + Call { + ref func, + ref args, + destination, + target, + ref cleanup, + from_hir_call: _, + fn_span: _, + } => { let old_stack = self.frame_idx(); let old_loc = self.frame().loc; let func = self.eval_operand(func, None)?; @@ -91,20 +99,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ), }; - let dest_place; - let ret = match destination { - Some((dest, ret)) => { - dest_place = self.eval_place(dest)?; - Some((&dest_place, ret)) - } - None => None, - }; + let destination = self.eval_place(destination)?; self.eval_fn_call( fn_val, (fn_sig.abi, fn_abi), &args, with_caller_location, - ret, + &destination, + target, match (cleanup, fn_abi.can_unwind) { (Some(cleanup), true) => StackPopUnwind::Cleanup(*cleanup), (None, true) => StackPopUnwind::Skip, @@ -183,7 +185,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // No question return true; } - // Compare layout + if caller_abi.layout.size != callee_abi.layout.size + || caller_abi.layout.align.abi != callee_abi.layout.align.abi + { + // This cannot go well... + // FIXME: What about unsized types? + return false; + } + // The rest *should* be okay, but we are extra conservative. match (caller_abi.layout.abi, callee_abi.layout.abi) { // Different valid ranges are okay (once we enforce validity, // that will take care to make it UB to leave the range, just @@ -299,7 +308,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (caller_abi, caller_fn_abi): (Abi, &FnAbi<'tcx, Ty<'tcx>>), args: &[OpTy<'tcx, M::PointerTag>], with_caller_location: bool, - ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>, + destination: &PlaceTy<'tcx, M::PointerTag>, + target: Option, mut unwind: StackPopUnwind, ) -> InterpResult<'tcx> { trace!("eval_fn_call: {:#?}", fn_val); @@ -307,15 +317,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let instance = match fn_val { FnVal::Instance(instance) => instance, FnVal::Other(extra) => { - return M::call_extra_fn(self, extra, caller_abi, args, ret, unwind); + return M::call_extra_fn( + self, + extra, + caller_abi, + args, + destination, + target, + unwind, + ); } }; match instance.def { - ty::InstanceDef::Intrinsic(..) => { - assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic); + ty::InstanceDef::Intrinsic(def_id) => { + assert!(self.tcx.is_intrinsic(def_id)); // caller_fn_abi is not relevant here, we interpret the arguments directly for each intrinsic. - M::call_intrinsic(self, instance, args, ret, unwind) + M::call_intrinsic(self, instance, args, destination, target, unwind) } ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) @@ -326,7 +344,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::InstanceDef::Item(_) => { // We need MIR for this fn let Some((body, instance)) = - M::find_mir_or_eval_fn(self, instance, caller_abi, args, ret, unwind)? else { + M::find_mir_or_eval_fn(self, instance, caller_abi, args, destination, target, unwind)? else { return Ok(()); }; @@ -335,12 +353,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME: for variadic support, do we have to somehow determine callee's extra_args? let callee_fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?; - if callee_fn_abi.c_variadic != caller_fn_abi.c_variadic { - throw_ub_format!( - "calling a c-variadic function via a non-variadic call site, or vice versa" - ); - } - if callee_fn_abi.c_variadic { + if callee_fn_abi.c_variadic || caller_fn_abi.c_variadic { throw_unsup_format!("calling a c-variadic function is not supported"); } @@ -362,8 +375,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.push_stack_frame( instance, body, - ret.map(|p| p.0), - StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind }, + destination, + StackPopCleanup::Goto { ret: target, unwind }, )?; // If an error is raised here, pop the frame again to get an accurate backtrace. @@ -540,7 +553,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (caller_abi, caller_fn_abi), &args, with_caller_location, - ret, + destination, + target, unwind, ) } @@ -582,7 +596,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (Abi::Rust, fn_abi), &[arg.into()], false, - Some((&dest.into(), target)), + &dest.into(), + Some(target), match unwind { Some(cleanup) => StackPopUnwind::Cleanup(cleanup), None => StackPopUnwind::Skip, diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 235938422a..9c48f3e833 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -2,8 +2,8 @@ use std::convert::TryFrom; use rustc_middle::mir::interpret::{InterpResult, Pointer, PointerArithmetic}; use rustc_middle::ty::{ - self, Ty, COMMON_VTABLE_ENTRIES, COMMON_VTABLE_ENTRIES_ALIGN, - COMMON_VTABLE_ENTRIES_DROPINPLACE, COMMON_VTABLE_ENTRIES_SIZE, + self, Ty, TyCtxt, COMMON_VTABLE_ENTRIES_ALIGN, COMMON_VTABLE_ENTRIES_DROPINPLACE, + COMMON_VTABLE_ENTRIES_SIZE, }; use rustc_target::abi::{Align, Size}; @@ -38,7 +38,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } /// Resolves the function at the specified slot in the provided - /// vtable. Currently an index of '3' (`COMMON_VTABLE_ENTRIES.len()`) + /// vtable. Currently an index of '3' (`TyCtxt::COMMON_VTABLE_ENTRIES.len()`) /// corresponds to the first method declared in the trait of the provided vtable. pub fn get_vtable_slot( &self, @@ -50,7 +50,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let vtable_slot = self .get_ptr_alloc(vtable_slot, ptr_size, self.tcx.data_layout.pointer_align.abi)? .expect("cannot be a ZST"); - let fn_ptr = self.scalar_to_ptr(vtable_slot.read_ptr_sized(Size::ZERO)?.check_init()?)?; + let fn_ptr = self.scalar_to_ptr(vtable_slot.read_pointer(Size::ZERO)?.check_init()?)?; self.get_ptr_fn(fn_ptr) } @@ -64,14 +64,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let vtable = self .get_ptr_alloc( vtable, - pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES.len()).unwrap(), + pointer_size * u64::try_from(TyCtxt::COMMON_VTABLE_ENTRIES.len()).unwrap(), self.tcx.data_layout.pointer_align.abi, )? .expect("cannot be a ZST"); let drop_fn = vtable - .read_ptr_sized( - pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_DROPINPLACE).unwrap(), - )? + .read_pointer(pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_DROPINPLACE).unwrap())? .check_init()?; // We *need* an instance here, no other kind of function value, to be able // to determine the type. @@ -99,17 +97,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let vtable = self .get_ptr_alloc( vtable, - pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES.len()).unwrap(), + pointer_size * u64::try_from(TyCtxt::COMMON_VTABLE_ENTRIES.len()).unwrap(), self.tcx.data_layout.pointer_align.abi, )? .expect("cannot be a ZST"); let size = vtable - .read_ptr_sized(pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_SIZE).unwrap())? + .read_integer( + pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_SIZE).unwrap(), + pointer_size, + )? .check_init()?; let size = size.to_machine_usize(self)?; let size = Size::from_bytes(size); let align = vtable - .read_ptr_sized(pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_ALIGN).unwrap())? + .read_integer( + pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_ALIGN).unwrap(), + pointer_size, + )? .check_init()?; let align = align.to_machine_usize(self)?; let align = Align::from_bytes(align).map_err(|e| err_ub!(InvalidVtableAlignment(e)))?; @@ -132,8 +136,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .get_ptr_alloc(vtable_slot, pointer_size, self.tcx.data_layout.pointer_align.abi)? .expect("cannot be a ZST"); - let new_vtable = - self.scalar_to_ptr(new_vtable.read_ptr_sized(Size::ZERO)?.check_init()?)?; + let new_vtable = self.scalar_to_ptr(new_vtable.read_pointer(Size::ZERO)?.check_init()?)?; Ok(new_vtable) } diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index e17bd9a8c0..b9866995e9 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,5 +1,5 @@ use rustc_middle::mir::interpret::InterpResult; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor}; use std::convert::TryInto; use std::ops::ControlFlow; @@ -8,7 +8,7 @@ use std::ops::ControlFlow; /// In case it does, returns a `TooGeneric` const eval error. Note that due to polymorphization /// types may be "concrete enough" even though they still contain generic parameters in /// case these parameters are unused. -crate fn ensure_monomorphic_enough<'tcx, T>(tcx: TyCtxt<'tcx>, ty: T) -> InterpResult<'tcx> +pub(crate) fn ensure_monomorphic_enough<'tcx, T>(tcx: TyCtxt<'tcx>, ty: T) -> InterpResult<'tcx> where T: TypeFoldable<'tcx>, { @@ -47,7 +47,7 @@ where match (is_used, subst.needs_subst()) { // Just in case there are closures or generators within this subst, // recurse. - (true, true) => return subst.super_visit_with(self), + (true, true) => return subst.visit_with(self), // Confirm that polymorphization replaced the parameter with // `ty::Param`/`ty::ConstKind::Param`. (false, true) if cfg!(debug_assertions) => match subst.unpack() { @@ -55,7 +55,7 @@ where assert!(matches!(ty.kind(), ty::Param(_))) } ty::subst::GenericArgKind::Const(ct) => { - assert!(matches!(ct.val(), ty::ConstKind::Param(_))) + assert!(matches!(ct.kind(), ty::ConstKind::Param(_))) } ty::subst::GenericArgKind::Lifetime(..) => (), }, @@ -69,7 +69,7 @@ where } fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow { - match c.val() { + match c.kind() { ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam), _ => c.super_visit_with(self), } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 2dab9ff898..b0087fcdfa 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -338,6 +338,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' { "invalid drop function pointer in vtable (not pointing to a function)" }, err_ub!(InvalidVtableDropFn(..)) => { "invalid drop function pointer in vtable (function has incompatible signature)" }, + // Stacked Borrows errors can happen here, see https://github.com/rust-lang/miri/issues/2123. + // (We assume there are no other MachineStop errors possible here.) + InterpError::MachineStop(_) => + { "vtable pointer does not have permission to read drop function pointer" }, ); try_validation!( self.ecx.read_size_and_align_from_vtable(vtable), @@ -347,6 +351,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' err_ub!(InvalidVtableAlignment(msg)) => { "invalid vtable: alignment {}", msg }, err_unsup!(ReadPointerAsBytes) => { "invalid size or align in vtable" }, + // Stacked Borrows errors can happen here, see https://github.com/rust-lang/miri/issues/2123. + // (We assume there are no other MachineStop errors possible here.) + InterpError::MachineStop(_) => + { "vtable pointer does not have permission to read size and alignment" }, ); // FIXME: More checks for the vtable. } @@ -412,22 +420,27 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' self.path, err_ub!(AlignmentCheckFailed { required, has }) => { - "an unaligned {} (required {} byte alignment but found {})", - kind, + "an unaligned {kind} (required {} byte alignment but found {})", required.bytes(), has.bytes() }, err_ub!(DanglingIntPointer(0, _)) => - { "a null {}", kind }, + { "a null {kind}" }, err_ub!(DanglingIntPointer(i, _)) => - { "a dangling {} (address 0x{:x} is unallocated)", kind, i }, + { "a dangling {kind} (address 0x{i:x} is unallocated)" }, err_ub!(PointerOutOfBounds { .. }) => - { "a dangling {} (going beyond the bounds of its allocation)", kind }, + { "a dangling {kind} (going beyond the bounds of its allocation)" }, // This cannot happen during const-eval (because interning already detects // dangling pointers), but it can happen in Miri. err_ub!(PointerUseAfterFree(..)) => - { "a dangling {} (use-after-free)", kind }, + { "a dangling {kind} (use-after-free)" }, ); + // Do not allow pointers to uninhabited types. + if place.layout.abi.is_uninhabited() { + throw_validation_failure!(self.path, + { "a {kind} pointing to uninhabited type {}", place.layout.ty } + ) + } // Recursive checking if let Some(ref mut ref_tracking) = self.ref_tracking { // Proceed recursively even for ZST, no reason to skip them! @@ -531,15 +544,23 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' let value = self.read_scalar(value)?; // NOTE: Keep this in sync with the array optimization for int/float // types below! - if M::enforce_number_validity(self.ecx) { - // Integers/floats with number validity: Must be scalar bits, pointers are dangerous. + if M::enforce_number_init(self.ecx) { + try_validation!( + value.check_init(), + self.path, + err_ub!(InvalidUninitBytes(..)) => + { "{:x}", value } expected { "initialized bytes" } + ); + } + // Always check for number provenance during CTFE validation, even if the machine + // internally temporarily accepts number provenance. + if self.ctfe_mode.is_some() || M::enforce_number_no_provenance(self.ecx) { // As a special exception we *do* match on a `Scalar` here, since we truly want // to know its underlying representation (and *not* cast it to an integer). - let is_bits = - value.check_init().map_or(false, |v| matches!(v, Scalar::Int(..))); - if !is_bits { + let is_ptr = value.check_init().map_or(false, |v| matches!(v, Scalar::Ptr(..))); + if is_ptr { throw_validation_failure!(self.path, - { "{:x}", value } expected { "initialized plain (non-pointer) bytes" } + { "{:x}", value } expected { "plain (non-pointer) bytes" } ) } } @@ -646,7 +667,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' let size = scalar_layout.size(self.ecx); let is_full_range = match scalar_layout { ScalarAbi::Initialized { .. } => { - if M::enforce_number_validity(self.ecx) { + if M::enforce_number_init(self.ecx) { false // not "full" since uninit is not accepted } else { scalar_layout.is_always_valid(self.ecx) @@ -905,10 +926,12 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> return Ok(()); }; - let allow_uninit_and_ptr = !M::enforce_number_validity(self.ecx); + // Always check for number provenance during CTFE validation, even if the machine + // internally temporarily accepts number provenance. match alloc.check_bytes( alloc_range(Size::ZERO, size), - allow_uninit_and_ptr, + /*allow_uninit*/ !M::enforce_number_init(self.ecx), + /*allow_ptr*/ !(self.ctfe_mode.is_some() || M::enforce_number_no_provenance(self.ecx)), ) { // In the happy case, we needn't check anything else. Ok(()) => {} diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 1ab461a942..64a74e9d7e 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -7,9 +7,9 @@ Rust MIR: a lowered representation of Rust. #![feature(assert_matches)] #![feature(box_patterns)] #![feature(control_flow_enum)] -#![feature(crate_visibility_modifier)] #![feature(decl_macro)] #![feature(exact_size_is_empty)] +#![feature(let_chains)] #![feature(let_else)] #![feature(map_try_insert)] #![feature(min_specialization)] @@ -20,6 +20,7 @@ Rust MIR: a lowered representation of Rust. #![feature(trusted_len)] #![feature(trusted_step)] #![feature(try_blocks)] +#![feature(yeet_expr)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] @@ -33,27 +34,28 @@ pub mod interpret; pub mod transform; pub mod util; +use rustc_middle::ty; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::ParamEnv; pub fn provide(providers: &mut Providers) { const_eval::provide(providers); providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider; providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; providers.const_caller_location = const_eval::const_caller_location; - providers.try_destructure_const = |tcx, param_env_and_value| { - let (param_env, value) = param_env_and_value.into_parts(); - const_eval::try_destructure_const(tcx, param_env, value).ok() - }; - providers.const_to_valtree = |tcx, param_env_and_value| { + providers.try_destructure_const = |tcx, val| const_eval::try_destructure_const(tcx, val); + providers.eval_to_valtree = |tcx, param_env_and_value| { let (param_env, raw) = param_env_and_value.into_parts(); - const_eval::const_to_valtree(tcx, param_env, raw) + const_eval::eval_to_valtree(tcx, param_env, raw) + }; + providers.try_destructure_mir_constant = |tcx, param_env_and_value| { + let (param_env, value) = param_env_and_value.into_parts(); + const_eval::try_destructure_mir_constant(tcx, param_env, value).ok() }; providers.valtree_to_const_val = |tcx, (ty, valtree)| { - const_eval::valtree_to_const_value(tcx, ParamEnv::empty().and(ty), valtree) + const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree) }; - providers.deref_const = |tcx, param_env_and_value| { + providers.deref_mir_constant = |tcx, param_env_and_value| { let (param_env, value) = param_env_and_value.into_parts(); - const_eval::deref_const(tcx, param_env, value) + const_eval::deref_mir_constant(tcx, param_env, value) }; } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 8d3bbefb37..069fbed36e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -8,7 +8,6 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt}; use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeFoldable}; @@ -229,18 +228,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // The local type and predicate checks are not free and only relevant for `const fn`s. if self.const_kind() == hir::ConstContext::ConstFn { - // Prevent const trait methods from being annotated as `stable`. - // FIXME: Do this as part of stability checking. - if self.is_const_stable_const_fn() { - if crate::const_eval::is_parent_const_impl_raw(tcx, def_id) { - self.ccx - .tcx - .sess - .struct_span_err(self.span, "trait methods cannot be stable const fn") - .emit(); - } - } - for (idx, local) in body.local_decls.iter_enumerated() { // Handle the return place below. if idx == RETURN_PLACE || local.internal { @@ -532,39 +519,33 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } } - Rvalue::Cast( - CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer), - _, - _, - ) => {} - Rvalue::Cast( CastKind::Pointer( - PointerCast::UnsafeFnPointer + PointerCast::MutToConstPointer + | PointerCast::ArrayToPointer + | PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer, ), _, _, ) => { - // Nothing to do here. Function pointer casts are allowed now. + // These are all okay; they only change the type, not the data. } Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => { - // Nothing to check here (`check_local_or_return_ty` ensures no trait objects occur - // in the type of any local, which also excludes casts). + // Unsizing is implemented for CTFE. } - Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => { - let operand_ty = operand.ty(self.body, self.tcx); - let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast"); - let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); - - if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) { - self.check_op(ops::RawPtrToIntCast); - } + Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { + self.check_op(ops::RawPtrToIntCast); + } + Rvalue::Cast(CastKind::PointerFromExposedAddress, _, _) => { + // Since no pointer can ever get exposed (rejected above), this is easy to support. } + Rvalue::Cast(CastKind::Misc, _, _) => {} + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {} Rvalue::ShallowInitBox(_, _) => {} @@ -702,8 +683,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { - use rustc_target::spec::abi::Abi::RustIntrinsic; - self.super_terminator(terminator, location); match &terminator.kind { @@ -725,8 +704,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } }; - let mut nonconst_call_permission = false; - // Attempting to call a trait method? if let Some(trait_id) = tcx.trait_of_item(callee) { trace!("attempting to call a trait method"); @@ -776,7 +753,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { callee = did; } - if let hir::Constness::NotConst = tcx.impl_constness(data.impl_def_id) { + if let hir::Constness::NotConst = tcx.constness(data.impl_def_id) { self.check_op(ops::FnCallNonConst { caller, callee, @@ -788,13 +765,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } } _ if !tcx.is_const_fn_raw(callee) => { - // At this point, it is only legal when the caller is marked with - // #[default_method_body_is_const], and the callee is in the same - // trait. - let callee_trait = tcx.trait_of_item(callee); - if callee_trait.is_some() - && tcx.has_attr(caller.to_def_id(), sym::default_method_body_is_const) - && callee_trait == tcx.trait_of_item(caller) + // At this point, it is only legal when the caller is in a trait + // marked with #[const_trait], and the callee is in the same trait. + let mut nonconst_call_permission = false; + if let Some(callee_trait) = tcx.trait_of_item(callee) + && tcx.has_attr(callee_trait, sym::const_trait) + && Some(callee_trait) == tcx.trait_of_item(caller) // Can only call methods when it's `::f`. && tcx.types.self_param == substs.type_at(0) { @@ -885,19 +861,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { return; } - let is_intrinsic = tcx.fn_sig(callee).abi() == RustIntrinsic; + let is_intrinsic = tcx.is_intrinsic(callee); if !tcx.is_const_fn_raw(callee) { - if tcx.trait_of_item(callee).is_some() { - if tcx.has_attr(callee, sym::default_method_body_is_const) { - // To get to here we must have already found a const impl for the - // trait, but for it to still be non-const can be that the impl is - // using default method bodies. - nonconst_call_permission = true; - } - } - - if !nonconst_call_permission { + if !tcx.is_const_default_method(callee) { + // To get to here we must have already found a const impl for the + // trait, but for it to still be non-const can be that the impl is + // using default method bodies. self.check_op(ops::FnCallNonConst { caller, callee, @@ -946,7 +916,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // have no `rustc_const_stable` attributes to be const-unstable as well. This // should be fixed later. let callee_is_unstable_unmarked = tcx.lookup_const_stability(callee).is_none() - && tcx.lookup_stability(callee).map_or(false, |s| s.level.is_unstable()); + && tcx.lookup_stability(callee).map_or(false, |s| s.is_unstable()); if callee_is_unstable_unmarked { trace!("callee_is_unstable_unmarked"); // We do not use `const` modifiers for intrinsic "functions", as intrinsics are @@ -1065,7 +1035,7 @@ fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol .span_suggestion( attr_span, "if it is not part of the public API, make this function unstably const", - concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(), + concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n'), Applicability::HasPlaceholders, ) .span_suggestion( diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 23e2afae79..25b420bed1 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::mir; use rustc_middle::ty::{self, TyCtxt}; -use rustc_span::{sym, Symbol}; +use rustc_span::Symbol; pub use self::qualifs::Qualif; @@ -84,34 +84,49 @@ pub fn rustc_allow_const_fn_unstable( // functions are subject to more stringent restrictions than "const-unstable" functions: They // cannot use unstable features and can only call other "const-stable" functions. pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - use attr::{ConstStability, Stability, StabilityLevel}; - - // A default body marked const is not const-stable because const + // A default body in a `#[const_trait]` is not const-stable because const // trait fns currently cannot be const-stable. We shouldn't // restrict default bodies to only call const-stable functions. - if tcx.has_attr(def_id, sym::default_method_body_is_const) { + if tcx.is_const_default_method(def_id) { return false; } // Const-stability is only relevant for `const fn`. assert!(tcx.is_const_fn_raw(def_id)); - // Functions with `#[rustc_const_unstable]` are const-unstable. + // A function is only const-stable if it has `#[rustc_const_stable]` or it the trait it belongs + // to is const-stable. match tcx.lookup_const_stability(def_id) { - Some(ConstStability { level: StabilityLevel::Unstable { .. }, .. }) => return false, - Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => return true, - None => {} + Some(stab) => stab.is_const_stable(), + None if is_parent_const_stable_trait(tcx, def_id) => { + // Remove this when `#![feature(const_trait_impl)]` is stabilized, + // returning `true` unconditionally. + tcx.sess.delay_span_bug( + tcx.def_span(def_id), + "trait implementations cannot be const stable yet", + ); + true + } + None => false, // By default, items are not const stable. } +} + +fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + let local_def_id = def_id.expect_local(); + let hir_id = tcx.local_def_id_to_hir_id(local_def_id); + + let Some(parent) = tcx.hir().find_parent_node(hir_id) else { return false }; + let parent_def = tcx.hir().get(parent); - // Functions with `#[unstable]` are const-unstable. - // - // FIXME(ecstaticmorse): We should keep const-stability attributes wholly separate from normal stability - // attributes. `#[unstable]` should be irrelevant. - if let Some(Stability { level: StabilityLevel::Unstable { .. }, .. }) = - tcx.lookup_stability(def_id) - { + if !matches!( + parent_def, + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), + .. + }) + ) { return false; } - true + tcx.lookup_const_stability(parent.owner).map_or(false, |stab| stab.is_const_stable()) } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 122471b208..0c587220cb 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -10,7 +10,8 @@ use rustc_middle::mir; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{ - suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, TraitPredicate, Ty, + suggest_constraining_type_param, Adt, Closure, DefIdTree, FnDef, FnPtr, Param, TraitPredicate, + Ty, }; use rustc_middle::ty::{Binder, BoundConstness, ImplPolarity, TraitRef}; use rustc_session::parse::feature_err; @@ -89,7 +90,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect { ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - ccx.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn") + ccx.tcx.sess.struct_span_err( + span, + &format!("function pointer calls are not allowed in {}s", ccx.const_kind()), + ) } } @@ -297,6 +301,15 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { diag_trait(&mut err, self_ty, tcx.lang_items().deref_trait().unwrap()); err } + _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentV1Methods) => { + struct_span_err!( + ccx.tcx.sess, + span, + E0015, + "cannot call non-const formatting macro in {}s", + ccx.const_kind(), + ) + } _ => struct_span_err!( ccx.tcx.sess, span, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 9fd94dc334..6e5a0c813a 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -353,7 +353,8 @@ where // Check the qualifs of the value of `const` items. if let Some(ct) = constant.literal.const_for_ty() { - if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.val() { + if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.kind() + { // Use qualifs of the type for the promoted. Promoteds in MIR body should be possible // only for `NeedsNonConstDrop` with precise drop checking. This is the only const // check performed after the promotion. Verify that with an assertion. diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index f88538f61e..3595a488d0 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -16,7 +16,6 @@ use rustc_hir as hir; use rustc_middle::mir::traversal::ReversePostorderIter; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, List, TyCtxt, TypeFoldable}; use rustc_span::Span; @@ -502,18 +501,12 @@ impl<'tcx> Validator<'_, 'tcx> { Rvalue::ThreadLocalRef(_) => return Err(Unpromotable), - Rvalue::Cast(kind, operand, cast_ty) => { - if matches!(kind, CastKind::Misc) { - let operand_ty = operand.ty(self.body, self.tcx); - let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast"); - let cast_out = CastTy::from_ty(*cast_ty).expect("bad output type for cast"); - if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) { - // ptr-to-int casts are not possible in consts and thus not promotable - return Err(Unpromotable); - } - // int-to-ptr casts are fine, they just use the integer value at pointer type. - } + // ptr-to-int casts are not possible in consts and thus not promotable + Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => return Err(Unpromotable), + // all other casts including int-to-ptr casts are fine, they just use the integer value + // at pointer type. + Rvalue::Cast(_, operand, _) => { self.validate_operand(operand)?; } @@ -772,7 +765,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let unit = Rvalue::Use(Operand::Constant(Box::new(Constant { span: statement.source_info.span, user_ty: None, - literal: ty::Const::zero_sized(self.tcx, self.tcx.types.unit).into(), + literal: ConstantKind::zero_sized(self.tcx.types.unit), }))); mem::replace(rhs, unit) }, @@ -788,7 +781,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } else { let terminator = self.source[loc.block].terminator_mut(); let target = match terminator.kind { - TerminatorKind::Call { destination: Some((_, target)), .. } => target, + TerminatorKind::Call { target: Some(target), .. } => target, ref kind => { span_bug!(terminator.source_info.span, "{:?} not promotable", kind); } @@ -814,7 +807,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { func, args, cleanup: None, - destination: Some((Place::from(new_temp), new_target)), + destination: Place::from(new_temp), + target: Some(new_target), from_hir_call, fn_span, }, @@ -841,26 +835,25 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let mut promoted_operand = |ty, span| { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span); + let _const = tcx.mk_const(ty::ConstS { + ty, + kind: ty::ConstKind::Unevaluated(ty::Unevaluated { + def, + substs: InternalSubsts::for_item(tcx, def.did, |param, _| { + if let ty::GenericParamDefKind::Lifetime = param.kind { + tcx.lifetimes.re_erased.into() + } else { + tcx.mk_param_from_def(param) + } + }), + promoted: Some(promoted_id), + }), + }); Operand::Constant(Box::new(Constant { span, user_ty: None, - literal: tcx - .mk_const(ty::ConstS { - ty, - val: ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs: InternalSubsts::for_item(tcx, def.did, |param, _| { - if let ty::GenericParamDefKind::Lifetime = param.kind { - tcx.lifetimes.re_erased.into() - } else { - tcx.mk_param_from_def(param) - } - }), - promoted: Some(promoted_id), - }), - }) - .into(), + literal: ConstantKind::from_const(_const, tcx), })) }; let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); @@ -1054,11 +1047,9 @@ pub fn is_const_fn_in_array_repeat_expression<'tcx>( { if let Operand::Constant(box Constant { literal, .. }) = func { if let ty::FnDef(def_id, _) = *literal.ty().kind() { - if let Some((destination_place, _)) = destination { - if destination_place == place { - if ccx.tcx.is_const_fn(def_id) { - return true; - } + if destination == place { + if ccx.tcx.is_const_fn(def_id) { + return true; } } } diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 3ce33d547c..66d66ea951 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -4,6 +4,7 @@ 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}; use rustc_middle::mir::{ traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, Local, Location, MirPass, @@ -13,7 +14,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_mir_dataflow::impls::MaybeStorageLive; -use rustc_mir_dataflow::storage::AlwaysLiveLocals; +use rustc_mir_dataflow::storage::always_live_locals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; use rustc_target::abi::{Size, VariantIdx}; @@ -47,7 +48,7 @@ impl<'tcx> MirPass<'tcx> for Validator { let param_env = tcx.param_env(def_id); let mir_phase = self.mir_phase; - let always_live_locals = AlwaysLiveLocals::new(body); + let always_live_locals = always_live_locals(body); let storage_liveness = MaybeStorageLive::new(always_live_locals) .into_engine(tcx, body) .iterate_to_fixpoint() @@ -239,72 +240,94 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { context: PlaceContext, location: Location, ) { - if let ProjectionElem::Index(index) = elem { - let index_ty = self.body.local_decls[index].ty; - if index_ty != self.tcx.types.usize { - self.fail(location, format!("bad index ({:?} != usize)", index_ty)) + match elem { + ProjectionElem::Index(index) => { + let index_ty = self.body.local_decls[index].ty; + if index_ty != self.tcx.types.usize { + self.fail(location, format!("bad index ({:?} != usize)", index_ty)) + } } - } - if let ProjectionElem::Field(f, ty) = elem { - let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) }; - let parent_ty = parent.ty(&self.body.local_decls, self.tcx); - let fail_out_of_bounds = |this: &Self, location| { - this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty)); - }; - let check_equal = |this: &Self, location, f_ty| { - if !this.mir_assign_valid_types(ty, f_ty) { - this.fail( + ProjectionElem::Deref if self.mir_phase >= MirPhase::GeneratorsLowered => { + let base_ty = Place::ty_from(local, proj_base, &self.body.local_decls, self.tcx).ty; + + if base_ty.is_box() { + self.fail( + location, + format!("{:?} dereferenced after ElaborateBoxDerefs", base_ty), + ) + } + } + ProjectionElem::Field(f, ty) => { + let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) }; + let parent_ty = parent.ty(&self.body.local_decls, self.tcx); + let fail_out_of_bounds = |this: &Self, location| { + this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty)); + }; + let check_equal = |this: &Self, location, f_ty| { + if !this.mir_assign_valid_types(ty, f_ty) { + this.fail( location, format!( "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is {:?}", parent, f, ty, f_ty ) ) - } - }; - match parent_ty.ty.kind() { - ty::Tuple(fields) => { - let Some(f_ty) = fields.get(f.as_usize()) else { - fail_out_of_bounds(self, location); - return; - }; - check_equal(self, location, *f_ty); - } - ty::Adt(adt_def, substs) => { - let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0)); - let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { - fail_out_of_bounds(self, location); - return; - }; - check_equal(self, location, field.ty(self.tcx, substs)); - } - ty::Closure(_, substs) => { - let substs = substs.as_closure(); - let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else { - fail_out_of_bounds(self, location); - return; - }; - check_equal(self, location, f_ty); - } - ty::Generator(_, substs, _) => { - let substs = substs.as_generator(); - let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else { - fail_out_of_bounds(self, location); - return; - }; - check_equal(self, location, f_ty); - } - _ => { - self.fail(location, format!("{:?} does not have fields", parent_ty.ty)); + } + }; + + match parent_ty.ty.kind() { + ty::Tuple(fields) => { + let Some(f_ty) = fields.get(f.as_usize()) else { + fail_out_of_bounds(self, location); + return; + }; + check_equal(self, location, *f_ty); + } + ty::Adt(adt_def, substs) => { + let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0)); + let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { + fail_out_of_bounds(self, location); + return; + }; + check_equal(self, location, field.ty(self.tcx, substs)); + } + ty::Closure(_, substs) => { + let substs = substs.as_closure(); + let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else { + fail_out_of_bounds(self, location); + return; + }; + check_equal(self, location, f_ty); + } + ty::Generator(_, substs, _) => { + let substs = substs.as_generator(); + let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else { + fail_out_of_bounds(self, location); + return; + }; + check_equal(self, location, f_ty); + } + _ => { + self.fail(location, format!("{:?} does not have fields", parent_ty.ty)); + } } } + _ => {} } self.super_projection_elem(local, proj_base, elem, context, location); } - fn visit_place(&mut self, place: &Place<'tcx>, _: PlaceContext, _: Location) { + fn visit_place(&mut self, place: &Place<'tcx>, cntxt: PlaceContext, location: Location) { // Set off any `bug!`s in the type computation code let _ = place.ty(&self.body.local_decls, self.tcx); + + if self.mir_phase >= MirPhase::Derefered + && place.projection.len() > 1 + && cntxt != PlaceContext::NonUse(VarDebugInfo) + && place.projection[1..].contains(&ProjectionElem::Deref) + { + self.fail(location, format!("{:?}, has deref at the wrong place", place)); + } } fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { @@ -673,7 +696,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.check_edge(location, *unwind, EdgeKind::Unwind); } } - TerminatorKind::Call { func, args, destination, cleanup, .. } => { + TerminatorKind::Call { func, args, destination, target, cleanup, .. } => { let func_ty = func.ty(&self.body.local_decls, self.tcx); match func_ty.kind() { ty::FnPtr(..) | ty::FnDef(..) => {} @@ -682,7 +705,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { format!("encountered non-callable type {} in `Call` terminator", func_ty), ), } - if let Some((_, target)) = destination { + if let Some(target) = target { self.check_edge(location, *target, EdgeKind::Normal); } if let Some(cleanup) = cleanup { @@ -693,9 +716,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // passed by a reference to the callee. Consequently they must be non-overlapping. // Currently this simply checks for duplicate places. self.place_cache.clear(); - if let Some((destination, _)) = destination { - self.place_cache.push(destination.as_ref()); - } + self.place_cache.push(destination.as_ref()); for arg in args { if let Operand::Move(place) = arg { self.place_cache.push(place.as_ref()); diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 7cc8b5c203..3192fc4cc5 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -9,7 +9,7 @@ doctest = false [dependencies] arrayvec = { version = "0.7", default-features = false } ena = "0.14" -indexmap = { version = "1.8.0" } +indexmap = { version = "1.9.1" } tracing = "0.1" jobserver_crate = { version = "0.1.13", package = "jobserver" } rustc_serialize = { path = "../rustc_serialize" } @@ -17,8 +17,8 @@ rustc_macros = { path = "../rustc_macros" } rustc_graphviz = { path = "../rustc_graphviz" } cfg-if = "0.1.2" stable_deref_trait = "1.0.0" -rayon = { version = "0.3.2", package = "rustc-rayon", optional = true } -rayon-core = { version = "0.3.2", package = "rustc-rayon-core", optional = true } +rayon = { version = "0.4.0", package = "rustc-rayon", optional = true } +rayon-core = { version = "0.4.0", package = "rustc-rayon-core", optional = true } rustc-hash = "1.1.0" smallvec = { version = "1.6.1", features = ["const_generics", "union", "may_dangle"] } rustc_index = { path = "../rustc_index", package = "rustc_index" } diff --git a/compiler/rustc_data_structures/src/base_n/tests.rs b/compiler/rustc_data_structures/src/base_n/tests.rs index b68ef1eb7f..2be2f0532c 100644 --- a/compiler/rustc_data_structures/src/base_n/tests.rs +++ b/compiler/rustc_data_structures/src/base_n/tests.rs @@ -15,7 +15,9 @@ fn test_encode() { test(u64::MAX as u128, base); test(u128::MAX, base); - for i in 0..1_000 { + const N: u128 = if cfg!(miri) { 10 } else { 1000 }; + + for i in 0..N { test(i * 983, base); } } diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index c88f3e73cf..5ff2d18dd2 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -1,5 +1,5 @@ use crate::stable_hasher; -use rustc_serialize::{Decodable, Encodable}; +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::convert::TryInto; use std::hash::{Hash, Hasher}; @@ -142,15 +142,14 @@ impl stable_hasher::StableHasherResult for Fingerprint { impl_stable_hash_via_hash!(Fingerprint); -impl Encodable for Fingerprint { +impl Encodable for Fingerprint { #[inline] - fn encode(&self, s: &mut E) -> Result<(), E::Error> { - s.emit_raw_bytes(&self.to_le_bytes())?; - Ok(()) + fn encode(&self, s: &mut E) { + s.emit_raw_bytes(&self.to_le_bytes()); } } -impl Decodable for Fingerprint { +impl Decodable for Fingerprint { #[inline] fn decode(d: &mut D) -> Self { Fingerprint::from_le_bytes(d.read_raw_bytes(16).try_into().unwrap()) @@ -185,16 +184,16 @@ impl std::fmt::Display for PackedFingerprint { } } -impl Encodable for PackedFingerprint { +impl Encodable for PackedFingerprint { #[inline] - fn encode(&self, s: &mut E) -> Result<(), E::Error> { + fn encode(&self, s: &mut E) { // Copy to avoid taking reference to packed field. let copy = self.0; - copy.encode(s) + copy.encode(s); } } -impl Decodable for PackedFingerprint { +impl Decodable for PackedFingerprint { #[inline] fn decode(d: &mut D) -> Self { Self(Fingerprint::decode(d)) diff --git a/compiler/rustc_data_structures/src/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs index 364005e67e..9940fee60d 100644 --- a/compiler/rustc_data_structures/src/graph/scc/tests.rs +++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs @@ -156,7 +156,10 @@ fn test_deep_linear() { v … */ + #[cfg(not(miri))] const NR_NODES: usize = 1 << 14; + #[cfg(miri)] + const NR_NODES: usize = 1 << 3; let mut nodes = vec![]; for i in 1..NR_NODES { nodes.push((i - 1, i)); diff --git a/compiler/rustc_data_structures/src/jobserver.rs b/compiler/rustc_data_structures/src/jobserver.rs index 41605afb44..09baa3095a 100644 --- a/compiler/rustc_data_structures/src/jobserver.rs +++ b/compiler/rustc_data_structures/src/jobserver.rs @@ -1,5 +1,5 @@ pub use jobserver_crate::Client; -use std::lazy::SyncLazy; +use std::sync::LazyLock; // We can only call `from_env` once per process @@ -18,7 +18,7 @@ use std::lazy::SyncLazy; // Also note that we stick this in a global because there could be // multiple rustc instances in this process, and the jobserver is // per-process. -static GLOBAL_CLIENT: SyncLazy = SyncLazy::new(|| unsafe { +static GLOBAL_CLIENT: LazyLock = LazyLock::new(|| unsafe { Client::from_env().unwrap_or_else(|| { let client = Client::new(32).expect("failed to create jobserver"); // Acquire a token for the main thread which we can release later diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 76ae17f28c..390a44d3f3 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -11,10 +11,7 @@ #![feature(associated_type_bounds)] #![feature(auto_traits)] #![feature(control_flow_enum)] -#![feature(core_intrinsics)] #![feature(extend_one)] -#![feature(generator_trait)] -#![feature(generators)] #![feature(let_else)] #![feature(hash_raw_entry)] #![feature(hasher_prefixfree_extras)] @@ -46,26 +43,6 @@ pub fn cold_path R, R>(f: F) -> R { f() } -#[macro_export] -macro_rules! likely { - ($e:expr) => { - match $e { - #[allow(unused_unsafe)] - e => unsafe { std::intrinsics::likely(e) }, - } - }; -} - -#[macro_export] -macro_rules! unlikely { - ($e:expr) => { - match $e { - #[allow(unused_unsafe)] - e => unsafe { std::intrinsics::unlikely(e) }, - } - }; -} - pub mod base_n; pub mod binary_search_util; pub mod captures; @@ -114,9 +91,6 @@ pub mod unhash; pub use ena::undo_log; pub use ena::unify; -use std::ops::{Generator, GeneratorState}; -use std::pin::Pin; - pub struct OnDrop(pub F); impl OnDrop { @@ -135,26 +109,6 @@ impl Drop for OnDrop { } } -struct IterFromGenerator(G); - -impl + Unpin> Iterator for IterFromGenerator { - type Item = G::Yield; - - fn next(&mut self) -> Option { - match Pin::new(&mut self.0).resume(()) { - GeneratorState::Yielded(n) => Some(n), - GeneratorState::Complete(_) => None, - } - } -} - -/// An adapter for turning a generator closure into an iterator, similar to `iter::from_fn`. -pub fn iter_from_generator + Unpin>( - generator: G, -) -> impl Iterator { - IterFromGenerator(generator) -} - // See comments in src/librustc_middle/lib.rs #[doc(hidden)] pub fn __noop_fix_for_27438() {} diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index 74f432a796..07a96dd7db 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -42,7 +42,7 @@ //! now considered to be in error. //! //! When the call to `process_obligations` completes, you get back an `Outcome`, -//! which includes three bits of information: +//! which includes two bits of information: //! //! - `completed`: a list of obligations where processing was fully //! completed without error (meaning that all transitive subobligations @@ -53,13 +53,10 @@ //! all the obligations in `C` have been found completed. //! - `errors`: a list of errors that occurred and associated backtraces //! at the time of error, which can be used to give context to the user. -//! - `stalled`: if true, then none of the existing obligations were -//! *shallowly successful* (that is, no callback returned `Changed(_)`). -//! This implies that all obligations were either errors or returned an -//! ambiguous result, which means that any further calls to -//! `process_obligations` would simply yield back further ambiguous -//! results. This is used by the `FulfillmentContext` to decide when it -//! has reached a steady state. +//! +//! Upon completion, none of the existing obligations were *shallowly +//! successful* (that is, no callback returned `Changed(_)`). This implies that +//! all obligations were either errors or returned an ambiguous result. //! //! ### Implementation details //! @@ -99,6 +96,8 @@ pub trait ObligationProcessor { type Obligation: ForestObligation; type Error: Debug; + fn needs_process_obligation(&self, obligation: &Self::Obligation) -> bool; + fn process_obligation( &mut self, obligation: &mut Self::Obligation, @@ -146,7 +145,7 @@ pub struct ObligationForest { /// A cache of the nodes in `nodes`, indexed by predicate. Unfortunately, /// its contents are not guaranteed to match those of `nodes`. See the - /// comments in [`Self::process_obligation` for details. + /// comments in `Self::process_obligation` for details. active_cache: FxHashMap, /// A vector reused in [Self::compress()] and [Self::find_cycles_from_node()], @@ -260,8 +259,6 @@ pub trait OutcomeTrait { type Obligation; fn new() -> Self; - fn mark_not_stalled(&mut self); - fn is_stalled(&self) -> bool; fn record_completed(&mut self, outcome: &Self::Obligation); fn record_error(&mut self, error: Self::Error); } @@ -270,14 +267,6 @@ pub trait OutcomeTrait { pub struct Outcome { /// Backtrace of obligations that were found to be in error. pub errors: Vec>, - - /// If true, then we saw no successful obligations, which means - /// there is no point in further iteration. This is based on the - /// assumption that when trait matching returns `Error` or - /// `Unchanged`, those results do not affect environmental - /// inference state. (Note that if we invoke `process_obligations` - /// with no pending obligations, stalled will be true.) - pub stalled: bool, } impl OutcomeTrait for Outcome { @@ -285,15 +274,7 @@ impl OutcomeTrait for Outcome { type Obligation = O; fn new() -> Self { - Self { stalled: true, errors: vec![] } - } - - fn mark_not_stalled(&mut self) { - self.stalled = false; - } - - fn is_stalled(&self) -> bool { - self.stalled + Self { errors: vec![] } } fn record_completed(&mut self, _outcome: &Self::Obligation) { @@ -415,10 +396,7 @@ impl ObligationForest { .insert(node.obligation.as_cache_key()); } - /// Performs a pass through the obligation list. This must - /// be called in a loop until `outcome.stalled` is false. - /// - /// This _cannot_ be unrolled (presently, at least). + /// Performs a fixpoint computation over the obligation list. #[inline(never)] pub fn process_obligations(&mut self, processor: &mut P) -> OUT where @@ -427,55 +405,69 @@ impl ObligationForest { { let mut outcome = OUT::new(); - // Note that the loop body can append new nodes, and those new nodes - // will then be processed by subsequent iterations of the loop. - // - // We can't use an iterator for the loop because `self.nodes` is - // appended to and the borrow checker would complain. We also can't use - // `for index in 0..self.nodes.len() { ... }` because the range would - // be computed with the initial length, and we would miss the appended - // nodes. Therefore we use a `while` loop. - let mut index = 0; - while let Some(node) = self.nodes.get_mut(index) { - // `processor.process_obligation` can modify the predicate within - // `node.obligation`, and that predicate is the key used for - // `self.active_cache`. This means that `self.active_cache` can get - // out of sync with `nodes`. It's not very common, but it does - // happen, and code in `compress` has to allow for it. - if node.state.get() != NodeState::Pending { - index += 1; - continue; - } - - match processor.process_obligation(&mut node.obligation) { - ProcessResult::Unchanged => { - // No change in state. + // Fixpoint computation: we repeat until the inner loop stalls. + loop { + let mut has_changed = false; + + // Note that the loop body can append new nodes, and those new nodes + // will then be processed by subsequent iterations of the loop. + // + // We can't use an iterator for the loop because `self.nodes` is + // appended to and the borrow checker would complain. We also can't use + // `for index in 0..self.nodes.len() { ... }` because the range would + // be computed with the initial length, and we would miss the appended + // nodes. Therefore we use a `while` loop. + let mut index = 0; + while let Some(node) = self.nodes.get_mut(index) { + if node.state.get() != NodeState::Pending + || !processor.needs_process_obligation(&node.obligation) + { + index += 1; + continue; } - ProcessResult::Changed(children) => { - // We are not (yet) stalled. - outcome.mark_not_stalled(); - node.state.set(NodeState::Success); - - for child in children { - let st = self.register_obligation_at(child, Some(index)); - if let Err(()) = st { - // Error already reported - propagate it - // to our node. - self.error_at(index); + + // `processor.process_obligation` can modify the predicate within + // `node.obligation`, and that predicate is the key used for + // `self.active_cache`. This means that `self.active_cache` can get + // out of sync with `nodes`. It's not very common, but it does + // happen, and code in `compress` has to allow for it. + + match processor.process_obligation(&mut node.obligation) { + ProcessResult::Unchanged => { + // No change in state. + } + ProcessResult::Changed(children) => { + // We are not (yet) stalled. + has_changed = true; + node.state.set(NodeState::Success); + + for child in children { + let st = self.register_obligation_at(child, Some(index)); + if let Err(()) = st { + // Error already reported - propagate it + // to our node. + self.error_at(index); + } } } + ProcessResult::Error(err) => { + has_changed = true; + outcome.record_error(Error { error: err, backtrace: self.error_at(index) }); + } } - ProcessResult::Error(err) => { - outcome.mark_not_stalled(); - outcome.record_error(Error { error: err, backtrace: self.error_at(index) }); - } + index += 1; + } + + // If unchanged, then we saw no successful obligations, which means + // there is no point in further iteration. This is based on the + // assumption that when trait matching returns `Error` or + // `Unchanged`, those results do not affect environmental inference + // state. (Note that this will occur if we invoke + // `process_obligations` with no pending obligations.) + if !has_changed { + break; } - index += 1; - } - // There's no need to perform marking, cycle processing and compression when nothing - // changed. - if !outcome.is_stalled() { self.mark_successes(); self.process_cycles(processor); self.compress(|obl| outcome.record_completed(obl)); @@ -634,17 +626,14 @@ impl ObligationForest { } } NodeState::Done => { - // This lookup can fail because the contents of + // The removal lookup might fail because the contents of // `self.active_cache` are not guaranteed to match those of // `self.nodes`. See the comment in `process_obligation` // for more details. - if let Some((predicate, _)) = - self.active_cache.remove_entry(&node.obligation.as_cache_key()) - { - self.done_cache.insert(predicate); - } else { - self.done_cache.insert(node.obligation.as_cache_key().clone()); - } + let cache_key = node.obligation.as_cache_key(); + self.active_cache.remove(&cache_key); + self.done_cache.insert(cache_key); + // Extract the success stories. outcome_cb(&node.obligation); node_rewrites[index] = orig_nodes_len; diff --git a/compiler/rustc_data_structures/src/obligation_forest/tests.rs b/compiler/rustc_data_structures/src/obligation_forest/tests.rs index 371c62c063..e2991aae17 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/tests.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/tests.rs @@ -20,7 +20,6 @@ struct ClosureObligationProcessor { struct TestOutcome { pub completed: Vec, pub errors: Vec>, - pub stalled: bool, } impl OutcomeTrait for TestOutcome @@ -31,15 +30,7 @@ where type Obligation = O; fn new() -> Self { - Self { errors: vec![], stalled: false, completed: vec![] } - } - - fn mark_not_stalled(&mut self) { - self.stalled = false; - } - - fn is_stalled(&self) -> bool { - self.stalled + Self { errors: vec![], completed: vec![] } } fn record_completed(&mut self, outcome: &Self::Obligation) { @@ -74,6 +65,10 @@ where type Obligation = O; type Error = E; + fn needs_process_obligation(&self, _obligation: &Self::Obligation) -> bool { + true + } + fn process_obligation( &mut self, obligation: &mut Self::Obligation, diff --git a/compiler/rustc_data_structures/src/owning_ref/tests.rs b/compiler/rustc_data_structures/src/owning_ref/tests.rs index 7b8179e90b..320c03d513 100644 --- a/compiler/rustc_data_structures/src/owning_ref/tests.rs +++ b/compiler/rustc_data_structures/src/owning_ref/tests.rs @@ -1,3 +1,5 @@ +// FIXME: owning_ref is not sound under stacked borrows. Preferably, get rid of it. +#[cfg(not(miri))] mod owning_ref { use super::super::OwningRef; use super::super::{BoxRef, Erased, ErasedBoxRef, RcRef}; @@ -361,6 +363,8 @@ mod owning_handle { } } +// FIXME: owning_ref is not sound under stacked borrows. Preferably, get rid of it. +#[cfg(not(miri))] mod owning_ref_mut { use super::super::BoxRef; use super::super::{BoxRefMut, Erased, ErasedBoxRefMut, OwningRefMut}; diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index bf7924a81f..88ff33b4d0 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -195,6 +195,7 @@ impl SelfProfilerRef { F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>, { #[inline(never)] + #[cold] fn cold_call(profiler_ref: &SelfProfilerRef, f: F) -> TimingGuard<'_> where F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>, @@ -203,7 +204,7 @@ impl SelfProfilerRef { f(&**profiler) } - if unlikely!(self.event_filter_mask.contains(event_filter)) { + if self.event_filter_mask.contains(event_filter) { cold_call(self, f) } else { TimingGuard::none() @@ -550,14 +551,20 @@ impl SelfProfiler { pub fn new( output_directory: &Path, crate_name: Option<&str>, - event_filters: &Option>, + event_filters: Option<&[String]>, + counter_name: &str, ) -> Result> { fs::create_dir_all(output_directory)?; let crate_name = crate_name.unwrap_or("unknown-crate"); - let filename = format!("{}-{}.rustc_profile", crate_name, process::id()); + // HACK(eddyb) we need to pad the PID, strange as it may seem, as its + // length can behave as a source of entropy for heap addresses, when + // ASLR is disabled and the heap is otherwise determinic. + let pid: u32 = process::id(); + let filename = format!("{}-{:07}.rustc_profile", crate_name, pid); let path = output_directory.join(&filename); - let profiler = Profiler::new(&path)?; + let profiler = + Profiler::with_counter(&path, measureme::counters::Counter::by_name(counter_name)?)?; let query_event_kind = profiler.alloc_string("Query"); let generic_activity_event_kind = profiler.alloc_string("GenericActivity"); @@ -570,7 +577,7 @@ impl SelfProfiler { let mut event_filter_mask = EventFilter::empty(); - if let Some(ref event_filters) = *event_filters { + if let Some(event_filters) = event_filters { let mut unknown_events = vec![]; for item in event_filters { if let Some(&(_, mask)) = diff --git a/compiler/rustc_data_structures/src/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs index abd25f46ad..90793a97ed 100644 --- a/compiler/rustc_data_structures/src/sip128.rs +++ b/compiler/rustc_data_structures/src/sip128.rs @@ -255,8 +255,9 @@ impl SipHasher128 { // elements from spill (at most LEN - 1 bytes could have overflowed // into the spill). The memcpy call is optimized away because the size // is known. And the whole copy is optimized away for LEN == 1. + let dst = self.buf.as_mut_ptr() as *mut u8; let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8; - ptr::copy_nonoverlapping(src, self.buf.as_mut_ptr() as *mut u8, LEN - 1); + ptr::copy_nonoverlapping(src, dst, LEN - 1); // This function should only be called when the write fills the buffer. // Therefore, when LEN == 1, the new `self.nbuf` must be zero. diff --git a/compiler/rustc_data_structures/src/sso/set.rs b/compiler/rustc_data_structures/src/sso/set.rs index f71522d371..4fda3adb7b 100644 --- a/compiler/rustc_data_structures/src/sso/set.rs +++ b/compiler/rustc_data_structures/src/sso/set.rs @@ -126,9 +126,10 @@ impl SsoHashSet { /// Adds a value to the set. /// - /// If the set did not have this value present, `true` is returned. + /// Returns whether the value was newly inserted. That is: /// - /// If the set did have this value present, `false` is returned. + /// - If the set did not previously contain this value, `true` is returned. + /// - If the set already contained this value, `false` is returned. #[inline] pub fn insert(&mut self, elem: T) -> bool { self.map.insert(elem, ()).is_none() diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index c8bb4fc5e6..a915a4daa9 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -632,10 +632,10 @@ fn stable_hash_reduce( } } -/// Controls what data we do or not not hash. +/// Controls what data we do or do not hash. /// Whenever a `HashStable` implementation caches its /// result, it needs to include `HashingControls` as part -/// of the key, to ensure that is does not produce an incorrect +/// of the key, to ensure that it does not produce an incorrect /// result (for example, using a `Fingerprint` produced while /// hashing `Span`s when a `Fingerprint` without `Span`s is /// being requested) diff --git a/compiler/rustc_data_structures/src/svh.rs b/compiler/rustc_data_structures/src/svh.rs index 12ef286091..61654b9e8f 100644 --- a/compiler/rustc_data_structures/src/svh.rs +++ b/compiler/rustc_data_structures/src/svh.rs @@ -49,8 +49,8 @@ impl fmt::Display for Svh { } impl Encodable for Svh { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_u64(self.as_u64().to_le()) + fn encode(&self, s: &mut S) { + s.emit_u64(self.as_u64().to_le()); } } diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index f99ca53ab2..feb82cb093 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -173,7 +173,7 @@ cfg_if! { pub use std::cell::RefMut as LockGuard; pub use std::cell::RefMut as MappedLockGuard; - pub use std::lazy::OnceCell; + pub use std::cell::OnceCell; use std::cell::RefCell as InnerRwLock; use std::cell::RefCell as InnerLock; @@ -258,7 +258,7 @@ cfg_if! { pub use parking_lot::MutexGuard as LockGuard; pub use parking_lot::MappedMutexGuard as MappedLockGuard; - pub use std::lazy::SyncOnceCell as OnceCell; + pub use std::sync::OnceLock as OnceCell; pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index fd2ca5bead..08d5d4f343 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -7,8 +7,8 @@ edition = "2021" crate-type = ["dylib"] [dependencies] -libc = "0.2" tracing = { version = "0.1.28" } +serde_json = "1.0.59" rustc_log = { path = "../rustc_log" } rustc_middle = { path = "../rustc_middle" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } @@ -20,7 +20,6 @@ rustc_feature = { path = "../rustc_feature" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_metadata = { path = "../rustc_metadata" } -rustc_const_eval = { path = "../rustc_const_eval" } rustc_parse = { path = "../rustc_parse" } rustc_plugin_impl = { path = "../rustc_plugin_impl" } rustc_save_analysis = { path = "../rustc_save_analysis" } @@ -28,11 +27,13 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_session = { path = "../rustc_session" } rustc_error_codes = { path = "../rustc_error_codes" } rustc_interface = { path = "../rustc_interface" } -rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } rustc_typeck = { path = "../rustc_typeck" } +[target.'cfg(unix)'.dependencies] +libc = "0.2" + [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] } diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 904d6f8cfd..caa92e7480 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(nll)] #![feature(let_else)] #![feature(once_cell)] #![recursion_limit = "256"] @@ -30,7 +29,6 @@ use rustc_log::stdout_isatty; use rustc_metadata::locator; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; -use rustc_serialize::json::ToJson; use rustc_session::config::{nightly_options, CG_OPTIONS, DB_OPTIONS}; use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths}; use rustc_session::cstore::MetadataLoader; @@ -40,6 +38,7 @@ use rustc_session::{config, DiagnosticOutput, Session}; use rustc_session::{early_error, early_error_no_abort, early_warn}; use rustc_span::source_map::{FileLoader, FileName}; use rustc_span::symbol::sym; +use rustc_target::json::ToJson; use std::borrow::Cow; use std::cmp::max; @@ -48,11 +47,11 @@ use std::env; use std::ffi::OsString; use std::fs; use std::io::{self, Read, Write}; -use std::lazy::SyncLazy; use std::panic::{self, catch_unwind}; use std::path::PathBuf; use std::process::{self, Command, Stdio}; use std::str; +use std::sync::LazyLock; use std::time::Instant; pub mod args; @@ -343,10 +342,7 @@ fn run_compiler( return early_exit(); } - if sess.opts.debugging_opts.parse_only - || sess.opts.debugging_opts.show_span.is_some() - || sess.opts.debugging_opts.ast_json_noexpand - { + if sess.opts.debugging_opts.parse_only || sess.opts.debugging_opts.show_span.is_some() { return early_exit(); } @@ -375,7 +371,7 @@ fn run_compiler( queries.global_ctxt()?; - if sess.opts.debugging_opts.no_analysis || sess.opts.debugging_opts.ast_json { + if sess.opts.debugging_opts.no_analysis { return early_exit(); } @@ -665,7 +661,9 @@ fn print_crate_info( } Sysroot => println!("{}", sess.sysroot.display()), TargetLibdir => println!("{}", sess.target_tlib_path.dir.display()), - TargetSpec => println!("{}", sess.target.to_json().pretty()), + TargetSpec => { + println!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap()); + } FileNames | CrateName => { let input = input.unwrap_or_else(|| { early_error(ErrorOutputType::default(), "no input file provided") @@ -1056,13 +1054,7 @@ pub fn handle_options(args: &[String]) -> Option { } if cg_flags.iter().any(|x| *x == "passes=list") { - let backend_name = debug_flags.iter().find_map(|x| { - if x.starts_with("codegen-backend=") { - Some(&x["codegen-backends=".len()..]) - } else { - None - } - }); + let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend=")); get_codegen_backend(&None, backend_name).print_passes(); return None; } @@ -1149,8 +1141,8 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 { } } -static DEFAULT_HOOK: SyncLazy) + Sync + Send + 'static>> = - SyncLazy::new(|| { +static DEFAULT_HOOK: LazyLock) + Sync + Send + 'static>> = + LazyLock::new(|| { let hook = panic::take_hook(); panic::set_hook(Box::new(|info| { // Invoke the default handler, which prints the actual panic message and optionally a backtrace @@ -1245,7 +1237,7 @@ pub fn install_ice_hook() { if std::env::var("RUST_BACKTRACE").is_err() { std::env::set_var("RUST_BACKTRACE", "full"); } - SyncLazy::force(&DEFAULT_HOOK); + LazyLock::force(&DEFAULT_HOOK); } /// This allows tools to enable rust logging without having to magically match rustc's diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 61a177f291..d507293ccb 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -491,6 +491,7 @@ E0784: include_str!("./error_codes/E0784.md"), E0785: include_str!("./error_codes/E0785.md"), E0786: include_str!("./error_codes/E0786.md"), E0787: include_str!("./error_codes/E0787.md"), +E0788: include_str!("./error_codes/E0788.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard @@ -527,7 +528,7 @@ E0787: include_str!("./error_codes/E0787.md"), // E0190, // deprecated: can only cast a &-pointer to an &-object // E0194, // merged into E0403 // E0196, // cannot determine a type for this closure - E0208, + E0208, // internal error code // E0209, // builtin traits can only be implemented on structs or enums // E0213, // associated types are not accepted in this context // E0215, // angle-bracket notation is not stable with `Fn` @@ -632,14 +633,14 @@ E0787: include_str!("./error_codes/E0787.md"), // E0629, // missing 'feature' (rustc_const_unstable) // E0630, // rustc_const_unstable attribute must be paired with stable/unstable // attribute - E0640, // infer outlives requirements + E0640, // infer outlives requirements, internal error code // E0645, // trait aliases not finished // E0694, // an unknown tool name found in scoped attributes // E0702, // replaced with a generic attribute input check // E0707, // multiple elided lifetimes used in arguments of `async fn` // E0709, // multiple different lifetimes used in arguments of `async fn` - E0711, // a feature has been declared with conflicting stability attributes - E0717, // rustc_promotable without stability attribute + E0711, // a feature has been declared with conflicting stability attributes, internal error code + E0717, // rustc_promotable without stability attribute, internal error code // E0721, // `await` keyword // E0723, // unstable feature in `const` context // E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`. diff --git a/compiler/rustc_error_codes/src/error_codes/E0060.md b/compiler/rustc_error_codes/src/error_codes/E0060.md index e6906d7236..54b10c886c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0060.md +++ b/compiler/rustc_error_codes/src/error_codes/E0060.md @@ -16,10 +16,10 @@ Using this declaration, it must be called with at least one argument, so simply calling `printf()` is invalid. But the following uses are allowed: ``` -# #![feature(static_nobundle)] # use std::os::raw::{c_char, c_int}; # #[cfg_attr(all(windows, target_env = "msvc"), -# link(name = "legacy_stdio_definitions", kind = "static-nobundle"))] +# link(name = "legacy_stdio_definitions", +# kind = "static", modifiers = "-bundle"))] # extern "C" { fn printf(_: *const c_char, ...) -> c_int; } # fn main() { unsafe { diff --git a/compiler/rustc_error_codes/src/error_codes/E0263.md b/compiler/rustc_error_codes/src/error_codes/E0263.md index 37271ac692..2d1ac40264 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0263.md +++ b/compiler/rustc_error_codes/src/error_codes/E0263.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + A lifetime was declared more than once in the same scope. Erroneous code example: -```compile_fail,E0263 +```compile_fail,E0403 fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str, z: &'a str) { // error! } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0312.md b/compiler/rustc_error_codes/src/error_codes/E0312.md index cb090d0138..c5f7cf2e33 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0312.md +++ b/compiler/rustc_error_codes/src/error_codes/E0312.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + Reference's lifetime of borrowed content doesn't match the expected lifetime. Erroneous code example: -```compile_fail,E0312 +```compile_fail pub fn opt_str<'a>(maybestr: &'a Option) -> &'static str { if maybestr.is_none() { "(none)" diff --git a/compiler/rustc_error_codes/src/error_codes/E0432.md b/compiler/rustc_error_codes/src/error_codes/E0432.md index a6e2acac5d..2920e2623f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0432.md +++ b/compiler/rustc_error_codes/src/error_codes/E0432.md @@ -10,10 +10,10 @@ In Rust 2015, paths in `use` statements are relative to the crate root. To import items relative to the current and parent modules, use the `self::` and `super::` prefixes, respectively. -In Rust 2018, paths in `use` statements are relative to the current module -unless they begin with the name of a crate or a literal `crate::`, in which -case they start from the crate root. As in Rust 2015 code, the `self::` and -`super::` prefixes refer to the current and parent modules respectively. +In Rust 2018 or later, paths in `use` statements are relative to the current +module unless they begin with the name of a crate or a literal `crate::`, in +which case they start from the crate root. As in Rust 2015 code, the `self::` +and `super::` prefixes refer to the current and parent modules respectively. Also verify that you didn't misspell the import name and that the import exists in the module from where you tried to import it. Example: @@ -38,8 +38,8 @@ use core::any; # fn main() {} ``` -In Rust 2018 the `extern crate` declaration is not required and you can instead -just `use` it: +Since Rust 2018 the `extern crate` declaration is not required and +you can instead just `use` it: ```edition2018 use core::any; // No extern crate required in Rust 2018. diff --git a/compiler/rustc_error_codes/src/error_codes/E0451.md b/compiler/rustc_error_codes/src/error_codes/E0451.md index 821073fe16..a12378a206 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0451.md +++ b/compiler/rustc_error_codes/src/error_codes/E0451.md @@ -3,14 +3,14 @@ A struct constructor with private fields was invoked. Erroneous code example: ```compile_fail,E0451 -mod Bar { +mod bar { pub struct Foo { pub a: isize, b: isize, } } -let f = Bar::Foo{ a: 0, b: 0 }; // error: field `b` of struct `Bar::Foo` +let f = bar::Foo{ a: 0, b: 0 }; // error: field `b` of struct `bar::Foo` // is private ``` @@ -18,20 +18,20 @@ To fix this error, please ensure that all the fields of the struct are public, or implement a function for easy instantiation. Examples: ``` -mod Bar { +mod bar { pub struct Foo { pub a: isize, pub b: isize, // we set `b` field public } } -let f = Bar::Foo{ a: 0, b: 0 }; // ok! +let f = bar::Foo{ a: 0, b: 0 }; // ok! ``` Or: ``` -mod Bar { +mod bar { pub struct Foo { pub a: isize, b: isize, // still private @@ -44,5 +44,5 @@ mod Bar { } } -let f = Bar::Foo::new(); // ok! +let f = bar::Foo::new(); // ok! ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0455.md b/compiler/rustc_error_codes/src/error_codes/E0455.md index 84689b3ece..437dacaff2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0455.md +++ b/compiler/rustc_error_codes/src/error_codes/E0455.md @@ -1,6 +1,11 @@ +Some linking kinds are target-specific and not supported on all platforms. + Linking with `kind=framework` is only supported when targeting macOS, as frameworks are specific to that operating system. +Similarly, `kind=raw-dylib` is only supported when targeting Windows-like +platforms. + Erroneous code example: ```ignore (should-compile_fail-but-cannot-doctest-conditionally-without-macos) diff --git a/compiler/rustc_error_codes/src/error_codes/E0458.md b/compiler/rustc_error_codes/src/error_codes/E0458.md index 359aeb6fd9..1b280cba44 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0458.md +++ b/compiler/rustc_error_codes/src/error_codes/E0458.md @@ -12,3 +12,4 @@ Please specify a valid "kind" value, from one of the following: * static * dylib * framework +* raw-dylib diff --git a/compiler/rustc_error_codes/src/error_codes/E0477.md b/compiler/rustc_error_codes/src/error_codes/E0477.md index 9cfefb1de6..c6be8dc705 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0477.md +++ b/compiler/rustc_error_codes/src/error_codes/E0477.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + The type does not fulfill the required lifetime. Erroneous code example: -```compile_fail,E0477 +```compile_fail use std::sync::Mutex; struct MyString<'a> { diff --git a/compiler/rustc_error_codes/src/error_codes/E0495.md b/compiler/rustc_error_codes/src/error_codes/E0495.md index f956237b80..cd10e71931 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0495.md +++ b/compiler/rustc_error_codes/src/error_codes/E0495.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + A lifetime cannot be determined in the given situation. Erroneous code example: -```compile_fail,E0495 +```compile_fail fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { match (&t,) { // error! ((u,),) => u, diff --git a/compiler/rustc_error_codes/src/error_codes/E0574.md b/compiler/rustc_error_codes/src/error_codes/E0574.md index 8154d5b782..4881f61d0b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0574.md +++ b/compiler/rustc_error_codes/src/error_codes/E0574.md @@ -4,9 +4,9 @@ expected. Erroneous code example: ```compile_fail,E0574 -mod Mordor {} +mod mordor {} -let sauron = Mordor { x: () }; // error! +let sauron = mordor { x: () }; // error! enum Jak { Daxter { i: isize }, @@ -19,17 +19,17 @@ match eco { ``` In all these errors, a type was expected. For example, in the first error, -we tried to instantiate the `Mordor` module, which is impossible. If you want +we tried to instantiate the `mordor` module, which is impossible. If you want to instantiate a type inside a module, you can do it as follow: ``` -mod Mordor { +mod mordor { pub struct TheRing { pub x: usize, } } -let sauron = Mordor::TheRing { x: 1 }; // ok! +let sauron = mordor::TheRing { x: 1 }; // ok! ``` In the second error, we tried to bind the `Jak` enum directly, which is not diff --git a/compiler/rustc_error_codes/src/error_codes/E0577.md b/compiler/rustc_error_codes/src/error_codes/E0577.md index 1feb9c0acf..eba2d3b141 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0577.md +++ b/compiler/rustc_error_codes/src/error_codes/E0577.md @@ -11,13 +11,13 @@ fn main() {} ``` `Sea` is not a module, therefore it is invalid to use it in a visibility path. -To fix this error we need to ensure `Sea` is a module. +To fix this error we need to ensure `sea` is a module. Please note that the visibility scope can only be applied on ancestors! ```edition2018 -pub mod Sea { - pub (in crate::Sea) struct Shark; // ok! +pub mod sea { + pub (in crate::sea) struct Shark; // ok! } fn main() {} diff --git a/compiler/rustc_error_codes/src/error_codes/E0603.md b/compiler/rustc_error_codes/src/error_codes/E0603.md index 69fefce390..eb293118ac 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0603.md +++ b/compiler/rustc_error_codes/src/error_codes/E0603.md @@ -3,13 +3,13 @@ A private item was used outside its scope. Erroneous code example: ```compile_fail,E0603 -mod SomeModule { +mod foo { const PRIVATE: u32 = 0x_a_bad_1dea_u32; // This const is private, so we // can't use it outside of the - // `SomeModule` module. + // `foo` module. } -println!("const value: {}", SomeModule::PRIVATE); // error: constant `PRIVATE` +println!("const value: {}", foo::PRIVATE); // error: constant `PRIVATE` // is private ``` @@ -17,10 +17,10 @@ In order to fix this error, you need to make the item public by using the `pub` keyword. Example: ``` -mod SomeModule { +mod foo { pub const PRIVATE: u32 = 0x_a_bad_1dea_u32; // We set it public by using the // `pub` keyword. } -println!("const value: {}", SomeModule::PRIVATE); // ok! +println!("const value: {}", foo::PRIVATE); // ok! ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0623.md b/compiler/rustc_error_codes/src/error_codes/E0623.md index 1290edd0a0..34db641bb9 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0623.md +++ b/compiler/rustc_error_codes/src/error_codes/E0623.md @@ -3,39 +3,70 @@ A lifetime didn't match what was expected. Erroneous code example: ```compile_fail,E0623 -struct Foo<'a> { - x: &'a isize, -} +struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>) +where + T: Convert<'a, 'b>; -fn bar<'short, 'long>(c: Foo<'short>, l: &'long isize) { - let _: Foo<'long> = c; // error! +trait Convert<'a, 'b>: Sized { + fn cast(&'a self) -> &'b Self; +} +impl<'long: 'short, 'short, T> Convert<'long, 'short> for T { + fn cast(&'long self) -> &'short T { + self + } +} +// error +fn badboi<'in_, 'out, T>( + x: Foo<'in_, 'out, T>, + sadness: &'in_ T +) -> &'out T { + sadness.cast() } ``` In this example, we tried to set a value with an incompatible lifetime to -another one (`'long` is unrelated to `'short`). We can solve this issue in +another one (`'in_` is unrelated to `'out`). We can solve this issue in two different ways: -Either we make `'short` live at least as long as `'long`: +Either we make `'in_` live at least as long as `'out`: ``` -struct Foo<'a> { - x: &'a isize, -} +struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>) +where + T: Convert<'a, 'b>; -// we set 'short to live at least as long as 'long -fn bar<'short: 'long, 'long>(c: Foo<'short>, l: &'long isize) { - let _: Foo<'long> = c; // ok! +trait Convert<'a, 'b>: Sized { + fn cast(&'a self) -> &'b Self; +} +impl<'long: 'short, 'short, T> Convert<'long, 'short> for T { + fn cast(&'long self) -> &'short T { + self + } +} +fn badboi<'in_: 'out, 'out, T>( + x: Foo<'in_, 'out, T>, + sadness: &'in_ T +) -> &'out T { + sadness.cast() } ``` Or we use only one lifetime: ``` -struct Foo<'a> { - x: &'a isize, +struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>) +where + T: Convert<'a, 'b>; + +trait Convert<'a, 'b>: Sized { + fn cast(&'a self) -> &'b Self; +} +impl<'long: 'short, 'short, T> Convert<'long, 'short> for T { + fn cast(&'long self) -> &'short T { + self + } } -fn bar<'short>(c: Foo<'short>, l: &'short isize) { - let _: Foo<'short> = c; // ok! +fn badboi<'out, T>(x: Foo<'out, 'out, T>, sadness: &'out T) -> &'out T { + sadness.cast() } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0632.md b/compiler/rustc_error_codes/src/error_codes/E0632.md index 40840e894d..7e0a5c71f5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0632.md +++ b/compiler/rustc_error_codes/src/error_codes/E0632.md @@ -1,9 +1,11 @@ +#### Note: this error code is no longer emitted by the compiler. + An explicit generic argument was provided when calling a function that uses `impl Trait` in argument position. Erroneous code example: -```compile_fail,E0632 +```ignore (no longer an error) fn foo(a: T, b: impl Clone) {} foo::(0i32, "abc".to_string()); diff --git a/compiler/rustc_error_codes/src/error_codes/E0713.md b/compiler/rustc_error_codes/src/error_codes/E0713.md index 9361046943..9b1b77f3bc 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0713.md +++ b/compiler/rustc_error_codes/src/error_codes/E0713.md @@ -4,8 +4,6 @@ lifetime of a type that implements the `Drop` trait. Erroneous code example: ```compile_fail,E0713 -#![feature(nll)] - pub struct S<'a> { data: &'a mut String } impl<'a> Drop for S<'a> { diff --git a/compiler/rustc_error_codes/src/error_codes/E0742.md b/compiler/rustc_error_codes/src/error_codes/E0742.md index fed9f1f4ce..e10c1639dd 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0742.md +++ b/compiler/rustc_error_codes/src/error_codes/E0742.md @@ -4,18 +4,18 @@ item. Erroneous code example: ```compile_fail,E0742,edition2018 -pub mod Sea {} +pub mod sea {} -pub (in crate::Sea) struct Shark; // error! +pub (in crate::sea) struct Shark; // error! fn main() {} ``` -To fix this error, we need to move the `Shark` struct inside the `Sea` module: +To fix this error, we need to move the `Shark` struct inside the `sea` module: ```edition2018 -pub mod Sea { - pub (in crate::Sea) struct Shark; // ok! +pub mod sea { + pub (in crate::sea) struct Shark; // ok! } fn main() {} @@ -25,9 +25,9 @@ Of course, you can do it as long as the module you're referring to is an ancestor: ```edition2018 -pub mod Earth { - pub mod Sea { - pub (in crate::Earth) struct Shark; // ok! +pub mod earth { + pub mod sea { + pub (in crate::earth) struct Shark; // ok! } } diff --git a/compiler/rustc_error_codes/src/error_codes/E0759.md b/compiler/rustc_error_codes/src/error_codes/E0759.md index 6b16a7d415..ce5d42b3c7 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0759.md +++ b/compiler/rustc_error_codes/src/error_codes/E0759.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + Return type involving a trait did not require `'static` lifetime. Erroneous code examples: -```compile_fail,E0759 +```compile_fail use std::fmt::Debug; fn foo(x: &i32) -> impl Debug { // error! diff --git a/compiler/rustc_error_codes/src/error_codes/E0772.md b/compiler/rustc_error_codes/src/error_codes/E0772.md index 3b73abaf77..5ffffd5112 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0772.md +++ b/compiler/rustc_error_codes/src/error_codes/E0772.md @@ -1,9 +1,11 @@ +#### Note: this error code is no longer emitted by the compiler. + A trait object has some specific lifetime `'1`, but it was used in a way that requires it to have a `'static` lifetime. Example of erroneous code: -```compile_fail,E0772 +```compile_fail trait BooleanLike {} trait Person {} diff --git a/compiler/rustc_error_codes/src/error_codes/E0788.md b/compiler/rustc_error_codes/src/error_codes/E0788.md new file mode 100644 index 0000000000..d26f9b5945 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0788.md @@ -0,0 +1,26 @@ +A `#[no_coverage]` attribute was applied to something which does not show up +in code coverage, or is too granular to be excluded from the coverage report. + +For now, this attribute can only be applied to function, method, and closure +definitions. In the future, it may be added to statements, blocks, and +expressions, and for the time being, using this attribute in those places +will just emit an `unused_attributes` lint instead of this error. + +Example of erroneous code: + +```compile_fail,E0788 +#[no_coverage] +struct Foo; + +#[no_coverage] +const FOO: Foo = Foo; +``` + +`#[no_coverage]` tells the compiler to not generate coverage instrumentation for +a piece of code when the `-C instrument-coverage` flag is passed. Things like +structs and consts are not coverable code, and thus cannot do anything with this +attribute. + +If you wish to apply this attribute to all methods in an impl or module, +manually annotate each method; it is not possible to annotate the entire impl +with a `#[no_coverage]` attribute. diff --git a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl new file mode 100644 index 0000000000..1d3e33c818 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl @@ -0,0 +1,5 @@ +builtin-macros-requires-cfg-pattern = + macro requires a cfg-pattern as an argument + .label = cfg-pattern required + +builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 3143b81b60..076b1b1cae 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -5,3 +5,30 @@ parser-struct-literal-body-without-path = parser-maybe-report-ambiguous-plus = ambiguous `+` in a type .suggestion = use parentheses to disambiguate + +parser-maybe-recover-from-bad-type-plus = + expected a path on the left-hand side of `+`, not `{$ty}` + +parser-add-paren = try adding parentheses + +parser-forgot-paren = perhaps you forgot parentheses? + +parser-expect-path = expected a path + +parser-maybe-recover-from-bad-qpath-stage-2 = + missing angle brackets in associated item path + .suggestion = try: `{$ty}` + +parser-incorrect-semicolon = + expected item, found `;` + .suggestion = remove this semicolon + .help = {$name} declarations are not followed by a semicolon + +parser-incorrect-use-of-await = + incorrect use of `await` + .parentheses-suggestion = `await` is not a method call, remove the parentheses + .postfix-suggestion = `await` is a postfix operation + +parser-in-in-typo = + expected iterable, found keyword `in` + .suggestion = remove the duplicated `in` diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl index 95b348ec61..c61735a57e 100644 --- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl @@ -95,12 +95,6 @@ typeck-expected-return-type = expected `{$expected}` because of return type typeck-unconstrained-opaque-type = unconstrained opaque type .note = `{$name}` must be used in combination with a concrete type within the same module -typeck-explicit-generic-args-with-impl-trait = - cannot provide explicit generic arguments when `impl Trait` is used in argument position - .label = explicit generic argument not allowed - .note = see issue #83701 for more information - .help = add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable - typeck-missing-type-params = the type {$parameterCount -> [one] parameter diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index e1e0ed7222..7211c05432 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,12 +1,12 @@ #![feature(let_chains)] #![feature(once_cell)] -#![feature(path_try_exists)] +#![feature(rustc_attrs)] #![feature(type_alias_impl_trait)] use fluent_bundle::FluentResource; use fluent_syntax::parser::ParserError; use rustc_data_structures::sync::Lrc; -use rustc_macros::{Decodable, Encodable}; +use rustc_macros::{fluent_messages, Decodable, Encodable}; use rustc_span::Span; use std::borrow::Cow; use std::error::Error; @@ -17,9 +17,9 @@ use std::path::{Path, PathBuf}; use tracing::{instrument, trace}; #[cfg(not(parallel_compiler))] -use std::lazy::Lazy; +use std::cell::LazyCell as Lazy; #[cfg(parallel_compiler)] -use std::lazy::SyncLazy as Lazy; +use std::sync::LazyLock as Lazy; #[cfg(parallel_compiler)] use intl_memoizer::concurrent::IntlLangMemoizer; @@ -29,8 +29,14 @@ use intl_memoizer::IntlLangMemoizer; pub use fluent_bundle::{FluentArgs, FluentError, FluentValue}; pub use unic_langid::{langid, LanguageIdentifier}; -pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = - &[include_str!("../locales/en-US/typeck.ftl"), include_str!("../locales/en-US/parser.ftl")]; +// Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module. +fluent_messages! { + parser => "../locales/en-US/parser.ftl", + typeck => "../locales/en-US/typeck.ftl", + builtin_macros => "../locales/en-US/builtin_macros.ftl", +} + +pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; pub type FluentBundle = fluent_bundle::bundle::FluentBundle; @@ -229,11 +235,55 @@ pub fn fallback_fluent_bundle( /// Identifier for the Fluent message/attribute corresponding to a diagnostic message. type FluentId = Cow<'static, str>; +/// Abstraction over a message in a subdiagnostic (i.e. label, note, help, etc) to support both +/// translatable and non-translatable diagnostic messages. +/// +/// Translatable messages for subdiagnostics are typically attributes attached to a larger Fluent +/// message so messages of this type must be combined with a `DiagnosticMessage` (using +/// `DiagnosticMessage::with_subdiagnostic_message`) before rendering. However, subdiagnostics from +/// the `SessionSubdiagnostic` derive refer to Fluent identifiers directly. +#[rustc_diagnostic_item = "SubdiagnosticMessage"] +pub enum SubdiagnosticMessage { + /// Non-translatable diagnostic message. + // FIXME(davidtwco): can a `Cow<'static, str>` be used here? + Str(String), + /// Identifier of a Fluent message. Instances of this variant are generated by the + /// `SessionSubdiagnostic` derive. + FluentIdentifier(FluentId), + /// Attribute of a Fluent message. Needs to be combined with a Fluent identifier to produce an + /// actual translated message. Instances of this variant are generated by the `fluent_messages` + /// macro. + /// + /// + FluentAttr(FluentId), +} + +impl SubdiagnosticMessage { + /// Create a `SubdiagnosticMessage` for the provided Fluent attribute. + pub fn attr(id: impl Into) -> Self { + SubdiagnosticMessage::FluentAttr(id.into()) + } + + /// Create a `SubdiagnosticMessage` for the provided Fluent identifier. + pub fn message(id: impl Into) -> Self { + SubdiagnosticMessage::FluentIdentifier(id.into()) + } +} + +/// `From` impl that enables existing diagnostic calls to functions which now take +/// `impl Into` to continue to work as before. +impl> From for SubdiagnosticMessage { + fn from(s: S) -> Self { + SubdiagnosticMessage::Str(s.into()) + } +} + /// Abstraction over a message in a diagnostic to support both translatable and non-translatable /// diagnostic messages. /// /// Intended to be removed once diagnostics are entirely translatable. #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] +#[rustc_diagnostic_item = "DiagnosticMessage"] pub enum DiagnosticMessage { /// Non-translatable diagnostic message. // FIXME(davidtwco): can a `Cow<'static, str>` be used here? @@ -247,6 +297,29 @@ pub enum DiagnosticMessage { } impl DiagnosticMessage { + /// Given a `SubdiagnosticMessage` which may contain a Fluent attribute, create a new + /// `DiagnosticMessage` that combines that attribute with the Fluent identifier of `self`. + /// + /// - If the `SubdiagnosticMessage` is non-translatable then return the message as a + /// `DiagnosticMessage`. + /// - If `self` is non-translatable then return `self`'s message. + pub fn with_subdiagnostic_message(&self, sub: SubdiagnosticMessage) -> Self { + let attr = match sub { + SubdiagnosticMessage::Str(s) => return DiagnosticMessage::Str(s.clone()), + SubdiagnosticMessage::FluentIdentifier(id) => { + return DiagnosticMessage::FluentIdentifier(id, None); + } + SubdiagnosticMessage::FluentAttr(attr) => attr, + }; + + match self { + DiagnosticMessage::Str(s) => DiagnosticMessage::Str(s.clone()), + DiagnosticMessage::FluentIdentifier(id, _) => { + DiagnosticMessage::FluentIdentifier(id.clone(), Some(attr)) + } + } + } + /// Returns the `String` contained within the `DiagnosticMessage::Str` variant, assuming that /// this diagnostic message is of the legacy, non-translatable variety. Panics if this /// assumption does not hold. @@ -261,14 +334,9 @@ impl DiagnosticMessage { } /// Create a `DiagnosticMessage` for the provided Fluent identifier. - pub fn fluent(id: impl Into) -> Self { + pub fn new(id: impl Into) -> Self { DiagnosticMessage::FluentIdentifier(id.into(), None) } - - /// Create a `DiagnosticMessage` for the provided Fluent identifier and attribute. - pub fn fluent_attr(id: impl Into, attr: impl Into) -> Self { - DiagnosticMessage::FluentIdentifier(id.into(), Some(attr.into())) - } } /// `From` impl that enables existing diagnostic calls to functions which now take diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 5f91998289..8955762605 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -19,6 +19,8 @@ atty = "0.2" termcolor = "1.0" annotate-snippets = "0.8.0" termize = "0.1.1" +serde = { version = "1.0.125", features = ["derive"] } +serde_json = "1.0.59" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] } diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 1f270fcf56..0fcd61d1e5 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -87,7 +87,7 @@ fn annotation_type_for_level(level: Level) -> AnnotationType { Level::Bug | Level::DelayedBug | Level::Fatal | Level::Error { .. } => { AnnotationType::Error } - Level::Warning => AnnotationType::Warning, + Level::Warning(_) => AnnotationType::Warning, Level::Note | Level::OnceNote => AnnotationType::Note, Level::Help => AnnotationType::Help, // FIXME(#59346): Not sure how to map this level diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 909ed566f6..b8545139ce 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1,7 +1,7 @@ use crate::snippet::Style; use crate::{ - CodeSuggestion, DiagnosticMessage, Level, MultiSpan, Substitution, SubstitutionPart, - SuggestionStyle, + CodeSuggestion, DiagnosticMessage, Level, MultiSpan, SubdiagnosticMessage, Substitution, + SubstitutionPart, SuggestionStyle, }; use rustc_data_structures::stable_map::FxHashMap; use rustc_error_messages::FluentValue; @@ -80,6 +80,7 @@ impl<'source> Into> for DiagnosticArgValue<'source> { /// Trait implemented by error types. This should not be implemented manually. Instead, use /// `#[derive(SessionSubdiagnostic)]` -- see [rustc_macros::SessionSubdiagnostic]. +#[rustc_diagnostic_item = "AddSubdiagnostic"] pub trait AddSubdiagnostic { /// Add a subdiagnostic to an existing diagnostic. fn add_to_diagnostic(self, diag: &mut Diagnostic); @@ -90,7 +91,7 @@ pub trait AddSubdiagnostic { pub struct Diagnostic { // NOTE(eddyb) this is private to disallow arbitrary after-the-fact changes, // outside of what methods in this crate themselves allow. - crate level: Level, + pub(crate) level: Level, pub message: Vec<(DiagnosticMessage, Style)>, pub code: Option, @@ -208,7 +209,7 @@ impl Diagnostic { | Level::Error { .. } | Level::FailureNote => true, - Level::Warning + Level::Warning(_) | Level::Note | Level::OnceNote | Level::Help @@ -221,7 +222,9 @@ impl Diagnostic { &mut self, unstable_to_stable: &FxHashMap, ) { - if let Level::Expect(expectation_id) = &mut self.level { + if let Level::Expect(expectation_id) | Level::Warning(Some(expectation_id)) = + &mut self.level + { if expectation_id.is_stable() { return; } @@ -283,8 +286,9 @@ impl Diagnostic { /// /// This span is *not* considered a ["primary span"][`MultiSpan`]; only /// the `Span` supplied when creating the diagnostic is primary. - pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { - self.span.push_span_label(span, label.into()); + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] + pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { + self.span.push_span_label(span, self.subdiagnostic_message_to_diagnostic_message(label)); self } @@ -401,12 +405,13 @@ impl Diagnostic { } /// Add a note attached to this diagnostic. - pub fn note(&mut self, msg: impl Into) -> &mut Self { + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] + pub fn note(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Note, msg, MultiSpan::new(), None); self } - pub fn highlighted_note>( + pub fn highlighted_note>( &mut self, msg: Vec<(M, Style)>, ) -> &mut Self { @@ -416,17 +421,18 @@ impl Diagnostic { /// Prints the span with a note above it. /// This is like [`Diagnostic::note()`], but it gets its own span. - pub fn note_once(&mut self, msg: impl Into) -> &mut Self { + pub fn note_once(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::OnceNote, msg, MultiSpan::new(), None); self } /// Prints the span with a note above it. /// This is like [`Diagnostic::note()`], but it gets its own span. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_note>( &mut self, sp: S, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::Note, msg, sp.into(), None); self @@ -437,31 +443,34 @@ impl Diagnostic { pub fn span_note_once>( &mut self, sp: S, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::OnceNote, msg, sp.into(), None); self } /// Add a warning attached to this diagnostic. - pub fn warn(&mut self, msg: impl Into) -> &mut Self { - self.sub(Level::Warning, msg, MultiSpan::new(), None); + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] + pub fn warn(&mut self, msg: impl Into) -> &mut Self { + self.sub(Level::Warning(None), msg, MultiSpan::new(), None); self } /// Prints the span with a warning above it. /// This is like [`Diagnostic::warn()`], but it gets its own span. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_warn>( &mut self, sp: S, - msg: impl Into, + msg: impl Into, ) -> &mut Self { - self.sub(Level::Warning, msg, sp.into(), None); + self.sub(Level::Warning(None), msg, sp.into(), None); self } /// Add a help message attached to this diagnostic. - pub fn help(&mut self, msg: impl Into) -> &mut Self { + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] + pub fn help(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Help, msg, MultiSpan::new(), None); self } @@ -474,10 +483,11 @@ impl Diagnostic { /// Prints the span with some help above it. /// This is like [`Diagnostic::help()`], but it gets its own span. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_help>( &mut self, sp: S, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::Help, msg, sp.into(), None); self @@ -514,7 +524,7 @@ impl Diagnostic { /// In other words, multiple changes need to be applied as part of this suggestion. pub fn multipart_suggestion( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -530,7 +540,7 @@ impl Diagnostic { /// In other words, multiple changes need to be applied as part of this suggestion. pub fn multipart_suggestion_verbose( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -544,7 +554,7 @@ impl Diagnostic { /// [`Diagnostic::multipart_suggestion()`] but you can set the [`SuggestionStyle`]. pub fn multipart_suggestion_with_style( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, style: SuggestionStyle, @@ -557,7 +567,7 @@ impl Diagnostic { .map(|(span, snippet)| SubstitutionPart { snippet, span }) .collect(), }], - msg: msg.into(), + msg: self.subdiagnostic_message_to_diagnostic_message(msg), style, applicability, }); @@ -572,7 +582,7 @@ impl Diagnostic { /// improve understandability. pub fn tool_only_multipart_suggestion( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -584,7 +594,7 @@ impl Diagnostic { .map(|(span, snippet)| SubstitutionPart { snippet, span }) .collect(), }], - msg: msg.into(), + msg: self.subdiagnostic_message_to_diagnostic_message(msg), style: SuggestionStyle::CompletelyHidden, applicability, }); @@ -611,7 +621,7 @@ impl Diagnostic { pub fn span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -629,7 +639,7 @@ impl Diagnostic { pub fn span_suggestion_with_style( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, style: SuggestionStyle, @@ -638,7 +648,7 @@ impl Diagnostic { substitutions: vec![Substitution { parts: vec![SubstitutionPart { snippet: suggestion.to_string(), span: sp }], }], - msg: msg.into(), + msg: self.subdiagnostic_message_to_diagnostic_message(msg), style, applicability, }); @@ -649,7 +659,7 @@ impl Diagnostic { pub fn span_suggestion_verbose( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -668,7 +678,7 @@ impl Diagnostic { pub fn span_suggestions( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestions: impl Iterator, applicability: Applicability, ) -> &mut Self { @@ -680,7 +690,7 @@ impl Diagnostic { .collect(); self.push_suggestion(CodeSuggestion { substitutions, - msg: msg.into(), + msg: self.subdiagnostic_message_to_diagnostic_message(msg), style: SuggestionStyle::ShowCode, applicability, }); @@ -691,7 +701,7 @@ impl Diagnostic { /// See also [`Diagnostic::span_suggestion()`]. pub fn multipart_suggestions( &mut self, - msg: impl Into, + msg: impl Into, suggestions: impl Iterator>, applicability: Applicability, ) -> &mut Self { @@ -704,7 +714,7 @@ impl Diagnostic { .collect(), }) .collect(), - msg: msg.into(), + msg: self.subdiagnostic_message_to_diagnostic_message(msg), style: SuggestionStyle::ShowCode, applicability, }); @@ -717,7 +727,7 @@ impl Diagnostic { pub fn span_suggestion_short( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -740,7 +750,7 @@ impl Diagnostic { pub fn span_suggestion_hidden( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -761,7 +771,7 @@ impl Diagnostic { pub fn tool_only_span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -827,10 +837,22 @@ impl Diagnostic { self } - pub fn styled_message(&self) -> &Vec<(DiagnosticMessage, Style)> { + pub fn styled_message(&self) -> &[(DiagnosticMessage, Style)] { &self.message } + /// Helper function that takes a `SubdiagnosticMessage` and returns a `DiagnosticMessage` by + /// combining it with the primary message of the diagnostic (if translatable, otherwise it just + /// passes the user's string along). + fn subdiagnostic_message_to_diagnostic_message( + &self, + attr: impl Into, + ) -> DiagnosticMessage { + let msg = + self.message.iter().map(|(msg, _)| msg).next().expect("diagnostic with no messages"); + msg.with_subdiagnostic_message(attr.into()) + } + /// Convenience function for internal use, clients should use one of the /// public methods above. /// @@ -838,13 +860,16 @@ impl Diagnostic { pub fn sub( &mut self, level: Level, - message: impl Into, + message: impl Into, span: MultiSpan, render_span: Option, ) { let sub = SubDiagnostic { level, - message: vec![(message.into(), Style::NoStyle)], + message: vec![( + self.subdiagnostic_message_to_diagnostic_message(message), + Style::NoStyle, + )], span, render_span, }; @@ -853,14 +878,17 @@ impl Diagnostic { /// Convenience function for internal use, clients should use one of the /// public methods above. - fn sub_with_highlights>( + fn sub_with_highlights>( &mut self, level: Level, mut message: Vec<(M, Style)>, span: MultiSpan, render_span: Option, ) { - let message = message.drain(..).map(|m| (m.0.into(), m.1)).collect(); + let message = message + .drain(..) + .map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.0), m.1)) + .collect(); let sub = SubDiagnostic { level, message, span, render_span }; self.children.push(sub); } @@ -870,11 +898,11 @@ impl Diagnostic { &self, ) -> ( &Level, - &Vec<(DiagnosticMessage, Style)>, + &[(DiagnosticMessage, Style)], &Option, &MultiSpan, &Result, SuggestionsDisabled>, - Option<&Vec>, + Option<&[SubDiagnostic]>, ) { ( &self.level, diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 53ad6e5a0e..9e0a99849a 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -1,5 +1,8 @@ use crate::diagnostic::IntoDiagnosticArg; -use crate::{Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed}; +use crate::{ + Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed, + SubdiagnosticMessage, +}; use crate::{Handler, Level, MultiSpan, StashKey}; use rustc_lint_defs::Applicability; @@ -88,7 +91,7 @@ mod sealed_level_is_error { use crate::Level; /// Sealed helper trait for statically checking that a `Level` is an error. - crate trait IsError {} + pub(crate) trait IsError {} impl IsError<{ Level::Bug }> for () {} impl IsError<{ Level::DelayedBug }> for () {} @@ -101,7 +104,7 @@ mod sealed_level_is_error { impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. - crate fn new_guaranteeing_error, const L: Level>( + pub(crate) fn new_guaranteeing_error, const L: Level>( handler: &'a Handler, message: M, ) -> Self @@ -168,7 +171,7 @@ impl EmissionGuarantee for ErrorGuaranteed { impl<'a> DiagnosticBuilder<'a, ()> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. - crate fn new>( + pub(crate) fn new>( handler: &'a Handler, level: Level, message: M, @@ -179,7 +182,7 @@ impl<'a> DiagnosticBuilder<'a, ()> { /// Creates a new `DiagnosticBuilder` with an already constructed /// diagnostic. - crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self { + pub(crate) fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self { debug!("Created new diagnostic"); Self { inner: DiagnosticBuilderInner { @@ -210,14 +213,14 @@ impl EmissionGuarantee for () { impl<'a> DiagnosticBuilder<'a, !> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. - crate fn new_fatal(handler: &'a Handler, message: impl Into) -> Self { + pub(crate) fn new_fatal(handler: &'a Handler, message: impl Into) -> Self { let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message); Self::new_diagnostic_fatal(handler, diagnostic) } /// Creates a new `DiagnosticBuilder` with an already constructed /// diagnostic. - crate fn new_diagnostic_fatal(handler: &'a Handler, diagnostic: Diagnostic) -> Self { + pub(crate) fn new_diagnostic_fatal(handler: &'a Handler, diagnostic: Diagnostic) -> Self { debug!("Created new diagnostic"); Self { inner: DiagnosticBuilderInner { @@ -395,7 +398,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { /// the diagnostic was constructed. However, the label span is *not* considered a /// ["primary span"][`MultiSpan`]; only the `Span` supplied when creating the diagnostic is /// primary. - pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self); + pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self); forward!( /// Labels all the given spans with the provided label. @@ -430,25 +433,29 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { found: DiagnosticStyledString, ) -> &mut Self); - forward!(pub fn note(&mut self, msg: impl Into) -> &mut Self); - forward!(pub fn note_once(&mut self, msg: impl Into) -> &mut Self); + forward!(pub fn note(&mut self, msg: impl Into) -> &mut Self); + forward!(pub fn note_once(&mut self, msg: impl Into) -> &mut Self); forward!(pub fn span_note( &mut self, sp: impl Into, - msg: impl Into, + msg: impl Into, ) -> &mut Self); forward!(pub fn span_note_once( &mut self, sp: impl Into, - msg: impl Into, + msg: impl Into, ) -> &mut Self); - forward!(pub fn warn(&mut self, msg: impl Into) -> &mut Self); - forward!(pub fn span_warn(&mut self, sp: impl Into, msg: &str) -> &mut Self); - forward!(pub fn help(&mut self, msg: impl Into) -> &mut Self); + forward!(pub fn warn(&mut self, msg: impl Into) -> &mut Self); + forward!(pub fn span_warn( + &mut self, + sp: impl Into, + msg: impl Into, + ) -> &mut Self); + forward!(pub fn help(&mut self, msg: impl Into) -> &mut Self); forward!(pub fn span_help( &mut self, sp: impl Into, - msg: impl Into, + msg: impl Into, ) -> &mut Self); forward!(pub fn help_use_latest_edition(&mut self,) -> &mut Self); forward!(pub fn set_is_lint(&mut self,) -> &mut Self); @@ -457,67 +464,67 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { forward!(pub fn multipart_suggestion( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self); forward!(pub fn multipart_suggestion_verbose( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self); forward!(pub fn tool_only_multipart_suggestion( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestions( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestions: impl Iterator, applicability: Applicability, ) -> &mut Self); forward!(pub fn multipart_suggestions( &mut self, - msg: impl Into, + msg: impl Into, suggestions: impl Iterator>, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestion_short( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestion_verbose( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestion_hidden( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self); forward!(pub fn tool_only_span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self); diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 5dd743e8d0..a4cbc73978 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -10,7 +10,7 @@ use Destination::*; use rustc_span::source_map::SourceMap; -use rustc_span::{SourceFile, Span}; +use rustc_span::{FileLines, SourceFile, Span}; use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString}; use crate::styled_buffer::StyledBuffer; @@ -771,8 +771,12 @@ impl EmitterWriter { self } - fn maybe_anonymized(&self, line_num: usize) -> String { - if self.ui_testing { ANONYMIZED_LINE_NUM.to_string() } else { line_num.to_string() } + fn maybe_anonymized(&self, line_num: usize) -> Cow<'static, str> { + if self.ui_testing { + Cow::Borrowed(ANONYMIZED_LINE_NUM) + } else { + Cow::Owned(line_num.to_string()) + } } fn draw_line( @@ -819,7 +823,7 @@ impl EmitterWriter { } buffer.puts(line_offset, 0, &self.maybe_anonymized(line_index), Style::LineNumber); - draw_col_separator(buffer, line_offset, width_offset - 2); + draw_col_separator_no_space(buffer, line_offset, width_offset - 2); } fn render_source_line( @@ -1261,16 +1265,23 @@ impl EmitterWriter { return 0; }; + let will_be_emitted = |span: Span| { + !span.is_dummy() && { + let file = sm.lookup_source_file(span.hi()); + sm.ensure_source_file_source_present(file) + } + }; + let mut max = 0; for primary_span in msp.primary_spans() { - if !primary_span.is_dummy() { + if will_be_emitted(*primary_span) { let hi = sm.lookup_char_pos(primary_span.hi()); max = (hi.line).max(max); } } if !self.short_message { for span_label in msp.span_labels() { - if !span_label.span.is_dummy() { + if will_be_emitted(span_label.span) { let hi = sm.lookup_char_pos(span_label.span.hi()); max = (hi.line).max(max); } @@ -1708,6 +1719,7 @@ impl EmitterWriter { fn emit_suggestion_default( &mut self, + span: &MultiSpan, suggestion: &CodeSuggestion, args: &FluentArgs<'_>, level: &Level, @@ -1753,12 +1765,30 @@ impl EmitterWriter { let has_deletion = parts.iter().any(|p| p.is_deletion()); let is_multiline = complete.lines().count() > 1; - enum DisplaySuggestion { - Underline, - Diff, - None, + if let Some(span) = span.primary_span() { + // Compare the primary span of the diagnostic with the span of the suggestion + // being emitted. If they belong to the same file, we don't *need* to show the + // file name, saving in verbosity, but if it *isn't* we do need it, otherwise we're + // telling users to make a change but not clarifying *where*. + let loc = sm.lookup_char_pos(parts[0].span.lo()); + if loc.file.name != sm.span_to_filename(span) && loc.file.name.is_real() { + buffer.puts(row_num - 1, 0, "--> ", Style::LineNumber); + buffer.append( + row_num - 1, + &format!( + "{}:{}:{}", + sm.filename_for_diagnostics(&loc.file.name), + sm.doctest_offset_line(&loc.file.name, loc.line), + loc.col.0 + 1, + ), + Style::LineAndColumn, + ); + for _ in 0..max_line_num_len { + buffer.prepend(row_num - 1, " ", Style::NoStyle); + } + row_num += 1; + } } - let show_code_change = if has_deletion && !is_multiline { DisplaySuggestion::Diff } else if (parts.len() != 1 || parts[0].snippet.trim() != complete.trim()) @@ -1780,7 +1810,7 @@ impl EmitterWriter { assert!(!file_lines.lines.is_empty() || parts[0].span.is_dummy()); let line_start = sm.lookup_char_pos(parts[0].span.lo()).line; - draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1); + draw_col_separator_no_space(&mut buffer, row_num - 1, max_line_num_len + 1); let mut lines = complete.lines(); if lines.clone().next().is_none() { // Account for a suggestion to completely remove a line(s) with whitespace (#94192). @@ -1807,79 +1837,94 @@ impl EmitterWriter { } row_num += line_end - line_start; } - for (line_pos, (line, highlight_parts)) in - lines.by_ref().zip(highlights).take(MAX_SUGGESTION_HIGHLIGHT_LINES).enumerate() - { - // Print the span column to avoid confusion - buffer.puts( - row_num, - 0, - &self.maybe_anonymized(line_start + line_pos), - Style::LineNumber, - ); - if let DisplaySuggestion::Diff = show_code_change { - // Add the line number for both addition and removal to drive the point home. - // - // N - fn foo(bar: A) { - // N + fn foo(bar: impl T) { - buffer.puts( - row_num - 1, - 0, - &self.maybe_anonymized(line_start + line_pos), - Style::LineNumber, - ); - buffer.puts(row_num - 1, max_line_num_len + 1, "- ", Style::Removal); - buffer.puts( - row_num - 1, - max_line_num_len + 3, - &normalize_whitespace( - &*file_lines - .file - .get_line(file_lines.lines[line_pos].line_index) - .unwrap(), - ), - Style::NoStyle, - ); - buffer.puts(row_num, max_line_num_len + 1, "+ ", Style::Addition); - } else if is_multiline { - match &highlight_parts[..] { - [SubstitutionHighlight { start: 0, end }] if *end == line.len() => { - buffer.puts(row_num, max_line_num_len + 1, "+ ", Style::Addition); - } - [] => { - draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); - } - _ => { - buffer.puts(row_num, max_line_num_len + 1, "~ ", Style::Addition); - } - } - } else { - draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); + let mut unhighlighted_lines = Vec::new(); + for (line_pos, (line, highlight_parts)) in lines.by_ref().zip(highlights).enumerate() { + debug!(%line_pos, %line, ?highlight_parts); + + // Remember lines that are not highlighted to hide them if needed + if highlight_parts.is_empty() { + unhighlighted_lines.push((line_pos, line)); + continue; } - // print the suggestion - buffer.append(row_num, &normalize_whitespace(line), Style::NoStyle); + match unhighlighted_lines.len() { + 0 => (), + // Since we show first line, "..." line and last line, + // There is no reason to hide if there are 3 or less lines + // (because then we just replace a line with ... which is + // not helpful) + n if n <= 3 => unhighlighted_lines.drain(..).for_each(|(p, l)| { + self.draw_code_line( + &mut buffer, + &mut row_num, + &Vec::new(), + p, + l, + line_start, + show_code_change, + max_line_num_len, + &file_lines, + is_multiline, + ) + }), + // Print first unhighlighted line, "..." and last unhighlighted line, like so: + // + // LL | this line was highlighted + // LL | this line is just for context + // ... + // LL | this line is just for context + // LL | this line was highlighted + _ => { + let last_line = unhighlighted_lines.pop(); + let first_line = unhighlighted_lines.drain(..).next(); + + first_line.map(|(p, l)| { + self.draw_code_line( + &mut buffer, + &mut row_num, + &Vec::new(), + p, + l, + line_start, + show_code_change, + max_line_num_len, + &file_lines, + is_multiline, + ) + }); - // Colorize addition/replacements with green. - for &SubstitutionHighlight { start, end } in highlight_parts { - // Account for tabs when highlighting (#87972). - let tabs: usize = line - .chars() - .take(start) - .map(|ch| match ch { - '\t' => 3, - _ => 0, - }) - .sum(); - buffer.set_style_range( - row_num, - max_line_num_len + 3 + start + tabs, - max_line_num_len + 3 + end + tabs, - Style::Addition, - true, - ); + buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber); + row_num += 1; + + last_line.map(|(p, l)| { + self.draw_code_line( + &mut buffer, + &mut row_num, + &Vec::new(), + p, + l, + line_start, + show_code_change, + max_line_num_len, + &file_lines, + is_multiline, + ) + }); + } } - row_num += 1; + + self.draw_code_line( + &mut buffer, + &mut row_num, + highlight_parts, + line_pos, + line, + line_start, + show_code_change, + max_line_num_len, + &file_lines, + is_multiline, + ) } // This offset and the ones below need to be signed to account for replacement code @@ -1888,7 +1933,7 @@ impl EmitterWriter { // Only show an underline in the suggestions if the suggestion is not the // entirety of the code being shown and the displayed code is not multiline. if let DisplaySuggestion::Diff | DisplaySuggestion::Underline = show_code_change { - draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); + draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1); for part in parts { let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display; let span_end_pos = sm.lookup_char_pos(part.span.hi()).col_display; @@ -2039,9 +2084,13 @@ impl EmitterWriter { ) { panic!("failed to emit error: {}", e); } - } else if let Err(e) = - self.emit_suggestion_default(sugg, args, &Level::Help, max_line_num_len) - { + } else if let Err(e) = self.emit_suggestion_default( + span, + sugg, + args, + &Level::Help, + max_line_num_len, + ) { panic!("failed to emit error: {}", e); }; } @@ -2060,6 +2109,90 @@ impl EmitterWriter { } } } + + fn draw_code_line( + &self, + buffer: &mut StyledBuffer, + row_num: &mut usize, + highlight_parts: &Vec, + line_pos: usize, + line: &str, + line_start: usize, + show_code_change: DisplaySuggestion, + max_line_num_len: usize, + file_lines: &FileLines, + is_multiline: bool, + ) { + // Print the span column to avoid confusion + buffer.puts(*row_num, 0, &self.maybe_anonymized(line_start + line_pos), Style::LineNumber); + if let DisplaySuggestion::Diff = show_code_change { + // Add the line number for both addition and removal to drive the point home. + // + // N - fn foo(bar: A) { + // N + fn foo(bar: impl T) { + buffer.puts( + *row_num - 1, + 0, + &self.maybe_anonymized(line_start + line_pos), + Style::LineNumber, + ); + buffer.puts(*row_num - 1, max_line_num_len + 1, "- ", Style::Removal); + buffer.puts( + *row_num - 1, + max_line_num_len + 3, + &normalize_whitespace( + &*file_lines.file.get_line(file_lines.lines[line_pos].line_index).unwrap(), + ), + Style::NoStyle, + ); + buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); + } else if is_multiline { + match &highlight_parts[..] { + [SubstitutionHighlight { start: 0, end }] if *end == line.len() => { + buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); + } + [] => { + draw_col_separator(buffer, *row_num, max_line_num_len + 1); + } + _ => { + buffer.puts(*row_num, max_line_num_len + 1, "~ ", Style::Addition); + } + } + } else { + draw_col_separator(buffer, *row_num, max_line_num_len + 1); + } + + // print the suggestion + buffer.append(*row_num, &normalize_whitespace(line), Style::NoStyle); + + // Colorize addition/replacements with green. + for &SubstitutionHighlight { start, end } in highlight_parts { + // Account for tabs when highlighting (#87972). + let tabs: usize = line + .chars() + .take(start) + .map(|ch| match ch { + '\t' => 3, + _ => 0, + }) + .sum(); + buffer.set_style_range( + *row_num, + max_line_num_len + 3 + start + tabs, + max_line_num_len + 3 + end + tabs, + Style::Addition, + true, + ); + } + *row_num += 1; + } +} + +#[derive(Clone, Copy)] +enum DisplaySuggestion { + Underline, + Diff, + None, } impl FileWithAnnotatedLines { diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 6ff52182d6..d4d1491c16 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -28,7 +28,7 @@ use std::path::Path; use std::sync::{Arc, Mutex}; use std::vec; -use rustc_serialize::json::{as_json, as_pretty_json}; +use serde::Serialize; #[cfg(test)] mod tests; @@ -126,9 +126,9 @@ impl Emitter for JsonEmitter { fn emit_diagnostic(&mut self, diag: &crate::Diagnostic) { let data = Diagnostic::from_errors_diagnostic(diag, self); let result = if self.pretty { - writeln!(&mut self.dst, "{}", as_pretty_json(&data)) + writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap()) } else { - writeln!(&mut self.dst, "{}", as_json(&data)) + writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap()) } .and_then(|_| self.dst.flush()); if let Err(e) = result { @@ -139,9 +139,9 @@ impl Emitter for JsonEmitter { fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) { let data = ArtifactNotification { artifact: path, emit: artifact_type }; let result = if self.pretty { - writeln!(&mut self.dst, "{}", as_pretty_json(&data)) + writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap()) } else { - writeln!(&mut self.dst, "{}", as_json(&data)) + writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap()) } .and_then(|_| self.dst.flush()); if let Err(e) = result { @@ -154,16 +154,16 @@ impl Emitter for JsonEmitter { .into_iter() .map(|mut diag| { if diag.level == crate::Level::Allow { - diag.level = crate::Level::Warning; + diag.level = crate::Level::Warning(None); } FutureBreakageItem { diagnostic: Diagnostic::from_errors_diagnostic(&diag, self) } }) .collect(); let report = FutureIncompatReport { future_incompat_report: data }; let result = if self.pretty { - writeln!(&mut self.dst, "{}", as_pretty_json(&report)) + writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&report).unwrap()) } else { - writeln!(&mut self.dst, "{}", as_json(&report)) + writeln!(&mut self.dst, "{}", serde_json::to_string(&report).unwrap()) } .and_then(|_| self.dst.flush()); if let Err(e) = result { @@ -175,9 +175,9 @@ impl Emitter for JsonEmitter { let lint_level = lint_level.as_str(); let data = UnusedExterns { lint_level, unused_extern_names: unused_externs }; let result = if self.pretty { - writeln!(&mut self.dst, "{}", as_pretty_json(&data)) + writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap()) } else { - writeln!(&mut self.dst, "{}", as_json(&data)) + writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap()) } .and_then(|_| self.dst.flush()); if let Err(e) = result { @@ -204,7 +204,7 @@ impl Emitter for JsonEmitter { // The following data types are provided just for serialisation. -#[derive(Encodable)] +#[derive(Serialize)] struct Diagnostic { /// The primary error message. message: String, @@ -218,7 +218,7 @@ struct Diagnostic { rendered: Option, } -#[derive(Encodable)] +#[derive(Serialize)] struct DiagnosticSpan { file_name: String, byte_start: u32, @@ -245,7 +245,7 @@ struct DiagnosticSpan { expansion: Option>, } -#[derive(Encodable)] +#[derive(Serialize)] struct DiagnosticSpanLine { text: String, @@ -255,7 +255,7 @@ struct DiagnosticSpanLine { highlight_end: usize, } -#[derive(Encodable)] +#[derive(Serialize)] struct DiagnosticSpanMacroExpansion { /// span where macro was applied to generate this code; note that /// this may itself derive from a macro (if @@ -269,7 +269,7 @@ struct DiagnosticSpanMacroExpansion { def_site_span: DiagnosticSpan, } -#[derive(Encodable)] +#[derive(Serialize)] struct DiagnosticCode { /// The code itself. code: String, @@ -277,7 +277,7 @@ struct DiagnosticCode { explanation: Option<&'static str>, } -#[derive(Encodable)] +#[derive(Serialize)] struct ArtifactNotification<'a> { /// The path of the artifact. artifact: &'a Path, @@ -285,12 +285,12 @@ struct ArtifactNotification<'a> { emit: &'a str, } -#[derive(Encodable)] +#[derive(Serialize)] struct FutureBreakageItem { diagnostic: Diagnostic, } -#[derive(Encodable)] +#[derive(Serialize)] struct FutureIncompatReport { future_incompat_report: Vec, } @@ -299,7 +299,7 @@ struct FutureIncompatReport { // doctest component (as well as cargo). // We could unify this struct the one in rustdoc but they have different // ownership semantics, so doing so would create wasteful allocations. -#[derive(Encodable)] +#[derive(Serialize)] struct UnusedExterns<'a, 'b, 'c> { /// The severity level of the unused dependencies lint lint_level: &'a str, diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 7eb6a4975f..d940d14e1d 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -5,12 +5,18 @@ use rustc_span::source_map::{FilePathMapping, SourceMap}; use crate::emitter::{ColorConfig, HumanReadableErrorType}; use crate::Handler; -use rustc_serialize::json; use rustc_span::{BytePos, Span}; use std::str; -#[derive(Debug, PartialEq, Eq)] +use serde::Deserialize; + +#[derive(Deserialize, Debug, PartialEq, Eq)] +struct TestData { + spans: Vec, +} + +#[derive(Deserialize, Debug, PartialEq, Eq)] struct SpanTestData { pub byte_start: u32, pub byte_end: u32, @@ -61,19 +67,11 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { let bytes = output.lock().unwrap(); let actual_output = str::from_utf8(&bytes).unwrap(); - let actual_output = json::from_str(&actual_output).unwrap(); - let spans = actual_output["spans"].as_array().unwrap(); + let actual_output: TestData = serde_json::from_str(actual_output).unwrap(); + let spans = actual_output.spans; assert_eq!(spans.len(), 1); - let obj = &spans[0]; - let actual_output = SpanTestData { - byte_start: obj["byte_start"].as_u64().unwrap() as u32, - byte_end: obj["byte_end"].as_u64().unwrap() as u32, - line_start: obj["line_start"].as_u64().unwrap() as u32, - line_end: obj["line_end"].as_u64().unwrap() as u32, - column_start: obj["column_start"].as_u64().unwrap() as u32, - column_end: obj["column_end"].as_u64().unwrap() as u32, - }; - assert_eq!(expected_output, actual_output); + + assert_eq!(expected_output, spans[0]) }) } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 29643eaad9..78b0892b3b 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -3,14 +3,13 @@ //! This module contains the code for creating and emitting diagnostics. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(crate_visibility_modifier)] #![feature(drain_filter)] #![feature(backtrace)] #![feature(if_let_guard)] #![feature(let_else)] #![feature(never_type)] -#![feature(nll)] #![feature(adt_const_params)] +#![feature(rustc_attrs)] #![allow(incomplete_features)] #![allow(rustc::potential_query_instability)] @@ -32,8 +31,9 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{self, Lock, Lrc}; use rustc_data_structures::AtomicRef; pub use rustc_error_messages::{ - fallback_fluent_bundle, fluent_bundle, DiagnosticMessage, FluentBundle, LanguageIdentifier, - LazyFallbackBundle, MultiSpan, SpanLabel, DEFAULT_LOCALE_RESOURCES, + fallback_fluent_bundle, fluent, fluent_bundle, DiagnosticMessage, FluentBundle, + LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage, + DEFAULT_LOCALE_RESOURCES, }; pub use rustc_lint_defs::{pluralize, Applicability}; use rustc_span::source_map::SourceMap; @@ -401,6 +401,9 @@ struct HandlerInner { emitter: Box, delayed_span_bugs: Vec, delayed_good_path_bugs: Vec, + /// This flag indicates that an expected diagnostic was emitted and suppressed. + /// This is used for the `delayed_good_path_bugs` check. + suppressed_expected_diag: bool, /// This set contains the `DiagnosticId` of all emitted diagnostics to avoid /// emitting the same diagnostic with extended help (`--teach`) twice, which @@ -496,7 +499,7 @@ impl Drop for HandlerInner { // instead of "require some error happened". Sadly that isn't ideal, as // lints can be `#[allow]`'d, potentially leading to this triggering. // Also, "good path" should be replaced with a better naming. - if !self.has_any_message() { + if !self.has_any_message() && !self.suppressed_expected_diag { let bugs = std::mem::replace(&mut self.delayed_good_path_bugs, Vec::new()); self.flush_delayed( bugs.into_iter().map(DelayedDiagnostic::decorate), @@ -578,6 +581,7 @@ impl Handler { emitter, delayed_span_bugs: Vec::new(), delayed_good_path_bugs: Vec::new(), + suppressed_expected_diag: false, taught_diagnostics: Default::default(), emitted_diagnostic_codes: Default::default(), emitted_diagnostics: Default::default(), @@ -645,6 +649,7 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_warn( &self, span: impl Into, @@ -655,7 +660,25 @@ impl Handler { result } + /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. + /// The `id` is used for lint emissions which should also fulfill a lint expectation. + /// + /// Attempting to `.emit()` the builder will only emit if either: + /// * `can_emit_warnings` is `true` + /// * `is_force_warn` was set in `DiagnosticId::Lint` + pub fn struct_span_warn_with_expectation( + &self, + span: impl Into, + msg: impl Into, + id: LintExpectationId, + ) -> DiagnosticBuilder<'_, ()> { + let mut result = self.struct_warn_with_expectation(msg, id); + result.set_span(span); + result + } + /// Construct a builder at the `Allow` level at the given `span` and with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_allow( &self, span: impl Into, @@ -668,6 +691,7 @@ impl Handler { /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. /// Also include a code. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_warn_with_code( &self, span: impl Into, @@ -684,16 +708,33 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Level::Warning, msg) + DiagnosticBuilder::new(self, Level::Warning(None), msg) + } + + /// Construct a builder at the `Warning` level with the `msg`. The `id` is used for + /// lint emissions which should also fulfill a lint expectation. + /// + /// Attempting to `.emit()` the builder will only emit if either: + /// * `can_emit_warnings` is `true` + /// * `is_force_warn` was set in `DiagnosticId::Lint` + pub fn struct_warn_with_expectation( + &self, + msg: impl Into, + id: LintExpectationId, + ) -> DiagnosticBuilder<'_, ()> { + DiagnosticBuilder::new(self, Level::Warning(Some(id)), msg) } /// Construct a builder at the `Allow` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_allow(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Allow, msg) } /// Construct a builder at the `Expect` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_expect( &self, msg: impl Into, @@ -703,6 +744,7 @@ impl Handler { } /// Construct a builder at the `Error` level at the given `span` and with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_err( &self, span: impl Into, @@ -714,6 +756,7 @@ impl Handler { } /// Construct a builder at the `Error` level at the given `span`, with the `msg`, and `code`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_err_with_code( &self, span: impl Into, @@ -727,6 +770,7 @@ impl Handler { /// Construct a builder at the `Error` level with the `msg`. // FIXME: This method should be removed (every error should have an associated error code). + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_err( &self, msg: impl Into, @@ -741,6 +785,7 @@ impl Handler { } /// Construct a builder at the `Error` level with the `msg` and the `code`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_err_with_code( &self, msg: impl Into, @@ -752,6 +797,7 @@ impl Handler { } /// Construct a builder at the `Warn` level with the `msg` and the `code`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_warn_with_code( &self, msg: impl Into, @@ -763,6 +809,7 @@ impl Handler { } /// Construct a builder at the `Fatal` level at the given `span` and with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_fatal( &self, span: impl Into, @@ -774,6 +821,7 @@ impl Handler { } /// Construct a builder at the `Fatal` level at the given `span`, with the `msg`, and `code`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_fatal_with_code( &self, span: impl Into, @@ -786,16 +834,19 @@ impl Handler { } /// Construct a builder at the `Error` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_fatal(&self, msg: impl Into) -> DiagnosticBuilder<'_, !> { DiagnosticBuilder::new_fatal(self, msg) } /// Construct a builder at the `Help` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_help(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Help, msg) } /// Construct a builder at the `Note` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_note_without_error( &self, msg: impl Into, @@ -803,11 +854,13 @@ impl Handler { DiagnosticBuilder::new(self, Level::Note, msg) } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_fatal(&self, span: impl Into, msg: impl Into) -> ! { self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span); FatalError.raise() } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_fatal_with_code( &self, span: impl Into, @@ -818,6 +871,7 @@ impl Handler { FatalError.raise() } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_err( &self, span: impl Into, @@ -826,6 +880,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span).unwrap() } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_err_with_code( &self, span: impl Into, @@ -838,17 +893,19 @@ impl Handler { ); } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_warn(&self, span: impl Into, msg: impl Into) { - self.emit_diag_at_span(Diagnostic::new(Warning, msg), span); + self.emit_diag_at_span(Diagnostic::new(Warning(None), msg), span); } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_warn_with_code( &self, span: impl Into, msg: impl Into, code: DiagnosticId, ) { - self.emit_diag_at_span(Diagnostic::new_with_code(Warning, Some(code), msg), span); + self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span); } pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { @@ -902,7 +959,7 @@ impl Handler { } pub fn warn(&self, msg: impl Into) { - let mut db = DiagnosticBuilder::new(self, Warning, msg); + let mut db = DiagnosticBuilder::new(self, Warning(None), msg); db.emit(); } @@ -1001,20 +1058,17 @@ impl Handler { let mut inner = self.inner.borrow_mut(); let diags = std::mem::take(&mut inner.unstable_expect_diagnostics); inner.check_unstable_expect_diagnostics = true; - if diags.is_empty() { - return; - } - - for mut diag in diags.into_iter() { - diag.update_unstable_expectation_id(unstable_to_stable); - let stable_id = diag - .level - .get_expectation_id() - .expect("all diagnostics inside `unstable_expect_diagnostics` must have a `LintExpectationId`"); - inner.fulfilled_expectations.insert(stable_id); + if !diags.is_empty() { + inner.suppressed_expected_diag = true; + for mut diag in diags.into_iter() { + diag.update_unstable_expectation_id(unstable_to_stable); - (*TRACK_DIAGNOSTICS)(&diag); + // Here the diagnostic is given back to `emit_diagnostic` where it was first + // intercepted. Now it should be processed as usual, since the unstable expectation + // id is now stable. + inner.emit_diagnostic(&mut diag); + } } inner @@ -1063,6 +1117,15 @@ impl HandlerInner { // FIXME(eddyb) this should ideally take `diagnostic` by value. fn emit_diagnostic(&mut self, diagnostic: &mut Diagnostic) -> Option { + // The `LintExpectationId` can be stable or unstable depending on when it was created. + // Diagnostics created before the definition of `HirId`s are unstable and can not yet + // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by + // a stable one by the `LintLevelsBuilder`. + if let Some(LintExpectationId::Unstable { .. }) = diagnostic.level.get_expectation_id() { + self.unstable_expect_diagnostics.push(diagnostic.clone()); + return None; + } + if diagnostic.level == Level::DelayedBug { // FIXME(eddyb) this should check for `has_errors` and stop pushing // once *any* errors were emitted (and truncate `delayed_span_bugs` @@ -1079,7 +1142,12 @@ impl HandlerInner { self.future_breakage_diagnostics.push(diagnostic.clone()); } - if diagnostic.level == Warning + if let Some(expectation_id) = diagnostic.level.get_expectation_id() { + self.suppressed_expected_diag = true; + self.fulfilled_expectations.insert(expectation_id); + } + + if matches!(diagnostic.level, Warning(_)) && !self.flags.can_emit_warnings && !diagnostic.is_force_warn() { @@ -1089,21 +1157,9 @@ impl HandlerInner { return None; } - // The `LintExpectationId` can be stable or unstable depending on when it was created. - // Diagnostics created before the definition of `HirId`s are unstable and can not yet - // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by - // a stable one by the `LintLevelsBuilder`. - if let Level::Expect(LintExpectationId::Unstable { .. }) = diagnostic.level { - self.unstable_expect_diagnostics.push(diagnostic.clone()); - return None; - } - (*TRACK_DIAGNOSTICS)(diagnostic); - if let Level::Expect(expectation_id) = diagnostic.level { - self.fulfilled_expectations.insert(expectation_id); - return None; - } else if diagnostic.level == Allow { + if matches!(diagnostic.level, Level::Expect(_) | Level::Allow) { return None; } @@ -1118,7 +1174,7 @@ impl HandlerInner { !this.emitted_diagnostics.insert(diagnostic_hash) }; - // Only emit the diagnostic if we've been asked to deduplicate and + // Only emit the diagnostic if we've been asked to deduplicate or // haven't already emitted an equivalent diagnostic. if !(self.flags.deduplicate_diagnostics && already_emitted(self)) { debug!(?diagnostic); @@ -1140,7 +1196,7 @@ impl HandlerInner { self.emitter.emit_diagnostic(&diagnostic); if diagnostic.is_error() { self.deduplicated_err_count += 1; - } else if diagnostic.level == Warning { + } else if let Warning(_) = diagnostic.level { self.deduplicated_warn_count += 1; } } @@ -1193,7 +1249,7 @@ impl HandlerInner { match (errors.len(), warnings.len()) { (0, 0) => return, (0, _) => self.emitter.emit_diagnostic(&Diagnostic::new( - Level::Warning, + Level::Warning(None), DiagnosticMessage::Str(warnings), )), (_, 0) => { @@ -1426,7 +1482,10 @@ pub enum Level { /// If this error comes from a lint, don't abort compilation even when abort_if_errors() is called. lint: bool, }, - Warning, + /// This [`LintExpectationId`] is used for expected lint diagnostics, which should + /// also emit a warning due to the `force-warn` flag. In all other cases this should + /// be `None`. + Warning(Option), Note, /// A note that is only emitted once. OnceNote, @@ -1449,7 +1508,7 @@ impl Level { Bug | DelayedBug | Fatal | Error { .. } => { spec.set_fg(Some(Color::Red)).set_intense(true); } - Warning => { + Warning(_) => { spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows)); } Note | OnceNote => { @@ -1468,7 +1527,7 @@ impl Level { match self { Bug | DelayedBug => "error: internal compiler error", Fatal | Error { .. } => "error", - Warning => "warning", + Warning(_) => "warning", Note | OnceNote => "note", Help => "help", FailureNote => "failure-note", @@ -1483,7 +1542,7 @@ impl Level { pub fn get_expectation_id(&self) -> Option { match self { - Level::Expect(id) => Some(*id), + Level::Expect(id) | Level::Warning(Some(id)) => Some(*id), _ => None, } } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 9ea09f7d70..245719bff1 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -4,7 +4,7 @@ use crate::module::DirOwnership; use rustc_ast::attr::MarkedAttrs; use rustc_ast::ptr::P; use rustc_ast::token::{self, Nonterminal}; -use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream}; +use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_ast::{self as ast, Attribute, HasAttrs, Item, NodeId, PatKind}; use rustc_attr::{self as attr, Deprecation, Stability}; @@ -13,8 +13,8 @@ use rustc_data_structures::sync::{self, Lrc}; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, PResult}; use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; use rustc_lint_defs::BuiltinLintDiagnostics; -use rustc_parse::{self, parser, to_token_stream, MACRO_ARGUMENTS}; -use rustc_session::{parse::ParseSess, Limit, Session}; +use rustc_parse::{self, parser, MACRO_ARGUMENTS}; +use rustc_session::{parse::ParseSess, Limit, Session, SessionDiagnostic}; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId}; @@ -28,7 +28,7 @@ use std::iter; use std::path::PathBuf; use std::rc::Rc; -crate use rustc_span::hygiene::MacroKind; +pub(crate) use rustc_span::hygiene::MacroKind; // When adding new variants, make sure to // adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector` @@ -109,20 +109,18 @@ impl Annotatable { } } - pub fn to_tokens(&self, sess: &ParseSess) -> TokenStream { + pub fn to_tokens(&self) -> TokenStream { match self { - Annotatable::Item(node) => to_token_stream(node, sess, CanSynthesizeMissingTokens::No), + Annotatable::Item(node) => TokenStream::from_ast(node), Annotatable::TraitItem(node) | Annotatable::ImplItem(node) => { - to_token_stream(node, sess, CanSynthesizeMissingTokens::No) - } - Annotatable::ForeignItem(node) => { - to_token_stream(node, sess, CanSynthesizeMissingTokens::No) + TokenStream::from_ast(node) } + Annotatable::ForeignItem(node) => TokenStream::from_ast(node), Annotatable::Stmt(node) => { assert!(!matches!(node.kind, ast::StmtKind::Empty)); - to_token_stream(node, sess, CanSynthesizeMissingTokens::No) + TokenStream::from_ast(node) } - Annotatable::Expr(node) => to_token_stream(node, sess, CanSynthesizeMissingTokens::No), + Annotatable::Expr(node) => TokenStream::from_ast(node), Annotatable::Arm(..) | Annotatable::ExprField(..) | Annotatable::PatField(..) @@ -268,7 +266,7 @@ where } } -pub trait ProcMacro { +pub trait BangProcMacro { fn expand<'cx>( &self, ecx: &'cx mut ExtCtxt<'_>, @@ -277,7 +275,7 @@ pub trait ProcMacro { ) -> Result; } -impl ProcMacro for F +impl BangProcMacro for F where F: Fn(TokenStream) -> TokenStream, { @@ -642,7 +640,7 @@ pub enum SyntaxExtensionKind { /// A token-based function-like macro. Bang( /// An expander with signature TokenStream -> TokenStream. - Box, + Box, ), /// An AST-based function-like macro. @@ -1087,6 +1085,17 @@ impl<'a> ExtCtxt<'a> { self.sess.parse_sess.span_diagnostic.struct_span_err(sp, msg) } + pub fn create_err( + &self, + err: impl SessionDiagnostic<'a>, + ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + self.sess.create_err(err) + } + + pub fn emit_err(&self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { + self.sess.emit_err(err) + } + /// Emit `msg` attached to `sp`, without immediately stopping /// compilation. /// @@ -1196,7 +1205,7 @@ pub fn expr_to_spanned_string<'a>( err.span_suggestion( expr.span.shrink_to_lo(), "consider removing the leading `b`", - String::new(), + "", Applicability::MaybeIncorrect, ); Some((err, true)) diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 301c67f702..e73c31c98f 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -160,7 +160,7 @@ impl<'a> ExtCtxt<'a> { attrs: AttrVec::new(), tokens: None, }); - ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp } + self.stmt_local(local, sp) } // Generates `let _: Type;`, which is usually used for type assertions. @@ -174,6 +174,10 @@ impl<'a> ExtCtxt<'a> { attrs: AttrVec::new(), tokens: None, }); + self.stmt_local(local, span) + } + + pub fn stmt_local(&self, local: P, span: Span) -> ast::Stmt { ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span } } @@ -514,7 +518,7 @@ impl<'a> ExtCtxt<'a> { } } - // FIXME: unused `self` + // `self` is unused but keep it as method for the convenience use. pub fn fn_decl(&self, inputs: Vec, output: ast::FnRetTy) -> P { P(ast::FnDecl { inputs, output }) } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 0b8cb07a64..3cada37257 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -347,7 +347,7 @@ impl<'a> StripUnconfigured<'a> { /// Gives a compiler warning when the `cfg_attr` contains no attributes and /// is in the original source file. Gives a compiler error if the syntax of /// the attribute is incorrect. - crate fn expand_cfg_attr(&self, attr: Attribute, recursive: bool) -> Vec { + pub(crate) fn expand_cfg_attr(&self, attr: Attribute, recursive: bool) -> Vec { let Some((cfg_predicate, expanded_attrs)) = rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) else { return vec![]; @@ -400,7 +400,7 @@ impl<'a> StripUnconfigured<'a> { // Use the `#` in `#[cfg_attr(pred, attr)]` as the `#` token // for `attr` when we expand it to `#[attr]` - let mut orig_trees = orig_tokens.trees(); + let mut orig_trees = orig_tokens.into_trees(); let TokenTree::Token(pound_token @ Token { kind: TokenKind::Pound, .. }) = orig_trees.next().unwrap() else { panic!("Bad tokens for attribute {:?}", attr); }; @@ -451,7 +451,7 @@ impl<'a> StripUnconfigured<'a> { attrs.iter().all(|attr| !is_cfg(attr) || self.cfg_true(attr)) } - crate fn cfg_true(&self, attr: &Attribute) -> bool { + pub(crate) fn cfg_true(&self, attr: &Attribute) -> bool { let meta_item = match validate_attr::parse_meta(&self.sess.parse_sess, attr) { Ok(meta_item) => meta_item, Err(mut err) => { @@ -465,7 +465,7 @@ impl<'a> StripUnconfigured<'a> { } /// If attributes are not allowed on expressions, emit an error for `attr` - crate fn maybe_emit_expr_attr_err(&self, attr: &Attribute) { + pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) { if !self.features.map_or(true, |features| features.stmt_expr_attributes) { let mut err = feature_err( &self.sess.parse_sess, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index a390e7a466..978f87b1d1 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -214,7 +214,7 @@ pub enum SupportsMacroExpansion { } impl AstFragmentKind { - crate fn dummy(self, span: Span) -> AstFragment { + pub(crate) fn dummy(self, span: Span) -> AstFragment { self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment") } @@ -679,9 +679,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ) ) => { - rustc_parse::fake_token_stream(&self.cx.sess.parse_sess, item_inner) + rustc_parse::fake_token_stream_for_item( + &self.cx.sess.parse_sess, + item_inner, + ) } - _ => item.to_tokens(&self.cx.sess.parse_sess), + _ => item.to_tokens(), }; let attr_item = attr.unwrap_normal_item(); if let MacArgs::Eq(..) = attr_item.args { @@ -942,7 +945,7 @@ pub fn ensure_complete_parse<'a>( err.span_suggestion( semi_span, "you might be missing a semicolon here", - ";".to_owned(), + ";", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index dc181ecda5..86ff110eec 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -1,7 +1,7 @@ #![allow(rustc::potential_query_instability)] +#![feature(array_windows)] #![feature(associated_type_bounds)] #![feature(associated_type_defaults)] -#![feature(crate_visibility_modifier)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(let_else)] @@ -21,7 +21,7 @@ mod placeholders; mod proc_macro_server; pub use mbe::macro_rules::compile_declarative_macro; -crate use rustc_span::hygiene; +pub(crate) use rustc_span::hygiene; pub mod base; pub mod build; #[macro_use] @@ -30,7 +30,7 @@ pub mod expand; pub mod module; pub mod proc_macro; -crate mod mbe; +pub(crate) mod mbe; // HACK(Centril, #64197): These shouldn't really be here. // Rather, they should be with their respective modules which are defined in other crates. diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index 36295da74a..f42576b16f 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -3,12 +3,12 @@ //! why we call this module `mbe`. For external documentation, prefer the //! official terminology: "declarative macros". -crate mod macro_check; -crate mod macro_parser; -crate mod macro_rules; -crate mod metavar_expr; -crate mod quoted; -crate mod transcribe; +pub(crate) mod macro_check; +pub(crate) mod macro_parser; +pub(crate) mod macro_rules; +pub(crate) mod metavar_expr; +pub(crate) mod quoted; +pub(crate) mod transcribe; use metavar_expr::MetaVarExpr; use rustc_ast::token::{Delimiter, NonterminalKind, Token, TokenKind}; diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index ddfbef945e..4fa91dfeae 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -70,8 +70,8 @@ //! eof: [a $( a )* a b ·] //! ``` -crate use NamedMatch::*; -crate use ParseResult::*; +pub(crate) use NamedMatch::*; +pub(crate) use ParseResult::*; use crate::mbe::{KleeneOp, TokenTree}; @@ -262,7 +262,7 @@ enum EofMatcherPositions { } /// Represents the possible results of an attempted parse. -crate enum ParseResult { +pub(crate) enum ParseResult { /// Parsed successfully. Success(T), /// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected @@ -276,7 +276,7 @@ crate enum ParseResult { /// A `ParseResult` where the `Success` variant contains a mapping of /// `MacroRulesNormalizedIdent`s to `NamedMatch`es. This represents the mapping /// of metavars to the token trees they bind to. -crate type NamedParseResult = ParseResult>; +pub(crate) type NamedParseResult = ParseResult>; /// Count how many metavars declarations are in `matcher`. pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize { @@ -340,7 +340,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize { /// ]) /// ``` #[derive(Debug, Clone)] -crate enum NamedMatch { +pub(crate) enum NamedMatch { MatchedSeq(Vec), // A metavar match of type `tt`. @@ -362,7 +362,7 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool { } // Note: the vectors could be created and dropped within `parse_tt`, but to avoid excess -// allocations we have a single vector fo each kind that is cleared and reused repeatedly. +// allocations we have a single vector for each kind that is cleared and reused repeatedly. pub struct TtParser { macro_name: Ident, diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 4cc3169180..f40c365cbc 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -33,7 +33,7 @@ use std::collections::hash_map::Entry; use std::{mem, slice}; use tracing::debug; -crate struct ParserAnyMacro<'a> { +pub(crate) struct ParserAnyMacro<'a> { parser: Parser<'a>, /// Span of the expansion site of the macro this parser is for @@ -47,7 +47,7 @@ crate struct ParserAnyMacro<'a> { is_local: bool, } -crate fn annotate_err_with_kind(err: &mut Diagnostic, kind: AstFragmentKind, span: Span) { +pub(crate) fn annotate_err_with_kind(err: &mut Diagnostic, kind: AstFragmentKind, span: Span) { match kind { AstFragmentKind::Ty => { err.span_label(span, "this macro call doesn't expand to a type"); @@ -102,7 +102,7 @@ fn emit_frag_parse_err( e.span_suggestion_verbose( site_span.shrink_to_hi(), "add `;` to interpret the expansion as a statement", - ";".to_string(), + ";", Applicability::MaybeIncorrect, ); } @@ -113,7 +113,7 @@ fn emit_frag_parse_err( } impl<'a> ParserAnyMacro<'a> { - crate fn make(mut self: Box>, kind: AstFragmentKind) -> AstFragment { + pub(crate) fn make(mut self: Box>, kind: AstFragmentKind) -> AstFragment { let ParserAnyMacro { site_span, macro_ident, @@ -123,7 +123,7 @@ impl<'a> ParserAnyMacro<'a> { is_trailing_mac, is_local, } = *self; - let snapshot = &mut parser.clone(); + let snapshot = &mut parser.create_snapshot_for_diagnostic(); let fragment = match parse_ast_fragment(parser, kind) { Ok(f) => f, Err(err) => { @@ -204,7 +204,7 @@ fn trace_macros_note(cx_expansions: &mut FxHashMap>, sp: Span, /// Expands the rules based macro defined by `lhses` and `rhses` for a given /// input `arg`. -fn expand_macro<'cx, 'tt>( +fn expand_macro<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, def_span: Span, @@ -212,8 +212,8 @@ fn expand_macro<'cx, 'tt>( name: Ident, transparency: Transparency, arg: TokenStream, - lhses: &'tt [Vec], - rhses: &'tt [mbe::TokenTree], + lhses: &[Vec], + rhses: &[mbe::TokenTree], ) -> Box { let sess = &cx.sess.parse_sess; // Macros defined in the current crate have a real node id, @@ -357,7 +357,7 @@ fn expand_macro<'cx, 'tt>( err.span_suggestion_short( comma_span, "missing comma here", - ", ".to_string(), + ", ", Applicability::MachineApplicable, ); } @@ -380,7 +380,7 @@ pub fn compile_declarative_macro( features: &Features, def: &ast::Item, edition: Edition, -) -> (SyntaxExtension, Vec) { +) -> (SyntaxExtension, Vec<(usize, Span)>) { debug!("compile_declarative_macro: {:?}", def); let mk_syn_ext = |expander| { SyntaxExtension::new( @@ -539,11 +539,22 @@ pub fn compile_declarative_macro( None => {} } - // Compute the spans of the macro rules - // We only take the span of the lhs here, - // so that the spans of created warnings are smaller. - let rule_spans = if def.id != DUMMY_NODE_ID { - lhses.iter().map(|lhs| lhs.span()).collect::>() + // Compute the spans of the macro rules for unused rule linting. + // To avoid warning noise, only consider the rules of this + // macro for the lint, if all rules are valid. + // Also, we are only interested in non-foreign macros. + let rule_spans = if valid && def.id != DUMMY_NODE_ID { + lhses + .iter() + .zip(rhses.iter()) + .enumerate() + // If the rhs contains an invocation like compile_error!, + // don't consider the rule for the unused rule lint. + .filter(|(_idx, (_lhs, rhs))| !has_compile_error_macro(rhs)) + // We only take the span of the lhs here, + // so that the spans of created warnings are smaller. + .map(|(idx, (lhs, _rhs))| (idx, lhs.span())) + .collect::>() } else { Vec::new() }; @@ -651,6 +662,29 @@ fn check_matcher(sess: &ParseSess, def: &ast::Item, matcher: &[mbe::TokenTree]) err == sess.span_diagnostic.err_count() } +fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool { + match rhs { + mbe::TokenTree::Delimited(_sp, d) => { + let has_compile_error = d.tts.array_windows::<3>().any(|[ident, bang, args]| { + if let mbe::TokenTree::Token(ident) = ident && + let TokenKind::Ident(ident, _) = ident.kind && + ident == sym::compile_error && + let mbe::TokenTree::Token(bang) = bang && + let TokenKind::Not = bang.kind && + let mbe::TokenTree::Delimited(_, del) = args && + del.delim != Delimiter::Invisible + { + true + } else { + false + } + }); + if has_compile_error { true } else { d.tts.iter().any(has_compile_error_macro) } + } + _ => false, + } +} + // `The FirstSets` for a matcher is a mapping from subsequences in the // matcher to the FIRST set for that subsequence. // diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index cdc5e20423..45c462bc42 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -1,5 +1,5 @@ use rustc_ast::token::{self, Delimiter}; -use rustc_ast::tokenstream::{Cursor, TokenStream, TokenTree}; +use rustc_ast::tokenstream::{CursorRef, TokenStream, TokenTree}; use rustc_ast::{LitIntType, LitKind}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, PResult}; @@ -9,7 +9,7 @@ use rustc_span::Span; /// A meta-variable expression, for expansions based on properties of meta-variables. #[derive(Debug, Clone, PartialEq, Encodable, Decodable)] -crate enum MetaVarExpr { +pub(crate) enum MetaVarExpr { /// The number of repetitions of an identifier, optionally limited to a number /// of outer-most repetition depths. If the depth limit is `None` then the depth is unlimited. Count(Ident, Option), @@ -28,7 +28,7 @@ crate enum MetaVarExpr { impl MetaVarExpr { /// Attempt to parse a meta-variable expression from a token stream. - crate fn parse<'sess>( + pub(crate) fn parse<'sess>( input: &TokenStream, outer_span: Span, sess: &'sess ParseSess, @@ -52,7 +52,7 @@ impl MetaVarExpr { err.span_suggestion( ident.span, "supported expressions are count, ignore, index and length", - String::new(), + "", Applicability::MachineApplicable, ); return Err(err); @@ -62,7 +62,7 @@ impl MetaVarExpr { Ok(rslt) } - crate fn ident(&self) -> Option { + pub(crate) fn ident(&self) -> Option { match *self { MetaVarExpr::Count(ident, _) | MetaVarExpr::Ignore(ident) => Some(ident), MetaVarExpr::Index(..) | MetaVarExpr::Length(..) => None, @@ -71,12 +71,14 @@ impl MetaVarExpr { } // Checks if there are any remaining tokens. For example, `${ignore(ident ... a b c ...)}` -fn check_trailing_token<'sess>(iter: &mut Cursor, sess: &'sess ParseSess) -> PResult<'sess, ()> { +fn check_trailing_token<'sess>( + iter: &mut CursorRef<'_>, + sess: &'sess ParseSess, +) -> PResult<'sess, ()> { if let Some(tt) = iter.next() { - let mut diag = sess.span_diagnostic.struct_span_err( - tt.span(), - &format!("unexpected token: {}", pprust::tt_to_string(&tt)), - ); + let mut diag = sess + .span_diagnostic + .struct_span_err(tt.span(), &format!("unexpected token: {}", pprust::tt_to_string(tt))); diag.span_note(tt.span(), "meta-variable expression must not have trailing tokens"); Err(diag) } else { @@ -86,7 +88,7 @@ fn check_trailing_token<'sess>(iter: &mut Cursor, sess: &'sess ParseSess) -> PRe /// Parse a meta-variable `count` expression: `count(ident[, depth])` fn parse_count<'sess>( - iter: &mut Cursor, + iter: &mut CursorRef<'_>, sess: &'sess ParseSess, span: Span, ) -> PResult<'sess, MetaVarExpr> { @@ -97,7 +99,7 @@ fn parse_count<'sess>( /// Parses the depth used by index(depth) and length(depth). fn parse_depth<'sess>( - iter: &mut Cursor, + iter: &mut CursorRef<'_>, sess: &'sess ParseSess, span: Span, ) -> PResult<'sess, usize> { @@ -110,7 +112,7 @@ fn parse_depth<'sess>( "meta-variable expression depth must be a literal" )); }; - if let Ok(lit_kind) = LitKind::from_lit_token(lit) + if let Ok(lit_kind) = LitKind::from_lit_token(*lit) && let LitKind::Int(n_u128, LitIntType::Unsuffixed) = lit_kind && let Ok(n_usize) = usize::try_from(n_u128) { @@ -124,7 +126,7 @@ fn parse_depth<'sess>( /// Parses an generic ident fn parse_ident<'sess>( - iter: &mut Cursor, + iter: &mut CursorRef<'_>, sess: &'sess ParseSess, span: Span, ) -> PResult<'sess, Ident> { @@ -132,7 +134,7 @@ fn parse_ident<'sess>( if let Some((elem, false)) = token.ident() { return Ok(elem); } - let token_str = pprust::token_to_string(&token); + let token_str = pprust::token_to_string(token); let mut err = sess.span_diagnostic.struct_span_err( span, &format!("expected identifier, found `{}`", &token_str) @@ -140,7 +142,7 @@ fn parse_ident<'sess>( err.span_suggestion( token.span, &format!("try removing `{}`", &token_str), - String::new(), + "", Applicability::MaybeIncorrect, ); return Err(err); @@ -150,7 +152,7 @@ fn parse_ident<'sess>( /// Tries to move the iterator forward returning `true` if there is a comma. If not, then the /// iterator is not modified and the result is `false`. -fn try_eat_comma(iter: &mut Cursor) -> bool { +fn try_eat_comma(iter: &mut CursorRef<'_>) -> bool { if let Some(TokenTree::Token(token::Token { kind: token::Comma, .. })) = iter.look_ahead(0) { let _ = iter.next(); return true; diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index d52de24c39..707cb73f09 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -48,7 +48,7 @@ pub(super) fn parse( // For each token tree in `input`, parse the token into a `self::TokenTree`, consuming // additional trees if need be. - let mut trees = input.trees(); + let mut trees = input.into_trees(); while let Some(tree) = trees.next() { // Given the parsed tree, if there is a metavar and we are expecting matchers, actually // parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`). diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 2a059f3519..876faad33b 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -26,7 +26,7 @@ pub struct ModulePathSuccess { pub dir_ownership: DirOwnership, } -crate struct ParsedExternalMod { +pub(crate) struct ParsedExternalMod { pub items: Vec>, pub spans: ModSpans, pub file_path: PathBuf, @@ -42,7 +42,7 @@ pub enum ModError<'a> { ParserError(DiagnosticBuilder<'a, ErrorGuaranteed>), } -crate fn parse_external_mod( +pub(crate) fn parse_external_mod( sess: &Session, ident: Ident, span: Span, // The span to blame on errors. @@ -78,7 +78,7 @@ crate fn parse_external_mod( ParsedExternalMod { items, spans, file_path, dir_path, dir_ownership } } -crate fn mod_dir_path( +pub(crate) fn mod_dir_path( sess: &Session, ident: Ident, attrs: &[Attribute], diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index 5d447d911e..8da7879275 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -61,7 +61,7 @@ fn bad_path_expr_1() { fn string_to_tts_macro() { create_default_session_globals_then(|| { let tts: Vec<_> = - string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect(); + string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).into_trees().collect(); let tts: &[TokenTree] = &tts[..]; match tts { @@ -293,7 +293,7 @@ fn ttdelim_span() { .unwrap(); let tts: Vec<_> = match expr.kind { - ast::ExprKind::MacCall(ref mac) => mac.args.inner_tokens().trees().collect(), + ast::ExprKind::MacCall(ref mac) => mac.args.inner_tokens().into_trees().collect(), _ => panic!("not a macro"), }; diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 6c74d462fb..9e1cd299fd 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -14,10 +14,10 @@ use rustc_span::{Span, DUMMY_SP}; const EXEC_STRATEGY: pm::bridge::server::SameThread = pm::bridge::server::SameThread; pub struct BangProcMacro { - pub client: pm::bridge::client::Client pm::TokenStream>, + pub client: pm::bridge::client::Client, } -impl base::ProcMacro for BangProcMacro { +impl base::BangProcMacro for BangProcMacro { fn expand<'cx>( &self, ecx: &'cx mut ExtCtxt<'_>, @@ -42,7 +42,7 @@ impl base::ProcMacro for BangProcMacro { } pub struct AttrProcMacro { - pub client: pm::bridge::client::Client pm::TokenStream>, + pub client: pm::bridge::client::Client<(pm::TokenStream, pm::TokenStream), pm::TokenStream>, } impl base::AttrProcMacro for AttrProcMacro { @@ -72,11 +72,11 @@ impl base::AttrProcMacro for AttrProcMacro { } } -pub struct ProcMacroDerive { - pub client: pm::bridge::client::Client pm::TokenStream>, +pub struct DeriveProcMacro { + pub client: pm::bridge::client::Client, } -impl MultiItemModifier for ProcMacroDerive { +impl MultiItemModifier for DeriveProcMacro { fn expand( &self, ecx: &mut ExtCtxt<'_>, @@ -96,7 +96,7 @@ impl MultiItemModifier for ProcMacroDerive { }; TokenTree::token(token::Interpolated(Lrc::new(nt)), DUMMY_SP).into() } else { - item.to_tokens(&ecx.sess.parse_sess) + item.to_tokens() }; let stream = { diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index c0c786e471..1e4193a5a1 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -2,14 +2,13 @@ use crate::base::ExtCtxt; use rustc_ast as ast; use rustc_ast::token; -use rustc_ast::tokenstream::{self, CanSynthesizeMissingTokens}; -use rustc_ast::tokenstream::{DelimSpan, Spacing::*, TokenStream, TreeAndSpacing}; +use rustc_ast::tokenstream::{self, DelimSpan, Spacing::*, TokenStream, TreeAndSpacing}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use rustc_errors::{Diagnostic, MultiSpan, PResult}; use rustc_parse::lexer::nfc_normalize; -use rustc_parse::{nt_to_tokenstream, parse_stream_from_source_str}; +use rustc_parse::parse_stream_from_source_str; use rustc_session::parse::ParseSess; use rustc_span::def_id::CrateNum; use rustc_span::symbol::{self, kw, sym, Symbol}; @@ -179,10 +178,9 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec, &mut Rustc<'_, '_>)> TokenTree::Ident(Ident::new(rustc.sess(), ident.name, is_raw, ident.span)) } Interpolated(nt) => { - let stream = nt_to_tokenstream(&nt, rustc.sess(), CanSynthesizeMissingTokens::No); TokenTree::Group(Group { delimiter: pm::Delimiter::None, - stream, + stream: TokenStream::from_nonterminal_ast(&nt), span: DelimSpan::from_single(span), flatten: crate::base::nt_pretty_printing_compatibility_hack(&nt, rustc.sess()), }) @@ -269,7 +267,7 @@ impl ToInternal for Level { fn to_internal(self) -> rustc_errors::Level { match self { Level::Error => rustc_errors::Level::Error { lint: false }, - Level::Warning => rustc_errors::Level::Warning, + Level::Warning => rustc_errors::Level::Warning(None), Level::Note => rustc_errors::Level::Note, Level::Help => rustc_errors::Level::Help, _ => unreachable!("unknown proc_macro::Level variant: {:?}", self), @@ -279,12 +277,6 @@ impl ToInternal for Level { pub struct FreeFunctions; -#[derive(Clone)] -pub struct TokenStreamIter { - cursor: tokenstream::Cursor, - stack: Vec>, -} - #[derive(Clone)] pub struct Group { delimiter: Delimiter, @@ -337,6 +329,7 @@ impl Ident { sess.symbol_gallery.insert(sym, span); Ident { sym, is_raw, span } } + fn dollar_crate(span: Span) -> Ident { // `$crate` is accepted as an ident only if it comes from the compiler. Ident { sym: kw::DollarCrate, is_raw: false, span } @@ -384,8 +377,6 @@ impl<'a, 'b> Rustc<'a, 'b> { impl server::Types for Rustc<'_, '_> { type FreeFunctions = FreeFunctions; type TokenStream = TokenStream; - type TokenStreamBuilder = tokenstream::TokenStreamBuilder; - type TokenStreamIter = TokenStreamIter; type Group = Group; type Punct = Punct; type Ident = Ident; @@ -410,12 +401,10 @@ impl server::FreeFunctions for Rustc<'_, '_> { } impl server::TokenStream for Rustc<'_, '_> { - fn new(&mut self) -> Self::TokenStream { - TokenStream::default() - } fn is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } + fn from_str(&mut self, src: &str) -> Self::TokenStream { parse_stream_from_source_str( FileName::proc_macro_source_code(src), @@ -424,9 +413,11 @@ impl server::TokenStream for Rustc<'_, '_> { Some(self.call_site), ) } + fn to_string(&mut self, stream: &Self::TokenStream) -> String { pprust::tts_to_string(stream) } + fn expand_expr(&mut self, stream: &Self::TokenStream) -> Result { // Parse the expression from our tokenstream. let expr: PResult<'_, _> = try { @@ -454,7 +445,7 @@ impl server::TokenStream for Rustc<'_, '_> { // NOTE: For now, limit `expand_expr` to exclusively expand to literals. // This may be relaxed in the future. - // We don't use `nt_to_tokenstream` as the tokenstream currently cannot + // We don't use `TokenStream::from_ast` as the tokenstream currently cannot // be recovered in the general case. match &expr.kind { ast::ExprKind::Lit(l) => { @@ -477,78 +468,110 @@ impl server::TokenStream for Rustc<'_, '_> { _ => Err(()), } } + fn from_token_tree( &mut self, tree: TokenTree, ) -> Self::TokenStream { tree.to_internal() } - fn into_iter(&mut self, stream: Self::TokenStream) -> Self::TokenStreamIter { - TokenStreamIter { cursor: stream.trees(), stack: vec![] } - } -} -impl server::TokenStreamBuilder for Rustc<'_, '_> { - fn new(&mut self) -> Self::TokenStreamBuilder { - tokenstream::TokenStreamBuilder::new() - } - fn push(&mut self, builder: &mut Self::TokenStreamBuilder, stream: Self::TokenStream) { - builder.push(stream); + fn concat_trees( + &mut self, + base: Option, + trees: Vec>, + ) -> Self::TokenStream { + let mut builder = tokenstream::TokenStreamBuilder::new(); + if let Some(base) = base { + builder.push(base); + } + for tree in trees { + builder.push(tree.to_internal()); + } + builder.build() } - fn build(&mut self, builder: Self::TokenStreamBuilder) -> Self::TokenStream { + + fn concat_streams( + &mut self, + base: Option, + streams: Vec, + ) -> Self::TokenStream { + let mut builder = tokenstream::TokenStreamBuilder::new(); + if let Some(base) = base { + builder.push(base); + } + for stream in streams { + builder.push(stream); + } builder.build() } -} -impl server::TokenStreamIter for Rustc<'_, '_> { - fn next( + fn into_trees( &mut self, - iter: &mut Self::TokenStreamIter, - ) -> Option> { + stream: Self::TokenStream, + ) -> Vec> { + // FIXME: This is a raw port of the previous approach (which had a + // `TokenStreamIter` server-side object with a single `next` method), + // and can probably be optimized (for bulk conversion). + let mut cursor = stream.into_trees(); + let mut stack = Vec::new(); + let mut tts = Vec::new(); loop { - let tree = iter.stack.pop().or_else(|| { - let next = iter.cursor.next_with_spacing()?; - Some(TokenTree::from_internal((next, &mut iter.stack, self))) - })?; - // A hack used to pass AST fragments to attribute and derive macros - // as a single nonterminal token instead of a token stream. - // Such token needs to be "unwrapped" and not represented as a delimited group. - // FIXME: It needs to be removed, but there are some compatibility issues (see #73345). - if let TokenTree::Group(ref group) = tree { - if group.flatten { - iter.cursor.append(group.stream.clone()); - continue; + let next = stack.pop().or_else(|| { + let next = cursor.next_with_spacing()?; + Some(TokenTree::from_internal((next, &mut stack, self))) + }); + match next { + Some(TokenTree::Group(group)) => { + // A hack used to pass AST fragments to attribute and derive + // macros as a single nonterminal token instead of a token + // stream. Such token needs to be "unwrapped" and not + // represented as a delimited group. + // FIXME: It needs to be removed, but there are some + // compatibility issues (see #73345). + if group.flatten { + tts.append(&mut self.into_trees(group.stream)); + } else { + tts.push(TokenTree::Group(group)); + } } + Some(tt) => tts.push(tt), + None => return tts, } - return Some(tree); } } } impl server::Group for Rustc<'_, '_> { - fn new(&mut self, delimiter: Delimiter, stream: Self::TokenStream) -> Self::Group { + fn new(&mut self, delimiter: Delimiter, stream: Option) -> Self::Group { Group { delimiter, - stream, + stream: stream.unwrap_or_default(), span: DelimSpan::from_single(server::Span::call_site(self)), flatten: false, } } + fn delimiter(&mut self, group: &Self::Group) -> Delimiter { group.delimiter } + fn stream(&mut self, group: &Self::Group) -> Self::TokenStream { group.stream.clone() } + fn span(&mut self, group: &Self::Group) -> Self::Span { group.span.entire() } + fn span_open(&mut self, group: &Self::Group) -> Self::Span { group.span.open } + fn span_close(&mut self, group: &Self::Group) -> Self::Span { group.span.close } + fn set_span(&mut self, group: &mut Self::Group, span: Self::Span) { group.span = DelimSpan::from_single(span); } @@ -558,15 +581,19 @@ impl server::Punct for Rustc<'_, '_> { fn new(&mut self, ch: char, spacing: Spacing) -> Self::Punct { Punct::new(ch, spacing == Spacing::Joint, server::Span::call_site(self)) } + fn as_char(&mut self, punct: Self::Punct) -> char { punct.ch } + fn spacing(&mut self, punct: Self::Punct) -> Spacing { if punct.joint { Spacing::Joint } else { Spacing::Alone } } + fn span(&mut self, punct: Self::Punct) -> Self::Span { punct.span } + fn with_span(&mut self, punct: Self::Punct, span: Self::Span) -> Self::Punct { Punct { span, ..punct } } @@ -576,9 +603,11 @@ impl server::Ident for Rustc<'_, '_> { fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident { Ident::new(self.sess(), Symbol::intern(string), is_raw, span) } + fn span(&mut self, ident: Self::Ident) -> Self::Span { ident.span } + fn with_span(&mut self, ident: Self::Ident, span: Self::Span) -> Self::Ident { Ident { span, ..ident } } @@ -630,45 +659,57 @@ impl server::Literal for Rustc<'_, '_> { Ok(Literal { lit, span: self.call_site }) } + fn to_string(&mut self, literal: &Self::Literal) -> String { literal.lit.to_string() } + fn debug_kind(&mut self, literal: &Self::Literal) -> String { format!("{:?}", literal.lit.kind) } + fn symbol(&mut self, literal: &Self::Literal) -> String { literal.lit.symbol.to_string() } + fn suffix(&mut self, literal: &Self::Literal) -> Option { literal.lit.suffix.as_ref().map(Symbol::to_string) } + fn integer(&mut self, n: &str) -> Self::Literal { self.lit(token::Integer, Symbol::intern(n), None) } + fn typed_integer(&mut self, n: &str, kind: &str) -> Self::Literal { self.lit(token::Integer, Symbol::intern(n), Some(Symbol::intern(kind))) } + fn float(&mut self, n: &str) -> Self::Literal { self.lit(token::Float, Symbol::intern(n), None) } + fn f32(&mut self, n: &str) -> Self::Literal { self.lit(token::Float, Symbol::intern(n), Some(sym::f32)) } + fn f64(&mut self, n: &str) -> Self::Literal { self.lit(token::Float, Symbol::intern(n), Some(sym::f64)) } + fn string(&mut self, string: &str) -> Self::Literal { let quoted = format!("{:?}", string); assert!(quoted.starts_with('"') && quoted.ends_with('"')); let symbol = "ed[1..quoted.len() - 1]; self.lit(token::Str, Symbol::intern(symbol), None) } + fn character(&mut self, ch: char) -> Self::Literal { let quoted = format!("{:?}", ch); assert!(quoted.starts_with('\'') && quoted.ends_with('\'')); let symbol = "ed[1..quoted.len() - 1]; self.lit(token::Char, Symbol::intern(symbol), None) } + fn byte_string(&mut self, bytes: &[u8]) -> Self::Literal { let string = bytes .iter() @@ -678,12 +719,15 @@ impl server::Literal for Rustc<'_, '_> { .collect::(); self.lit(token::ByteStr, Symbol::intern(&string), None) } + fn span(&mut self, literal: &Self::Literal) -> Self::Span { literal.span } + fn set_span(&mut self, literal: &mut Self::Literal, span: Self::Span) { literal.span = span; } + fn subspan( &mut self, literal: &Self::Literal, @@ -726,6 +770,7 @@ impl server::SourceFile for Rustc<'_, '_> { fn eq(&mut self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool { Lrc::ptr_eq(file1, file2) } + fn path(&mut self, file: &Self::SourceFile) -> String { match file.name { FileName::Real(ref name) => name @@ -737,6 +782,7 @@ impl server::SourceFile for Rustc<'_, '_> { _ => file.name.prefer_local().to_string(), } } + fn is_real(&mut self, file: &Self::SourceFile) -> bool { file.is_real_file() } @@ -746,6 +792,7 @@ impl server::MultiSpan for Rustc<'_, '_> { fn new(&mut self) -> Self::MultiSpan { vec![] } + fn push(&mut self, spans: &mut Self::MultiSpan, span: Self::Span) { spans.push(span) } @@ -757,6 +804,7 @@ impl server::Diagnostic for Rustc<'_, '_> { diag.set_span(MultiSpan::from_spans(spans)); diag } + fn sub( &mut self, diag: &mut Self::Diagnostic, @@ -766,6 +814,7 @@ impl server::Diagnostic for Rustc<'_, '_> { ) { diag.sub(level.to_internal(), msg, MultiSpan::from_spans(spans), None); } + fn emit(&mut self, mut diag: Self::Diagnostic) { self.sess().span_diagnostic.emit_diagnostic(&mut diag); } @@ -779,38 +828,49 @@ impl server::Span for Rustc<'_, '_> { format!("{:?} bytes({}..{})", span.ctxt(), span.lo().0, span.hi().0) } } + fn def_site(&mut self) -> Self::Span { self.def_site } + fn call_site(&mut self) -> Self::Span { self.call_site } + fn mixed_site(&mut self) -> Self::Span { self.mixed_site } + fn source_file(&mut self, span: Self::Span) -> Self::SourceFile { self.sess().source_map().lookup_char_pos(span.lo()).file } + fn parent(&mut self, span: Self::Span) -> Option { span.parent_callsite() } + fn source(&mut self, span: Self::Span) -> Self::Span { span.source_callsite() } + fn start(&mut self, span: Self::Span) -> LineColumn { let loc = self.sess().source_map().lookup_char_pos(span.lo()); LineColumn { line: loc.line, column: loc.col.to_usize() } } + fn end(&mut self, span: Self::Span) -> LineColumn { let loc = self.sess().source_map().lookup_char_pos(span.hi()); LineColumn { line: loc.line, column: loc.col.to_usize() } } + fn before(&mut self, span: Self::Span) -> Self::Span { span.shrink_to_lo() } + fn after(&mut self, span: Self::Span) -> Self::Span { span.shrink_to_hi() } + fn join(&mut self, first: Self::Span, second: Self::Span) -> Option { let self_loc = self.sess().source_map().lookup_char_pos(first.lo()); let other_loc = self.sess().source_map().lookup_char_pos(second.lo()); @@ -821,9 +881,11 @@ impl server::Span for Rustc<'_, '_> { Some(first.to(second)) } + fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span { span.with_ctxt(at.ctxt()) } + fn source_text(&mut self, span: Self::Span) -> Option { self.sess().source_map().span_to_snippet(span).ok() } @@ -854,6 +916,7 @@ impl server::Span for Rustc<'_, '_> { fn save_span(&mut self, span: Self::Span) -> usize { self.sess().save_proc_macro_span(span) } + fn recover_proc_macro_span(&mut self, id: usize) -> Self::Span { let (resolver, krate, def_site) = (&*self.ecx.resolver, self.krate, self.def_site); *self.rebased_spans.entry(id).or_insert_with(|| { diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 693159f9ae..8b7153776e 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -22,7 +22,7 @@ fn string_to_parser(ps: &ParseSess, source_str: String) -> Parser<'_> { new_parser_from_source_str(ps, PathBuf::from("bogofile").into(), source_str) } -crate fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T +pub(crate) fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T where F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>, { @@ -33,7 +33,7 @@ where } /// Maps a string to tts, using a made-up filename. -crate fn string_to_stream(source_str: String) -> TokenStream { +pub(crate) fn string_to_stream(source_str: String) -> TokenStream { let ps = ParseSess::new(FilePathMapping::empty()); source_file_to_stream( &ps, @@ -44,7 +44,7 @@ crate fn string_to_stream(source_str: String) -> TokenStream { } /// Parses a string, returns a crate. -crate fn string_to_crate(source_str: String) -> ast::Crate { +pub(crate) fn string_to_crate(source_str: String) -> ast::Crate { let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| p.parse_crate_mod()) } @@ -53,7 +53,7 @@ crate fn string_to_crate(source_str: String) -> ast::Crate { /// may be deleted or replaced with other whitespace to match the pattern. /// This function is relatively Unicode-ignorant; fortunately, the careful design /// of UTF-8 mitigates this ignorance. It doesn't do NKF-normalization(?). -crate fn matches_codepattern(a: &str, b: &str) -> bool { +pub(crate) fn matches_codepattern(a: &str, b: &str) -> bool { let mut a_iter = a.chars().peekable(); let mut b_iter = b.chars().peekable(); @@ -109,7 +109,7 @@ struct SpanLabel { label: &'static str, } -crate struct Shared { +pub(crate) struct Shared { pub data: Arc>, } diff --git a/compiler/rustc_expand/src/tokenstream/tests.rs b/compiler/rustc_expand/src/tokenstream/tests.rs index 31052bfb54..e4a4db204d 100644 --- a/compiler/rustc_expand/src/tokenstream/tests.rs +++ b/compiler/rustc_expand/src/tokenstream/tests.rs @@ -4,7 +4,6 @@ use rustc_ast::token; use rustc_ast::tokenstream::{Spacing, TokenStream, TokenStreamBuilder, TokenTree}; use rustc_span::create_default_session_globals_then; use rustc_span::{BytePos, Span, Symbol}; -use smallvec::smallvec; fn string_to_ts(string: &str) -> TokenStream { string_to_stream(string.to_owned()) @@ -24,7 +23,10 @@ fn test_concat() { let test_res = string_to_ts("foo::bar::baz"); let test_fst = string_to_ts("foo::bar"); let test_snd = string_to_ts("::baz"); - let eq_res = TokenStream::from_streams(smallvec![test_fst, test_snd]); + let mut builder = TokenStreamBuilder::new(); + builder.push(test_fst); + builder.push(test_snd); + let eq_res = builder.build(); assert_eq!(test_res.trees().count(), 5); assert_eq!(eq_res.trees().count(), 5); assert_eq!(test_res.eq_unspanned(&eq_res), true); @@ -35,7 +37,7 @@ fn test_concat() { fn test_to_from_bijection() { create_default_session_globals_then(|| { let test_start = string_to_ts("foo::bar(baz)"); - let test_end = test_start.trees().collect(); + let test_end = test_start.trees().cloned().collect(); assert_eq!(test_start, test_end) }) } diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 048039343a..099c40b215 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -142,6 +142,8 @@ declare_features! ( (accepted, dyn_trait, "1.27.0", Some(44662), None), /// Allows integer match exhaustiveness checking (RFC 2591). (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None), + /// Allows explicit generic arguments specification with `impl Trait` present. + (accepted, explicit_generic_args_with_impl_trait, "1.63.0", Some(83701), None), /// Allows arbitrary expressions in key-value attributes at parse time. (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None), /// Allows resolving absolute paths as paths from other crates. @@ -219,8 +221,12 @@ declare_features! ( (accepted, move_ref_pattern, "1.49.0", Some(68354), None), /// Allows specifying modifiers in the link attribute: `#[link(modifiers = "...")]` (accepted, native_link_modifiers, "1.61.0", Some(81490), None), + /// Allows specifying the bundle link modifier + (accepted, native_link_modifiers_bundle, "1.63.0", Some(81490), None), /// Allows specifying the whole-archive link modifier (accepted, native_link_modifiers_whole_archive, "1.61.0", Some(81490), None), + /// Allows using non lexical lifetimes (RFC 2094). + (accepted, nll, "1.63.0", Some(43234), None), /// Allows using `#![no_std]`. (accepted, no_std, "1.6.0", None, None), /// Allows defining identifiers beyond ASCII. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 520769d308..b54f0ef361 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -150,6 +150,8 @@ declare_features! ( (active, allow_internal_unstable, "1.0.0", None, None), /// Allows identifying the `compiler_builtins` crate. (active, compiler_builtins, "1.13.0", None, None), + /// Outputs useful `assert!` messages + (active, generic_assert, "1.63.0", None, None), /// Allows using the `rust-intrinsic`'s "ABI". (active, intrinsics, "1.0.0", None, None), /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic. @@ -319,6 +321,8 @@ declare_features! ( (active, cfg_sanitize, "1.41.0", Some(39699), None), /// Allows `cfg(target_abi = "...")`. (active, cfg_target_abi, "1.55.0", Some(80970), None), + /// Allows `cfg(target(abi = "..."))`. + (active, cfg_target_compact, "1.63.0", Some(96901), None), /// Allows `cfg(target_has_atomic_load_store = "...")`. (active, cfg_target_has_atomic, "1.60.0", Some(94039), None), /// Allows `cfg(target_has_atomic_equal_alignment = "...")`. @@ -351,8 +355,6 @@ declare_features! ( (active, const_trait_impl, "1.42.0", Some(67792), None), /// Allows the `?` operator in const contexts. (active, const_try, "1.56.0", Some(74935), None), - /// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`. - (active, crate_visibility_modifier, "1.23.0", Some(53120), None), /// Allows non-builtin attributes in inner attribute position. (active, custom_inner_attributes, "1.30.0", Some(54726), None), /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. @@ -381,8 +383,6 @@ declare_features! ( (active, exclusive_range_pattern, "1.11.0", Some(37854), None), /// Allows exhaustive pattern matching on types that contain uninhabited types. (active, exhaustive_patterns, "1.13.0", Some(51085), None), - /// Allows explicit generic arguments specification with `impl Trait` present. - (active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None), /// Allows defining `extern type`s. (active, extern_types, "1.23.0", Some(43467), None), /// Allows the use of `#[ffi_const]` on foreign functions. @@ -409,8 +409,6 @@ declare_features! ( (active, if_let_guard, "1.47.0", Some(51114), None), /// Allows using imported `main` function (active, imported_main, "1.53.0", Some(28937), None), - /// Allows inferring `'static` outlives requirements (RFC 2093). - (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None), /// Allows associated types in inherent impls. (incomplete, inherent_associated_types, "1.52.0", Some(8995), None), /// Allow anonymous constants from an inline `const` block @@ -449,8 +447,6 @@ declare_features! ( (active, naked_functions, "1.9.0", Some(32408), None), /// Allows specifying the as-needed link modifier (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None), - /// Allows specifying the bundle link modifier - (active, native_link_modifiers_bundle, "1.53.0", Some(81490), None), /// Allows specifying the verbatim link modifier (active, native_link_modifiers_verbatim, "1.53.0", Some(81490), None), /// Allow negative trait implementations. @@ -459,8 +455,6 @@ declare_features! ( (active, never_type, "1.13.0", Some(35121), None), /// Allows diverging expressions to fall back to `!` rather than `()`. (active, never_type_fallback, "1.41.0", Some(65992), None), - /// Allows using non lexical lifetimes (RFC 2094). - (active, nll, "1.0.0", Some(43234), None), /// Allows `#![no_core]`. (active, no_core, "1.3.0", Some(29639), None), /// Allows function attribute `#[no_coverage]`, to bypass coverage @@ -496,12 +490,12 @@ declare_features! ( (incomplete, repr128, "1.16.0", Some(56071), None), /// Allows `repr(simd)` and importing the various simd intrinsics. (active, repr_simd, "1.4.0", Some(27731), None), + /// Allows `extern "rust-cold"`. + (active, rust_cold_cc, "1.63.0", Some(97544), None), /// Allows the use of SIMD types in functions declared in `extern` blocks. (active, simd_ffi, "1.0.0", Some(27731), None), /// Allows specialization of implementations (RFC 1210). (incomplete, specialization, "1.7.0", Some(31844), None), - /// Allows `#[link(kind="static-nobundle"...)]`. - (active, static_nobundle, "1.16.0", Some(37403), None), /// Allows attributes on expressions and non-item statements. (active, stmt_expr_attributes, "1.6.0", Some(15701), None), /// Allows lints part of the strict provenance effort. @@ -527,7 +521,7 @@ declare_features! ( (active, type_ascription, "1.6.0", Some(23416), None), /// Allows creation of instances of a struct by moving fields that have /// not changed from prior instances of the same struct (RFC #2528) - (incomplete, type_changing_struct_update, "1.58.0", Some(86555), None), + (active, type_changing_struct_update, "1.58.0", Some(86555), None), /// Allows unsized fn parameters. (active, unsized_fn_params, "1.49.0", Some(48055), None), /// Allows unsized rvalues at arguments and parameters. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 097493e898..6fcdfe44d8 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -9,7 +9,7 @@ use crate::{Features, Stability}; use rustc_data_structures::fx::FxHashMap; use rustc_span::symbol::{sym, Symbol}; -use std::lazy::SyncLazy; +use std::sync::LazyLock; type GateFn = fn(&Features) -> bool; @@ -399,7 +399,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // RFC #3191: #[debugger_visualizer] support gated!( - debugger_visualizer, Normal, template!(List: r#"natvis_file = "...""#), + debugger_visualizer, Normal, template!(List: r#"natvis_file = "...", gdb_script_file = "...""#), DuplicatesOk, experimental!(debugger_visualizer) ), @@ -473,9 +473,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // RFC 2632 gated!( - default_method_body_is_const, Normal, template!(Word), WarnFollowing, const_trait_impl, - "`default_method_body_is_const` is a temporary placeholder for declaring default bodies \ - as `const`, which may be removed or renamed in the future." + const_trait, Normal, template!(Word), WarnFollowing, const_trait_impl, + "`const` is a temporary placeholder for marking a trait that is suitable for `const` \ + `impls` and all default bodies as `const`, which may be removed or renamed in the \ + future." ), // lang-team MCP 147 gated!( @@ -488,11 +489,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // ========================================================================== ungated!(feature, CrateLevel, template!(List: "name1, name2, ..."), DuplicatesOk), - // FIXME(jhpratt) remove this eventually - ungated!( - rustc_deprecated, Normal, - template!(List: r#"since = "version", note = "...""#), ErrorFollowing - ), // DuplicatesOk since it has its own validation ungated!( stable, Normal, template!(List: r#"feature = "name", since = "version""#), DuplicatesOk, @@ -614,6 +610,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Used by the `rustc::potential_query_instability` lint to warn methods which // might not be stable during incremental compilation. rustc_attr!(rustc_lint_query_instability, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE), + // Used by the `rustc::untranslatable_diagnostic` and `rustc::diagnostic_outside_of_impl` lints + // to assist in changes to diagnostic APIs. + rustc_attr!(rustc_lint_diagnostics, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE), // ========================================================================== // Internal attributes, Const related: @@ -674,6 +673,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \ the given type by annotating all impl items with #[rustc_allow_incoherent_impl]." ), + rustc_attr!( + rustc_box, AttributeType::Normal, template!(Word), ErrorFollowing, + "#[rustc_box] allows creating boxes \ + and it is only intended to be used in `alloc`." + ), + BuiltinAttribute { name: sym::rustc_diagnostic_item, // FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`. @@ -804,8 +809,8 @@ pub fn is_builtin_only_local(name: Symbol) -> bool { BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| attr.only_local) } -pub static BUILTIN_ATTRIBUTE_MAP: SyncLazy> = - SyncLazy::new(|| { +pub static BUILTIN_ATTRIBUTE_MAP: LazyLock> = + LazyLock::new(|| { let mut map = FxHashMap::default(); for attr in BUILTIN_ATTRIBUTES.iter() { if map.insert(attr.name, attr).is_some() { diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 26e0538b0e..efb8305276 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -11,7 +11,6 @@ //! even if it is stabilized or removed, *do not remove it*. Instead, move the //! symbol to the `accepted` or `removed` modules respectively. -#![cfg_attr(bootstrap, feature(derive_default_enum))] #![feature(once_cell)] mod accepted; diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index fae9bd633a..54626caaf5 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -72,6 +72,8 @@ declare_features! ( /// Allows `T: ?const Trait` syntax in bounds. (removed, const_trait_bound_opt_out, "1.42.0", Some(67794), None, Some("Removed in favor of `~const` bound in #![feature(const_trait_impl)]")), + /// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`. + (removed, crate_visibility_modifier, "1.63.0", Some(53120), None, Some("removed in favor of `pub(crate)`")), /// Allows using custom attributes (RFC 572). (removed, custom_attribute, "1.0.0", Some(29642), None, Some("removed in favor of `#![register_tool]` and `#![register_attr]`")), @@ -107,6 +109,9 @@ declare_features! ( /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`). (removed, in_band_lifetimes, "1.23.0", Some(44524), None, Some("removed due to unsolved ergonomic questions and added lifetime resolution complexity")), + /// Allows inferring `'static` outlives requirements (RFC 2093). + (removed, infer_static_outlives_requirements, "1.63.0", Some(54185), None, + Some("removed as it caused some confusion and discussion was inactive for years")), /// Lazily evaluate constants. This allows constants to depend on type parameters. (removed, lazy_normalization_consts, "1.46.0", Some(72219), None, Some("superseded by `generic_const_exprs`")), /// Allows using the `#[link_args]` attribute. @@ -167,6 +172,9 @@ declare_features! ( (removed, sanitizer_runtime, "1.17.0", None, None, None), (removed, simd, "1.0.0", Some(27731), None, Some("removed in favor of `#[repr(simd)]`")), + /// Allows `#[link(kind = "static-nobundle", ...)]`. + (removed, static_nobundle, "1.16.0", Some(37403), None, + Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#)), (removed, struct_inherit, "1.0.0", None, None, None), (removed, test_removed_feature, "1.0.0", None, None, None), /// Allows using items which are missing stability attributes diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 676c66f41a..6eaff5c2f7 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -273,7 +273,6 @@ html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] -#![feature(nll)] use LabelText::*; diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 34d366f401..47ace7ca3a 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -8,7 +8,6 @@ doctest = false [dependencies] rustc_target = { path = "../rustc_target" } -rustc_feature = { path = "../rustc_feature" } rustc_macros = { path = "../rustc_macros" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index a639df01a7..d0893cd09d 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -1,9 +1,9 @@ -use crate::def_id::DefId; use crate::hir; use rustc_ast as ast; use rustc_ast::NodeId; use rustc_macros::HashStable_Generic; +use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::hygiene::MacroKind; use rustc_span::Symbol; @@ -92,6 +92,7 @@ pub enum DefKind { /// [RFC 2593]: https://github.com/rust-lang/rfcs/pull/2593 Ctor(CtorOf, CtorKind), /// Associated function: `impl MyStruct { fn associated() {} }` + /// or `trait Foo { fn associated() {} }` AssocFn, /// Associated constant: `trait MyTrait { const ASSOC: usize; }` AssocConst, @@ -670,7 +671,10 @@ impl Res { #[track_caller] pub fn expect_non_local(self) -> Res { - self.map_id(|_| panic!("unexpected `Res::Local`")) + self.map_id( + #[track_caller] + |_| panic!("unexpected `Res::Local`"), + ) } pub fn macro_kind(self) -> Option { @@ -707,3 +711,44 @@ impl Res { matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..)) } } + +/// Resolution for a lifetime appearing in a type. +#[derive(Copy, Clone, Debug)] +pub enum LifetimeRes { + /// Successfully linked the lifetime to a generic parameter. + Param { + /// Id of the generic parameter that introduced it. + param: LocalDefId, + /// Id of the introducing place. That can be: + /// - an item's id, for the item's generic parameters; + /// - a TraitRef's ref_id, identifying the `for<...>` binder; + /// - a BareFn type's id. + /// + /// This information is used for impl-trait lifetime captures, to know when to or not to + /// capture any given lifetime. + binder: NodeId, + }, + /// Created a generic parameter for an anonymous lifetime. + Fresh { + /// Id of the generic parameter that introduced it. + /// + /// Creating the associated `LocalDefId` is the responsibility of lowering. + param: NodeId, + /// Id of the introducing place. See `Param`. + binder: NodeId, + }, + /// This variant is used for anonymous lifetimes that we did not resolve during + /// late resolution. Shifting the work to the HIR lifetime resolver. + Anonymous { + /// Id of the introducing place. See `Param`. + binder: NodeId, + /// Whether this lifetime was spelled or elided. + elided: bool, + }, + /// Explicit `'static` lifetime. + Static, + /// Resolution failure. + Error, + /// HACK: This is used to recover the NodeId of an elided lifetime. + ElidedAnchor { start: NodeId, end: NodeId }, +} diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 5c32dd372d..5f8801cc4e 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -11,9 +11,7 @@ use crate::def_path_hash_map::DefPathHashMap; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; use rustc_index::vec::IndexVec; -use rustc_span::hygiene::ExpnId; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::Span; use std::fmt::{self, Write}; use std::hash::Hash; @@ -101,11 +99,6 @@ pub struct Definitions { table: DefPathTable, next_disambiguator: FxHashMap<(LocalDefId, DefPathData), u32>, - /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. - expansions_that_defined: FxHashMap, - - def_id_to_span: IndexVec, - /// The [StableCrateId] of the local crate. stable_crate_id: StableCrateId, } @@ -323,7 +316,7 @@ impl Definitions { } /// Adds a root definition (no parent) and a few other reserved definitions. - pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions { + pub fn new(stable_crate_id: StableCrateId) -> Definitions { let key = DefKey { parent: None, disambiguated_data: DisambiguatedDefPathData { @@ -340,30 +333,12 @@ impl Definitions { let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) }; assert_eq!(root.local_def_index, CRATE_DEF_INDEX); - let mut def_id_to_span = IndexVec::new(); - // A relative span's parent must be an absolute span. - debug_assert_eq!(crate_span.data_untracked().parent, None); - let _root = def_id_to_span.push(crate_span); - debug_assert_eq!(_root, root); - - Definitions { - table, - next_disambiguator: Default::default(), - expansions_that_defined: Default::default(), - def_id_to_span, - stable_crate_id, - } + Definitions { table, next_disambiguator: Default::default(), stable_crate_id } } /// Adds a definition with a parent definition. - pub fn create_def( - &mut self, - parent: LocalDefId, - data: DefPathData, - expn_id: ExpnId, - span: Span, - ) -> LocalDefId { - debug!("create_def(parent={:?}, data={:?}, expn_id={:?})", parent, data, expn_id); + pub fn create_def(&mut self, parent: LocalDefId, data: DefPathData) -> LocalDefId { + debug!("create_def(parent={:?}, data={:?})", parent, data); // The root node must be created with `create_root_def()`. assert!(data != DefPathData::CrateRoot); @@ -386,28 +361,7 @@ impl Definitions { debug!("create_def: after disambiguation, key = {:?}", key); // Create the definition. - let def_id = LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) }; - - if expn_id != ExpnId::root() { - self.expansions_that_defined.insert(def_id, expn_id); - } - - // A relative span's parent must be an absolute span. - debug_assert_eq!(span.data_untracked().parent, None); - let _id = self.def_id_to_span.push(span); - debug_assert_eq!(_id, def_id); - - def_id - } - - pub fn expansion_that_defined(&self, id: LocalDefId) -> ExpnId { - self.expansions_that_defined.get(&id).copied().unwrap_or_else(ExpnId::root) - } - - /// Retrieves the span of the given `DefId` if `DefId` is in the local crate. - #[inline] - pub fn def_span(&self, def_id: LocalDefId) -> Span { - self.def_id_to_span[def_id] + LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) } } pub fn iter_local_def_id(&self) -> impl Iterator + '_ { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index dc88d86698..a7fc59255d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,6 +1,6 @@ use crate::def::{CtorKind, DefKind, Res}; use crate::def_id::DefId; -crate use crate::hir_id::{HirId, ItemLocalId}; +pub(crate) use crate::hir_id::{HirId, ItemLocalId}; use crate::intravisit::FnKind; use crate::LangItem; @@ -26,7 +26,7 @@ use rustc_target::spec::abi::Abi; use smallvec::SmallVec; use std::fmt; -#[derive(Copy, Clone, Encodable, HashStable_Generic)] +#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)] pub struct Lifetime { pub hir_id: HirId, pub span: Span, @@ -60,7 +60,7 @@ pub enum ParamName { /// ``` /// where `'f` is something like `Fresh(0)`. The indices are /// unique per impl, but not necessarily continuous. - Fresh(LocalDefId), + Fresh, /// Indicates an illegal name was given and an error has been /// reported (so we should squelch other derived errors). Occurs @@ -72,9 +72,7 @@ impl ParamName { pub fn ident(&self) -> Ident { match *self { ParamName::Plain(ident) => ident, - ParamName::Fresh(_) | ParamName::Error => { - Ident::with_dummy_span(kw::UnderscoreLifetime) - } + ParamName::Fresh | ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime), } } @@ -90,7 +88,7 @@ impl ParamName { #[derive(HashStable_Generic)] pub enum LifetimeName { /// User-given names or fresh (synthetic) names. - Param(ParamName), + Param(LocalDefId, ParamName), /// User wrote nothing (e.g., the lifetime in `&u32`). Implicit, @@ -127,7 +125,18 @@ impl LifetimeName { | LifetimeName::Error => Ident::empty(), LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime), LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime), - LifetimeName::Param(param_name) => param_name.ident(), + LifetimeName::Param(_, param_name) => param_name.ident(), + } + } + + pub fn is_anonymous(&self) -> bool { + match *self { + LifetimeName::ImplicitObjectLifetimeDefault + | LifetimeName::Implicit + | LifetimeName::Underscore + | LifetimeName::Param(_, ParamName::Fresh) + | LifetimeName::Error => true, + LifetimeName::Static | LifetimeName::Param(..) => false, } } @@ -137,12 +146,12 @@ impl LifetimeName { | LifetimeName::Implicit | LifetimeName::Underscore => true, - // It might seem surprising that `Fresh(_)` counts as + // It might seem surprising that `Fresh` counts as // *not* elided -- but this is because, as far as the code - // in the compiler is concerned -- `Fresh(_)` variants act + // in the compiler is concerned -- `Fresh` variants act // equivalently to "some fresh name". They correspond to // early-bound regions on an impl, in other words. - LifetimeName::Error | LifetimeName::Param(_) | LifetimeName::Static => false, + LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false, } } @@ -152,8 +161,8 @@ impl LifetimeName { pub fn normalize_to_macros_2_0(&self) -> LifetimeName { match *self { - LifetimeName::Param(param_name) => { - LifetimeName::Param(param_name.normalize_to_macros_2_0()) + LifetimeName::Param(def_id, param_name) => { + LifetimeName::Param(def_id, param_name.normalize_to_macros_2_0()) } lifetime_name => lifetime_name, } @@ -166,12 +175,6 @@ impl fmt::Display for Lifetime { } } -impl fmt::Debug for Lifetime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "lifetime({}: {})", self.hir_id, self.name.ident()) - } -} - impl Lifetime { pub fn is_elided(&self) -> bool { self.name.is_elided() @@ -343,12 +346,12 @@ pub struct GenericArgs<'hir> { pub span_ext: Span, } -impl GenericArgs<'_> { +impl<'hir> GenericArgs<'hir> { pub const fn none() -> Self { Self { args: &[], bindings: &[], parenthesized: false, span_ext: DUMMY_SP } } - pub fn inputs(&self) -> &[Ty<'_>] { + pub fn inputs(&self) -> &[Ty<'hir>] { if self.parenthesized { for arg in self.args { match arg { @@ -532,7 +535,7 @@ pub struct GenericParamCount { pub struct Generics<'hir> { pub params: &'hir [GenericParam<'hir>], pub predicates: &'hir [WherePredicate<'hir>], - pub has_where_clause: bool, + pub has_where_clause_predicates: bool, pub where_clause_span: Span, pub span: Span, } @@ -542,14 +545,14 @@ impl<'hir> Generics<'hir> { const NOPE: Generics<'_> = Generics { params: &[], predicates: &[], - has_where_clause: false, + has_where_clause_predicates: false, where_clause_span: DUMMY_SP, span: DUMMY_SP, }; &NOPE } - pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'_>> { + pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'hir>> { for param in self.params { if name == param.name.ident().name { return Some(param); @@ -578,21 +581,11 @@ impl<'hir> Generics<'hir> { } } - pub fn where_clause_span(&self) -> Option { - if self.predicates.is_empty() { None } else { Some(self.where_clause_span) } - } - - /// The `where_span` under normal circumstances points at either the predicates or the empty - /// space where the `where` clause should be. Only of use for diagnostic suggestions. - pub fn span_for_predicates_or_empty_place(&self) -> Span { - self.where_clause_span - } - /// `Span` where further predicates would be suggested, accounting for trailing commas, like /// in `fn foo(t: T) where T: Foo,` so we don't suggest two trailing commas. pub fn tail_span_for_predicate_suggestion(&self) -> Span { - let end = self.span_for_predicates_or_empty_place().shrink_to_hi(); - if self.has_where_clause { + let end = self.where_clause_span.shrink_to_hi(); + if self.has_where_clause_predicates { self.predicates .iter() .filter(|p| p.in_where_clause()) @@ -605,10 +598,21 @@ impl<'hir> Generics<'hir> { } } + pub fn add_where_or_trailing_comma(&self) -> &'static str { + if self.has_where_clause_predicates { + "," + } else if self.where_clause_span.is_empty() { + " where" + } else { + // No where clause predicates, but we have `where` token + "" + } + } + pub fn bounds_for_param( &self, param_def_id: LocalDefId, - ) -> impl Iterator> { + ) -> impl Iterator> { self.predicates.iter().filter_map(move |pred| match pred { WherePredicate::BoundPredicate(bp) if bp.is_param_bound(param_def_id.to_def_id()) => { Some(bp) @@ -617,6 +621,16 @@ impl<'hir> Generics<'hir> { }) } + pub fn outlives_for_param( + &self, + param_def_id: LocalDefId, + ) -> impl Iterator> { + self.predicates.iter().filter_map(move |pred| match pred { + WherePredicate::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp), + _ => None, + }) + } + pub fn bounds_span_for_suggestions(&self, param_def_id: LocalDefId) -> Option { self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map( |bound| { @@ -758,6 +772,16 @@ pub struct WhereRegionPredicate<'hir> { pub bounds: GenericBounds<'hir>, } +impl<'hir> WhereRegionPredicate<'hir> { + /// Returns `true` if `param_def_id` matches the `lifetime` of this predicate. + pub fn is_param_bound(&self, param_def_id: LocalDefId) -> bool { + match self.lifetime.name { + LifetimeName::Param(id, _) => id == param_def_id, + _ => false, + } + } +} + /// An equality predicate (e.g., `T = int`); currently unsupported. #[derive(Debug, HashStable_Generic)] pub struct WhereEqPredicate<'hir> { @@ -796,7 +820,6 @@ impl<'tcx> AttributeMap<'tcx> { /// Map of all HIR nodes inside the current owner. /// These nodes are mapped by `ItemLocalId` alongside the index of their parent node. /// The HIR tree, including bodies, is pre-hashed. -#[derive(Debug)] pub struct OwnerNodes<'tcx> { /// Pre-computed hash of the full HIR. pub hash_including_bodies: Fingerprint, @@ -822,6 +845,18 @@ impl<'tcx> OwnerNodes<'tcx> { } } +impl fmt::Debug for OwnerNodes<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OwnerNodes") + .field("node", &self.nodes[ItemLocalId::from_u32(0)]) + .field("bodies", &self.bodies) + .field("local_id_to_def_id", &self.local_id_to_def_id) + .field("hash_without_bodies", &self.hash_without_bodies) + .field("hash_including_bodies", &self.hash_including_bodies) + .finish() + } +} + /// Full information resulting from lowering an AST node. #[derive(Debug, HashStable_Generic)] pub struct OwnerInfo<'hir> { @@ -1320,8 +1355,21 @@ pub struct Let<'hir> { #[derive(Debug, HashStable_Generic)] pub enum Guard<'hir> { If(&'hir Expr<'hir>), - // FIXME use hir::Let for this. - IfLet(&'hir Pat<'hir>, &'hir Expr<'hir>), + IfLet(&'hir Let<'hir>), +} + +impl<'hir> Guard<'hir> { + /// Returns the body of the guard + /// + /// In other words, returns the e in either of the following: + /// + /// - `if e` + /// - `if let x = e` + pub fn body(&self) -> &'hir Expr<'hir> { + match self { + Guard::If(e) | Guard::IfLet(Let { init: e, .. }) => e, + } + } } #[derive(Debug, HashStable_Generic)] @@ -1346,7 +1394,7 @@ pub enum UnsafeSource { UserProvided, } -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] pub struct BodyId { pub hir_id: HirId, } @@ -1604,7 +1652,7 @@ impl Expr<'_> { ExprKind::Let(..) => ExprPrecedence::Let, ExprKind::Loop(..) => ExprPrecedence::Loop, ExprKind::Match(..) => ExprPrecedence::Match, - ExprKind::Closure(..) => ExprPrecedence::Closure, + ExprKind::Closure { .. } => ExprPrecedence::Closure, ExprKind::Block(..) => ExprPrecedence::Block, ExprKind::Assign(..) => ExprPrecedence::Assign, ExprKind::AssignOp(..) => ExprPrecedence::AssignOp, @@ -1664,7 +1712,7 @@ impl Expr<'_> { | ExprKind::Tup(..) | ExprKind::If(..) | ExprKind::Match(..) - | ExprKind::Closure(..) + | ExprKind::Closure { .. } | ExprKind::Block(..) | ExprKind::Repeat(..) | ExprKind::Array(..) @@ -1747,7 +1795,7 @@ impl Expr<'_> { | ExprKind::Match(..) | ExprKind::MethodCall(..) | ExprKind::Call(..) - | ExprKind::Closure(..) + | ExprKind::Closure { .. } | ExprKind::Block(..) | ExprKind::Repeat(..) | ExprKind::Break(..) @@ -1766,6 +1814,20 @@ impl Expr<'_> { | ExprKind::Err => true, } } + + // To a first-order approximation, is this a pattern + pub fn is_approximately_pattern(&self) -> bool { + match &self.kind { + ExprKind::Box(_) + | ExprKind::Array(_) + | ExprKind::Call(..) + | ExprKind::Tup(_) + | ExprKind::Lit(_) + | ExprKind::Path(_) + | ExprKind::Struct(..) => true, + _ => false, + } + } } /// Checks if the specified expression is a built-in range literal. @@ -1824,7 +1886,7 @@ pub enum ExprKind<'hir> { /// To resolve the called method to a `DefId`, call [`type_dependent_def_id`] with /// the `hir_id` of the `MethodCall` node itself. /// - /// [`type_dependent_def_id`]: ../ty/struct.TypeckResults.html#method.type_dependent_def_id + /// [`type_dependent_def_id`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.type_dependent_def_id MethodCall(&'hir PathSegment<'hir>, &'hir [Expr<'hir>], Span), /// A tuple (e.g., `(a, b, c, d)`). Tup(&'hir [Expr<'hir>]), @@ -1868,7 +1930,14 @@ pub enum ExprKind<'hir> { /// /// This may also be a generator literal or an `async block` as indicated by the /// `Option`. - Closure(CaptureBy, &'hir FnDecl<'hir>, BodyId, Span, Option), + Closure { + capture_clause: CaptureBy, + bound_generic_params: &'hir [GenericParam<'hir>], + fn_decl: &'hir FnDecl<'hir>, + body: BodyId, + fn_decl_span: Span, + movability: Option, + }, /// A block (e.g., `'label: { ... }`). Block(&'hir Block<'hir>, Option -The `State` trait defines the behavior shared by different post states, and the -`Draft`, `PendingReview`, and `Published` states will all implement the `State` -trait. For now, the trait doesn’t have any methods, and we’ll start by defining -just the `Draft` state because that is the state we want a post to start in. +The `State` trait defines the behavior shared by different post states. The +state objects are `Draft`, `PendingReview`, and `Published`, and they will all +implement the `State` trait. For now, the trait doesn’t have any methods, and +we’ll start by defining just the `Draft` state because that is the state we +want a post to start in. When we create a new `Post`, we set its `state` field to a `Some` value that -holds a `Box`. This `Box` points to a new instance of the `Draft` struct. This -ensures whenever we create a new instance of `Post`, it will start out as a -draft. Because the `state` field of `Post` is private, there is no way to +holds a `Box`. This `Box` points to a new instance of the `Draft` struct. +This ensures whenever we create a new instance of `Post`, it will start out as +a draft. Because the `state` field of `Post` is private, there is no way to create a `Post` in any other state! In the `Post::new` function, we set the `content` field to a new, empty `String`. ### Storing the Text of the Post Content -Listing 17-11 showed that we want to be able to call a method named -`add_text` and pass it a `&str` that is then added to the text content of the -blog post. We implement this as a method rather than exposing the `content` -field as `pub`. This means we can implement a method later that will control -how the `content` field’s data is read. The `add_text` method is pretty +We saw in Listing 17-11 that we want to be able to call a method named +`add_text` and pass it a `&str` that is then added as the text content of the +blog post. We implement this as a method, rather than exposing the `content` +field as `pub`, so that later we can implement a method that will control how +the `content` field’s data is read. The `add_text` method is pretty straightforward, so let’s add the implementation in Listing 17-13 to the `impl Post` block: @@ -164,7 +176,7 @@ reference to `self`. Then we call an internal `request_review` method on the current state of `Post`, and this second `request_review` method consumes the current state and returns a new state. -We’ve added the `request_review` method to the `State` trait; all types that +We add the `request_review` method to the `State` trait; all types that implement the trait will now need to implement the `request_review` method. Note that rather than having `self`, `&self`, or `&mut self` as the first parameter of the method, we have `self: Box`. This syntax means the @@ -185,12 +197,12 @@ with code like `self.state = self.state.request_review();` to get ownership of the `state` value. This ensures `Post` can’t use the old `state` value after we’ve transformed it into a new state. -The `request_review` method on `Draft` needs to return a new, boxed instance of -a new `PendingReview` struct, which represents the state when a post is waiting -for a review. The `PendingReview` struct also implements the `request_review` -method but doesn’t do any transformations. Rather, it returns itself, because -when we request a review on a post already in the `PendingReview` state, it -should stay in the `PendingReview` state. +The `request_review` method on `Draft` returns a new, boxed instance of a new +`PendingReview` struct, which represents the state when a post is waiting for a +review. The `PendingReview` struct also implements the `request_review` method +but doesn’t do any transformations. Rather, it returns itself, because when we +request a review on a post already in the `PendingReview` state, it should stay +in the `PendingReview` state. Now we can start seeing the advantages of the state pattern: the `request_review` method on `Post` is the same no matter its `state` value. Each @@ -201,7 +213,10 @@ slice. We can now have a `Post` in the `PendingReview` state as well as in the `Draft` state, but we want the same behavior in the `PendingReview` state. Listing 17-11 now works up to line 10! -### Adding the `approve` Method that Changes the Behavior of `content` + + + +### Adding `approve` to Change the Behavior of `content` The `approve` method will be similar to the `request_review` method: it will set `state` to the value that the current state says it should have when that @@ -228,7 +243,7 @@ method, it returns itself, because the post should stay in the `Published` state in those cases. Now we need to update the `content` method on `Post`. We want the value -returned from `content` to depend on the current state of the `Post`, so we're +returned from `content` to depend on the current state of the `Post`, so we’re going to have the `Post` delegate to a `content` method defined on its `state`, as shown in Listing 17-17: @@ -243,7 +258,7 @@ delegate to a `content` method on `State` Because the goal is to keep all these rules inside the structs that implement `State`, we call a `content` method on the value in `state` and pass the post -instance (that is, `self`) as an argument. Then we return the value that is +instance (that is, `self`) as an argument. Then we return the value that’s returned from using the `content` method on the `state` value. We call the `as_ref` method on the `Option` because we want a reference to the @@ -260,12 +275,12 @@ Compiler”][more-info-than-rustc] section of Chapter 9 when we know that a `None` value is never possible, even though the compiler isn’t able to understand that. -At this point, when we call `content` on the `&Box`, deref coercion will -take effect on the `&` and the `Box` so the `content` method will ultimately be -called on the type that implements the `State` trait. That means we need to add -`content` to the `State` trait definition, and that is where we’ll put the -logic for what content to return depending on which state we have, as shown in -Listing 17-18: +At this point, when we call `content` on the `&Box`, deref coercion +will take effect on the `&` and the `Box` so the `content` method will +ultimately be called on the type that implements the `State` trait. That means +we need to add `content` to the `State` trait definition, and that is where +we’ll put the logic for what content to return depending on which state we +have, as shown in Listing 17-18: Filename: src/lib.rs @@ -290,6 +305,15 @@ And we’re done—all of Listing 17-11 now works! We’ve implemented the state pattern with the rules of the blog post workflow. The logic related to the rules lives in the state objects rather than being scattered throughout `Post`. +> #### Why Not An Enum? +> +> You may have been wondering why we didn’t use an `enum` with the different +> possible post states as variants. That’s certainly a possible solution, try +> it and compare the end results to see which you prefer! One disadvantage of +> using an enum is every place that checks the value of the enum will need a +> `match` expression or similar to handle every possible variant. This could +> get more repetitive than this trait object solution. + ### Trade-offs of the State Pattern We’ve shown that Rust is capable of implementing the object-oriented state @@ -458,10 +482,10 @@ now impossible because of the type system and the type checking that happens at compile time! This ensures that certain bugs, such as display of the content of an unpublished post, will be discovered before they make it to production. -Try the tasks suggested for additional requirements that we mentioned at the -start of this section on the `blog` crate as it is after Listing 17-20 to see -what you think about the design of this version of the code. Note that some of -the tasks might be completed already in this design. +Try the tasks suggested at the start of this section on the `blog` crate as it +is after Listing 17-21 to see what you think about the design of this version +of the code. Note that some of the tasks might be completed already in this +design. We’ve seen that even though Rust is capable of implementing object-oriented design patterns, other patterns, such as encoding state into the type system, diff --git a/src/doc/book/src/ch18-00-patterns.md b/src/doc/book/src/ch18-00-patterns.md index e1cc752642..dc9290e331 100644 --- a/src/doc/book/src/ch18-00-patterns.md +++ b/src/doc/book/src/ch18-00-patterns.md @@ -1,6 +1,6 @@ # Patterns and Matching -Patterns are a special syntax in Rust for matching against the structure of +*Patterns* are a special syntax in Rust for matching against the structure of types, both complex and simple. Using patterns in conjunction with `match` expressions and other constructs gives you more control over a program’s control flow. A pattern consists of some combination of the following: @@ -11,9 +11,10 @@ control flow. A pattern consists of some combination of the following: * Wildcards * Placeholders -These components describe the shape of the data we’re working with, which we -then match against values to determine whether our program has the correct data -to continue running a particular piece of code. +Some example patterns include `x`, `(a, 3)`, and `Some(Color::Red)`. In the +contexts in which patterns are valid, these components describe the shape of +data. Our program then matches values against the patterns to determine whether +it has the correct shape of data to continue running a particular piece of code. To use a pattern, we compare it to some value. If the pattern matches the value, we use the value parts in our code. Recall the `match` expressions in diff --git a/src/doc/book/src/ch18-01-all-the-places-for-patterns.md b/src/doc/book/src/ch18-01-all-the-places-for-patterns.md index 42dddcaf1e..58f5af573b 100644 --- a/src/doc/book/src/ch18-01-all-the-places-for-patterns.md +++ b/src/doc/book/src/ch18-01-all-the-places-for-patterns.md @@ -19,16 +19,29 @@ match VALUE { } ``` +For example, here's the `match` expression from Listing 6-5 that matches on an +`Option` value in the variable `x`: + +```rust,ignore +match x { + None => None, + Some(i) => Some(i + 1), +} +``` + +The patterns in this `match` expression are the `None` and `Some(i)` on the +left of each arrow. + One requirement for `match` expressions is that they need to be *exhaustive* in the sense that all possibilities for the value in the `match` expression must be accounted for. One way to ensure you’ve covered every possibility is to have a catchall pattern for the last arm: for example, a variable name matching any value can never fail and thus covers every remaining case. -A particular pattern `_` will match anything, but it never binds to a variable, -so it’s often used in the last match arm. The `_` pattern can be useful when -you want to ignore any value not specified, for example. We’ll cover the `_` -pattern in more detail in the [“Ignoring Values in a +The particular pattern `_` will match anything, but it never binds to a +variable, so it’s often used in the last match arm. The `_` pattern can be +useful when you want to ignore any value not specified, for example. We’ll +cover the `_` pattern in more detail in the [“Ignoring Values in a Pattern”][ignoring-values-in-a-pattern] section later in this chapter. @@ -42,11 +55,11 @@ the pattern in the `if let` doesn’t match. Listing 18-1 shows that it’s also possible to mix and match `if let`, `else if`, and `else if let` expressions. Doing so gives us more flexibility than a `match` expression in which we can express only one value to compare with the -patterns. Also, the conditions in a series of `if let`, `else if`, `else if -let` arms aren’t required to relate to each other. +patterns. Also, Rust doesn't require that the conditions in a series of `if +let`, `else if`, `else if let` arms relate to each other. -The code in Listing 18-1 shows a series of checks for several conditions that -decide what the background color should be. For this example, we’ve created +The code in Listing 18-1 determines what color to make your background based on +a series of checks for several conditions. For this example, we’ve created variables with hardcoded values that a real program might receive from user input. @@ -59,11 +72,12 @@ input. Listing 18-1: Mixing `if let`, `else if`, `else if let`, and `else` -If the user specifies a favorite color, that color is the background color. If -today is Tuesday, the background color is green. If the user specifies -their age as a string and we can parse it as a number successfully, the color -is either purple or orange depending on the value of the number. If none of -these conditions apply, the background color is blue. +If the user specifies a favorite color, that color is used as the background. +If no favorite color is specified and today is Tuesday, the background color is +green. Otherwise, if the user specifies their age as a string and we can parse +it as a number successfully, the color is either purple or orange depending on +the value of the number. If none of these conditions apply, the background +color is blue. This conditional structure lets us support complex requirements. With the hardcoded values we have here, this example will print `Using purple as the @@ -78,16 +92,16 @@ shadowed `age` we want to compare to 30 isn’t valid until the new scope starts with the curly bracket. The downside of using `if let` expressions is that the compiler doesn’t check -exhaustiveness, whereas with `match` expressions it does. If we omitted the +for exhaustiveness, whereas with `match` expressions it does. If we omitted the last `else` block and therefore missed handling some cases, the compiler would not alert us to the possible logic bug. ### `while let` Conditional Loops Similar in construction to `if let`, the `while let` conditional loop allows a -`while` loop to run for as long as a pattern continues to match. The example in -Listing 18-2 shows a `while let` loop that uses a vector as a stack and prints -the values in the vector in the opposite order in which they were pushed. +`while` loop to run for as long as a pattern continues to match. In Listing +18-2 we code a `while let` loop that uses a vector as a stack and prints the +values in the vector in the opposite order in which they were pushed. ```rust {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-02/src/main.rs:here}} @@ -104,13 +118,10 @@ use `while let` to pop every element off our stack. ### `for` Loops -In Chapter 3, we mentioned that the `for` loop is the most common loop -construction in Rust code, but we haven’t yet discussed the pattern that `for` -takes. In a `for` loop, the pattern is the value that directly follows the -keyword `for`, so in `for x in y` the `x` is the pattern. - -Listing 18-3 demonstrates how to use a pattern in a `for` loop to destructure, -or break apart, a tuple as part of the `for` loop. +In a `for` loop, the value that directly follows the keyword `for` is a +pattern. For example, in `for x in y` the `x` is the pattern. Listing 18-3 +demonstrates how to use a pattern in a `for` loop to destructure, or break +apart, a tuple as part of the `for` loop. ```rust {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-03/src/main.rs:here}} @@ -125,11 +136,11 @@ The code in Listing 18-3 will print the following: {{#include ../listings/ch18-patterns-and-matching/listing-18-03/output.txt}} ``` -We use the `enumerate` method to adapt an iterator to produce a value and that -value’s index in the iterator, placed into a tuple. The first value produced is -the tuple `(0, 'a')`. When this value is matched to the pattern `(index, -value)`, `index` will be `0` and `value` will be `'a'`, printing the first line -of the output. +We adapt an iterator using the `enumerate` method so it produces a value and +the index for that value, placed into a tuple. The first value produced is the +tuple `(0, 'a')`. When this value is matched to the pattern `(index, value)`, +`index` will be `0` and `value` will be `'a'`, printing the first line of the +output. ### `let` Statements @@ -142,9 +153,9 @@ variable assignment with `let`: let x = 5; ``` -Throughout this book, we’ve used `let` like this hundreds of times, and -although you might not have realized it, you were using patterns! More -formally, a `let` statement looks like this: +Every time you've used a `let` statement like this you've been using patterns, +although you might not have realized it! More formally, a `let` statement looks +like this: ```text let PATTERN = EXPRESSION; @@ -190,8 +201,8 @@ Attempting to compile this code results in this type error: {{#include ../listings/ch18-patterns-and-matching/listing-18-05/output.txt}} ``` -If we wanted to ignore one or more of the values in the tuple, we could use `_` -or `..`, as you’ll see in the [“Ignoring Values in a +To fix the error, we could ignore one or more of the values in the tuple using +`_` or `..`, as you’ll see in the [“Ignoring Values in a Pattern”][ignoring-values-in-a-pattern] section. If the problem is that we have too many variables in the pattern, the solution is to make the types match by removing variables so the number of variables equals the number diff --git a/src/doc/book/src/ch18-02-refutability.md b/src/doc/book/src/ch18-02-refutability.md index 431721e01c..be3c31765c 100644 --- a/src/doc/book/src/ch18-02-refutability.md +++ b/src/doc/book/src/ch18-02-refutability.md @@ -47,11 +47,11 @@ use a refutable pattern where an irrefutable pattern is required: Because we didn’t cover (and couldn’t cover!) every valid value with the pattern `Some(x)`, Rust rightfully produces a compiler error. -To fix the problem where we have a refutable pattern where an irrefutable -pattern is needed, we can change the code that uses the pattern: instead of -using `let`, we can use `if let`. Then if the pattern doesn’t match, the code -will just skip the code in the curly brackets, giving it a way to continue -validly. Listing 18-9 shows how to fix the code in Listing 18-8. +If we have a refutable pattern where an irrefutable pattern is needed, we can +fix it by changing the code that uses the pattern: instead of using `let`, we +can use `if let`. Then if the pattern doesn’t match, the code will just skip +the code in the curly brackets, giving it a way to continue validly. Listing +18-9 shows how to fix the code in Listing 18-8. ```rust {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-09/src/main.rs:here}} diff --git a/src/doc/book/src/ch18-03-pattern-syntax.md b/src/doc/book/src/ch18-03-pattern-syntax.md index 903c206dda..aeaa766ff3 100644 --- a/src/doc/book/src/ch18-03-pattern-syntax.md +++ b/src/doc/book/src/ch18-03-pattern-syntax.md @@ -1,8 +1,7 @@ ## Pattern Syntax -Throughout the book, you’ve seen examples of many kinds of patterns. In this -section, we gather all the syntax valid in patterns and discuss why you might -want to use each one. +In this section, we gather all the syntax valid in patterns and discuss why and +when you might want to use each one. ### Matching Literals @@ -70,10 +69,10 @@ ignore --> section. ### Multiple Patterns In `match` expressions, you can match multiple patterns using the `|` syntax, -which means *or*. For example, the following code matches the value of `x` -against the match arms, the first of which has an *or* option, meaning if the -value of `x` matches either of the values in that arm, that arm’s code will -run: +which is the pattern *or* operator. For example, in the following code we match +the value of `x` against the match arms, the first of which has an *or* option, +meaning if the value of `x` matches either of the values in that arm, that +arm’s code will run: ```rust {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/src/main.rs:here}} @@ -84,22 +83,22 @@ This code prints `one or two`. ### Matching Ranges of Values with `..=` The `..=` syntax allows us to match to an inclusive range of values. In the -following code, when a pattern matches any of the values within the range, that -arm will execute: +following code, when a pattern matches any of the values within the given +range, that arm will execute: ```rust {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs:here}} ``` If `x` is 1, 2, 3, 4, or 5, the first arm will match. This syntax is more -convenient than using the `|` operator to express the same idea; instead of -`1..=5`, we would have to specify `1 | 2 | 3 | 4 | 5` if we used `|`. +convenient for multiple match values than using the `|` operator to express the +same idea; if we were to use `|` we would have to specify `1 | 2 | 3 | 4 | 5`. Specifying a range is much shorter, especially if we want to match, say, any number between 1 and 1,000! -Ranges are only allowed with numeric values or `char` values, because the -compiler checks that the range isn’t empty at compile time. The only types for -which Rust can tell if a range is empty or not are `char` and numeric values. +The compiler checks that the range isn’t empty at compile time, and because the +only types for which Rust can tell if a range is empty or not are `char` and +numeric values, ranges are only allowed with numeric or `char` values. Here is an example using ranges of `char` values: @@ -131,17 +130,15 @@ separate variables This code creates the variables `a` and `b` that match the values of the `x` and `y` fields of the `p` struct. This example shows that the names of the -variables in the pattern don’t have to match the field names of the struct. But -it’s common to want the variable names to match the field names to make it -easier to remember which variables came from which fields. - -Because having variable names match the fields is common and because writing -`let Point { x: x, y: y } = p;` contains a lot of duplication, there is a -shorthand for patterns that match struct fields: you only need to list the name -of the struct field, and the variables created from the pattern will have the -same names. Listing 18-13 shows code that behaves in the same way as the code -in Listing 18-12, but the variables created in the `let` pattern are `x` and -`y` instead of `a` and `b`. +variables in the pattern don’t have to match the field names of the struct. +However, it’s common to match the variable names to the field names to make it +easier to remember which variables came from which fields. Because of this +common usage, and because writing `let Point { x: x, y: y } = p;` contains a +lot of duplication, Rust has a shorthand for patterns that match struct fields: +you only need to list the name of the struct field, and the variables created +from the pattern will have the same names. Listing 18-13 behaves in the same +way as the code in Listing 18-12, but the variables created in the `let` +pattern are `x` and `y` instead of `a` and `b`. Filename: src/main.rs @@ -161,9 +158,9 @@ rather than creating variables for all the fields. Doing so allows us to test some of the fields for particular values while creating variables to destructure the other fields. -Listing 18-14 shows a `match` expression that separates `Point` values into -three cases: points that lie directly on the `x` axis (which is true when `y = -0`), on the `y` axis (`x = 0`), or neither. +In Listing 18-14, we have a `match` expression that separates `Point` values +into three cases: points that lie directly on the `x` axis (which is true when +`y = 0`), on the `y` axis (`x = 0`), or neither. Filename: src/main.rs @@ -186,12 +183,15 @@ matches any other `Point` and creates variables for both the `x` and `y` fields. In this example, the value `p` matches the second arm by virtue of `x` containing a 0, so this code will print `On the y axis at 7`. +Remember that a `match` expression stops checking arms once it has found the +first matching pattern, so even though `Point { x: 0, y: 0}` is on the `x` axis +and the `y` axis, this code would only print `On the x axis at 0`. + #### Destructuring Enums -We’ve destructured enums earlier in this book, for example, when we -destructured `Option` in Listing 6-5 in Chapter 6. One detail we haven’t -mentioned explicitly is that the pattern to destructure an enum should -correspond to the way the data stored within the enum is defined. As an +We've destructured enums in this book (for example, Listing 6-5 in Chapter 6), +but haven’t yet explicitly discussed that the pattern to destructure an enum +corresponds to the way the data stored within the enum is defined. As an example, in Listing 18-15 we use the `Message` enum from Listing 6-2 and write a `match` with patterns that will destructure each inner value. @@ -225,11 +225,10 @@ matching. #### Destructuring Nested Structs and Enums -Until now, all our examples have been matching structs or enums that were one -level deep. Matching can work on nested items too! - -For example, we can refactor the code in Listing 18-15 to support RGB and HSV -colors in the `ChangeColor` message, as shown in Listing 18-16. +So far, our examples have all been matching structs or enums one level deep, +but matching can work on nested items too! For example, we can refactor the +code in Listing 18-15 to support RGB and HSV colors in the `ChangeColor` +message, as shown in Listing 18-16. ```rust {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-16/src/main.rs}} @@ -241,8 +240,8 @@ The pattern of the first arm in the `match` expression matches a `Message::ChangeColor` enum variant that contains a `Color::Rgb` variant; then the pattern binds to the three inner `i32` values. The pattern of the second arm also matches a `Message::ChangeColor` enum variant, but the inner enum -matches the `Color::Hsv` variant instead. We can specify these complex -conditions in one `match` expression, even though two enums are involved. +matches `Color::Hsv` instead. We can specify these complex conditions in one +`match` expression, even though two enums are involved. #### Destructuring Structs and Tuples @@ -272,10 +271,10 @@ parts of a value. Let’s explore how and why to use each of these patterns. #### Ignoring an Entire Value with `_` -We’ve used the underscore (`_`) as a wildcard pattern that will match any value -but not bind to the value. Although the underscore `_` pattern is especially -useful as the last arm in a `match` expression, we can use it in any pattern, -including function parameters, as shown in Listing 18-17. +We’ve used the underscore as a wildcard pattern that will match any value but +not bind to the value. This is especially useful as the last arm in a `match` +expression, but we can also use it in any pattern, including function +parameters, as shown in Listing 18-17. Filename: src/main.rs @@ -285,16 +284,16 @@ including function parameters, as shown in Listing 18-17. Listing 18-17: Using `_` in a function signature -This code will completely ignore the value passed as the first argument, `3`, +This code will completely ignore the value `3` passed as the first argument, and will print `This code only uses the y parameter: 4`. In most cases when you no longer need a particular function parameter, you would change the signature so it doesn’t include the unused parameter. Ignoring -a function parameter can be especially useful in some cases, for example, when -implementing a trait when you need a certain type signature but the function -body in your implementation doesn’t need one of the parameters. The compiler -will then not warn about unused function parameters, as it would if you used a -name instead. +a function parameter can be especially useful in cases when, for example, +you're implementing a trait when you need a certain type signature but the +function body in your implementation doesn’t need one of the parameters. You +then avoid getting a compiler warning about unused function parameters, as you +would if you used a name instead. #### Ignoring Parts of a Value with a Nested `_` @@ -317,7 +316,7 @@ This code will print `Can't overwrite an existing customized value` and then `setting is Some(5)`. In the first match arm, we don’t need to match on or use the values inside either `Some` variant, but we do need to test for the case when `setting_value` and `new_setting_value` are the `Some` variant. In that -case, we print why we’re not changing `setting_value`, and it doesn’t get +case, we print the reason for not changing `setting_value`, and it doesn’t get changed. In all other cases (if either `setting_value` or `new_setting_value` are @@ -340,12 +339,12 @@ ignored. #### Ignoring an Unused Variable by Starting Its Name with `_` If you create a variable but don’t use it anywhere, Rust will usually issue a -warning because that could be a bug. But sometimes it’s useful to create a -variable you won’t use yet, such as when you’re prototyping or just starting a -project. In this situation, you can tell Rust not to warn you about the unused -variable by starting the name of the variable with an underscore. In Listing -18-20, we create two unused variables, but when we compile this code, we should -only get a warning about one of them. +warning because an unused variable could be a bug. However, sometimes it’s +useful to be able to create a variable you won’t use yet, such as when you’re +prototyping or just starting a project. In this situation, you can tell Rust +not to warn you about the unused variable by starting the name of the variable +with an underscore. In Listing 18-20, we create two unused variables, but when +we compile this code, we should only get a warning about one of them. Filename: src/main.rs @@ -357,7 +356,7 @@ only get a warning about one of them. underscore to avoid getting unused variable warnings Here we get a warning about not using the variable `y`, but we don’t get a -warning about not using the variable preceded by the underscore. +warning about not using `_x`. Note that there is a subtle difference between using only `_` and using a name that starts with an underscore. The syntax `_x` still binds the value to the @@ -387,7 +386,7 @@ This code works just fine because we never bind `s` to anything; it isn’t move #### Ignoring Remaining Parts of a Value with `..` -With values that have many parts, we can use the `..` syntax to use only a few +With values that have many parts, we can use the `..` syntax to use specific parts and ignore the rest, avoiding the need to list underscores for each ignored value. The `..` pattern ignores any parts of a value that we haven’t explicitly matched in the rest of the pattern. In Listing 18-23, we have a @@ -452,10 +451,9 @@ compiler error because using `..` in two places like this is ambiguous. ### Extra Conditionals with Match Guards -A *match guard* is an additional `if` condition specified after the pattern in -a `match` arm that must also match, along with the pattern matching, for that -arm to be chosen. Match guards are useful for expressing more complex ideas -than a pattern alone allows. +A *match guard* is an additional `if` condition, specified after the pattern in +a `match` arm, that must also match for that arm to be chosen. Match guards are +useful for expressing more complex ideas than a pattern alone allows. The condition can use variables created in the pattern. Listing 18-26 shows a `match` where the first arm has the pattern `Some(x)` and also has a match @@ -483,7 +481,7 @@ this additional expressiveness is that the compiler doesn't try to check for exhaustiveness when match guard expressions are involved. In Listing 18-11, we mentioned that we could use match guards to solve our -pattern-shadowing problem. Recall that a new variable was created inside the +pattern-shadowing problem. Recall that we created a new variable inside the pattern in the `match` expression instead of using the variable outside the `match`. That new variable meant we couldn’t test against the value of the outer variable. Listing 18-27 shows how we can use a match guard to fix this @@ -512,10 +510,10 @@ we can look for a value that has the same value as the outer `y` by comparing You can also use the *or* operator `|` in a match guard to specify multiple patterns; the match guard condition will apply to all the patterns. Listing -18-28 shows the precedence of combining a match guard with a pattern that uses -`|`. The important part of this example is that the `if y` match guard applies -to `4`, `5`, *and* `6`, even though it might look like `if y` only applies to -`6`. +18-28 shows the precedence when combining a pattern that uses `|` with a match +guard. The important part of this example is that the `if y` match guard +applies to `4`, `5`, *and* `6`, even though it might look like `if y` only +applies to `6`. ```rust {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-28/src/main.rs:here}} @@ -550,13 +548,12 @@ were applied only to the final value in the list of values specified using the ### `@` Bindings -The *at* operator (`@`) lets us create a variable that holds a value at the -same time we’re testing that value to see whether it matches a pattern. Listing -18-29 shows an example where we want to test that a `Message::Hello` `id` field -is within the range `3..=7`. But we also want to bind the value to the variable -`id_variable` so we can use it in the code associated with the arm. We could -name this variable `id`, the same as the field, but for this example we’ll use -a different name. +The *at* operator `@` lets us create a variable that holds a value at the same +time as we’re testing that value for a pattern match. In Listing 18-29, we want +to test that a `Message::Hello` `id` field is within the range `3..=7`. We also +want to bind the value to the variable `id_variable` so we can use it in the +code associated with the arm. We could name this variable `id`, the same as the +field, but for this example we’ll use a different name. ```rust {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-29/src/main.rs:here}} @@ -586,11 +583,11 @@ Using `@` lets us test a value and save it in a variable within one pattern. ## Summary -Rust’s patterns are very useful in that they help distinguish between different -kinds of data. When used in `match` expressions, Rust ensures your patterns -cover every possible value, or your program won’t compile. Patterns in `let` -statements and function parameters make those constructs more useful, enabling -the destructuring of values into smaller parts at the same time as assigning to +Rust’s patterns are very useful in distinguishing between different kinds of +data. When used in `match` expressions, Rust ensures your patterns cover every +possible value, or your program won’t compile. Patterns in `let` statements and +function parameters make those constructs more useful, enabling the +destructuring of values into smaller parts at the same time as assigning to variables. We can create simple or complex patterns to suit our needs. Next, for the penultimate chapter of the book, we’ll look at some advanced diff --git a/src/doc/book/src/ch19-00-advanced-features.md b/src/doc/book/src/ch19-00-advanced-features.md index 270d6da6d1..a0db41fde4 100644 --- a/src/doc/book/src/ch19-00-advanced-features.md +++ b/src/doc/book/src/ch19-00-advanced-features.md @@ -2,11 +2,11 @@ By now, you’ve learned the most commonly used parts of the Rust programming language. Before we do one more project in Chapter 20, we’ll look at a few -aspects of the language you might run into every once in a while. You can use -this chapter as a reference for when you encounter any unknowns when using -Rust. The features you’ll learn to use in this chapter are useful in very -specific situations. Although you might not reach for them often, we want to -make sure you have a grasp of all the features Rust has to offer. +aspects of the language you might run into every once in a while, but may not +use every day. You can use this chapter as a reference for when you encounter +any unknowns. The features covered here are useful in very specific situations. +Although you might not reach for them often, we want to make sure you have a +grasp of all the features Rust has to offer. In this chapter, we’ll cover: diff --git a/src/doc/book/src/ch19-01-unsafe-rust.md b/src/doc/book/src/ch19-01-unsafe-rust.md index 97caf8a9b8..24e33fb918 100644 --- a/src/doc/book/src/ch19-01-unsafe-rust.md +++ b/src/doc/book/src/ch19-01-unsafe-rust.md @@ -7,13 +7,13 @@ and works just like regular Rust, but gives us extra superpowers. Unsafe Rust exists because, by nature, static analysis is conservative. When the compiler tries to determine whether or not code upholds the guarantees, -it’s better for it to reject some valid programs rather than accept some -invalid programs. Although the code *might* be okay, if the Rust compiler -doesn’t have enough information to be confident, it will reject the code. In -these cases, you can use unsafe code to tell the compiler, “Trust me, I know -what I’m doing.” The downside is that you use it at your own risk: if you use -unsafe code incorrectly, problems due to memory unsafety, such as null pointer -dereferencing, can occur. +it’s better for it to reject some valid programs than to accept some invalid +programs. Although the code *might* be okay, if the Rust compiler doesn’t have +enough information to be confident, it will reject the code. In these cases, +you can use unsafe code to tell the compiler, “Trust me, I know what I’m +doing.” Be warned, however, that you use unsafe Rust at your own risk: if you +use unsafe code incorrectly, problems can occur due to memory unsafety, such as +null pointer dereferencing. Another reason Rust has an unsafe alter ego is that the underlying computer hardware is inherently unsafe. If Rust didn’t let you do unsafe operations, you @@ -26,9 +26,9 @@ Rust and how to do it. ### Unsafe Superpowers To switch to unsafe Rust, use the `unsafe` keyword and then start a new block -that holds the unsafe code. You can take five actions in unsafe Rust, called -*unsafe superpowers*, that you can’t in safe Rust. Those superpowers include -the ability to: +that holds the unsafe code. You can take five actions in unsafe Rust that you +can’t in safe Rust, which we call *unsafe superpowers*. Those superpowers +include the ability to: * Dereference a raw pointer * Call an unsafe function or method @@ -107,12 +107,13 @@ directly from references guaranteed to be valid, we know these particular raw pointers are valid, but we can’t make that assumption about just any raw pointer. -Next, we’ll create a raw pointer whose validity we can’t be so certain of. -Listing 19-2 shows how to create a raw pointer to an arbitrary location in -memory. Trying to use arbitrary memory is undefined: there might be data at -that address or there might not, the compiler might optimize the code so there -is no memory access, or the program might error with a segmentation fault. -Usually, there is no good reason to write code like this, but it is possible. +To demonstrate this, next we’ll create a raw pointer whose validity we can’t be +so certain of. Listing 19-2 shows how to create a raw pointer to an arbitrary +location in memory. Trying to use arbitrary memory is undefined: there might be +data at that address or there might not, the compiler might optimize the code +so there is no memory access, or the program might error with a segmentation +fault. Usually, there is no good reason to write code like this, but it is +possible. ```rust {{#rustdoc_include ../listings/ch19-advanced-features/listing-19-02/src/main.rs:here}} @@ -154,14 +155,14 @@ abstraction that uses unsafe code. ### Calling an Unsafe Function or Method -The second type of operation that requires an unsafe block is calls to unsafe -functions. Unsafe functions and methods look exactly like regular functions and -methods, but they have an extra `unsafe` before the rest of the definition. The -`unsafe` keyword in this context indicates the function has requirements we -need to uphold when we call this function, because Rust can’t guarantee we’ve -met these requirements. By calling an unsafe function within an `unsafe` block, -we’re saying that we’ve read this function’s documentation and take -responsibility for upholding the function’s contracts. +The second type of operation you can perform in an unsafe block is calling +unsafe functions. Unsafe functions and methods look exactly like regular +functions and methods, but they have an extra `unsafe` before the rest of the +definition. The `unsafe` keyword in this context indicates the function has +requirements we need to uphold when we call this function, because Rust can’t +guarantee we’ve met these requirements. By calling an unsafe function within an +`unsafe` block, we’re saying that we’ve read this function’s documentation and +take responsibility for upholding the function’s contracts. Here is an unsafe function named `dangerous` that doesn’t do anything in its body: @@ -177,10 +178,9 @@ try to call `dangerous` without the `unsafe` block, we’ll get an error: {{#include ../listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt}} ``` -By inserting the `unsafe` block around our call to `dangerous`, we’re asserting -to Rust that we’ve read the function’s documentation, we understand how to use -it properly, and we’ve verified that we’re fulfilling the contract of the -function. +With the `unsafe` block, we’re asserting to Rust that we’ve read the function’s +documentation, we understand how to use it properly, and we’ve verified that +we’re fulfilling the contract of the function. Bodies of unsafe functions are effectively `unsafe` blocks, so to perform other unsafe operations within an unsafe function, we don’t need to add another @@ -190,10 +190,10 @@ unsafe operations within an unsafe function, we don’t need to add another Just because a function contains unsafe code doesn’t mean we need to mark the entire function as unsafe. In fact, wrapping unsafe code in a safe function is -a common abstraction. As an example, let’s study a function from the standard -library, `split_at_mut`, that requires some unsafe code and explore how we -might implement it. This safe method is defined on mutable slices: it takes one -slice and makes it two by splitting the slice at the index given as an +a common abstraction. As an example, let’s study the `split_at_mut` function +from the standard library, which requires some unsafe code. We’ll explore how +we might implement it. This safe method is defined on mutable slices: it takes +one slice and makes it two by splitting the slice at the index given as an argument. Listing 19-4 shows how to use `split_at_mut`. ```rust @@ -296,7 +296,7 @@ that the slice this code creates contains valid `i32` values. Attempting to use #### Using `extern` Functions to Call External Code Sometimes, your Rust code might need to interact with code written in another -language. For this, Rust has a keyword, `extern`, that facilitates the creation +language. For this, Rust has the keyword `extern` that facilitates the creation and use of a *Foreign Function Interface (FFI)*. An FFI is a way for a programming language to define functions and enable a different (foreign) programming language to call those functions. @@ -325,15 +325,15 @@ most common and follows the C programming language’s ABI. > #### Calling Rust Functions from Other Languages > > We can also use `extern` to create an interface that allows other languages -> to call Rust functions. Instead of an `extern` block, we add the `extern` -> keyword and specify the ABI to use just before the `fn` keyword. We also need -> to add a `#[no_mangle]` annotation to tell the Rust compiler not to mangle -> the name of this function. *Mangling* is when a compiler changes the name -> we’ve given a function to a different name that contains more information for -> other parts of the compilation process to consume but is less human readable. -> Every programming language compiler mangles names slightly differently, so -> for a Rust function to be nameable by other languages, we must disable the -> Rust compiler’s name mangling. +> to call Rust functions. Instead of an creating a whole `extern` block, we add +> the `extern` keyword and specify the ABI to use just before the `fn` keyword +> for the relevant function. We also need to add a `#[no_mangle]` annotation to +> tell the Rust compiler not to mangle the name of this function. *Mangling* is +> when a compiler changes the name we’ve given a function to a different name +> that contains more information for other parts of the compilation process to +> consume but is less human readable. Every programming language compiler +> mangles names slightly differently, so for a Rust function to be nameable by +> other languages, we must disable the Rust compiler’s name mangling. > > In the following example, we make the `call_from_c` function accessible from > C code, after it’s compiled to a shared library and linked from C: @@ -349,8 +349,8 @@ most common and follows the C programming language’s ABI. ### Accessing or Modifying a Mutable Static Variable -Until now, we’ve not talked about *global variables*, which Rust does support -but can be problematic with Rust’s ownership rules. If two threads are +In this book, we’ve not yet talked about *global variables*, which Rust does +support but can be problematic with Rust’s ownership rules. If two threads are accessing the same mutable global variable, it can cause a data race. In Rust, global variables are called *static* variables. Listing 19-9 shows an @@ -368,19 +368,17 @@ variable Static variables are similar to constants, which we discussed in the [“Differences Between Variables and -Constants”][differences-between-variables-and-constants] -section in Chapter 3. The names of static variables are in -`SCREAMING_SNAKE_CASE` by convention. Static variables can only store -references with the `'static` lifetime, which means the Rust compiler can -figure out the lifetime and we aren’t required to annotate it explicitly. -Accessing an immutable static variable is safe. - -Constants and immutable static variables might seem similar, but a subtle -difference is that values in a static variable have a fixed address in memory. -Using the value will always access the same data. Constants, on the other hand, -are allowed to duplicate their data whenever they’re used. - -Another difference between constants and static variables is that static +Constants”][differences-between-variables-and-constants] section +in Chapter 3. The names of static variables are in `SCREAMING_SNAKE_CASE` by +convention. Static variables can only store references with the `'static` +lifetime, which means the Rust compiler can figure out the lifetime and we +aren’t required to annotate it explicitly. Accessing an immutable static +variable is safe. + +A subtle difference between constants and immutable static variables is that +values in a static variable have a fixed address in memory. Using the value +will always access the same data. Constants, on the other hand, are allowed to +duplicate their data whenever they’re used. Another difference is that static variables can be mutable. Accessing and modifying mutable static variables is *unsafe*. Listing 19-10 shows how to declare, access, and modify a mutable static variable named `COUNTER`. @@ -408,11 +406,11 @@ that data accessed from different threads is done safely. ### Implementing an Unsafe Trait -Another use case for `unsafe` is implementing an unsafe trait. A trait is -unsafe when at least one of its methods has some invariant that the compiler -can’t verify. We can declare that a trait is `unsafe` by adding the `unsafe` -keyword before `trait` and marking the implementation of the trait as `unsafe` -too, as shown in Listing 19-11. +We can use `unsafe` to implement an unsafe trait. A trait is unsafe when at +least one of its methods has some invariant that the compiler can’t verify. We +declare that a trait is `unsafe` by adding the `unsafe` keyword before `trait` +and marking the implementation of the trait as `unsafe` too, as shown in +Listing 19-11. ```rust {{#rustdoc_include ../listings/ch19-advanced-features/listing-19-11/src/main.rs}} diff --git a/src/doc/book/src/ch19-03-advanced-traits.md b/src/doc/book/src/ch19-03-advanced-traits.md index 850d58830b..6fd3e09f49 100644 --- a/src/doc/book/src/ch19-03-advanced-traits.md +++ b/src/doc/book/src/ch19-03-advanced-traits.md @@ -9,10 +9,10 @@ about Rust, we can get into the nitty-gritty. *Associated types* connect a type placeholder with a trait such that the trait method definitions can use these placeholder types in their signatures. The -implementor of a trait will specify the concrete type to be used in this type’s -place for the particular implementation. That way, we can define a trait that -uses some types without needing to know exactly what those types are until the -trait is implemented. +implementor of a trait will specify the concrete type to be used instead of the +placeholder type for the particular implementation. That way, we can define a +trait that uses some types without needing to know exactly what those types are +until the trait is implemented. We’ve described most of the advanced features in this chapter as being rarely needed. Associated types are somewhere in the middle: they’re used more rarely @@ -32,18 +32,16 @@ iterating over. The definition of the `Iterator` trait is as shown in Listing Listing 19-12: The definition of the `Iterator` trait that has an associated type `Item` -The type `Item` is a placeholder type, and the `next` method’s definition shows -that it will return values of type `Option`. Implementors of the +The type `Item` is a placeholder, and the `next` method’s definition shows that +it will return values of type `Option`. Implementors of the `Iterator` trait will specify the concrete type for `Item`, and the `next` method will return an `Option` containing a value of that concrete type. Associated types might seem like a similar concept to generics, in that the latter allow us to define a function without specifying what types it can -handle. So why use associated types? - -Let’s examine the difference between the two concepts with an example that -implements the `Iterator` trait on a `Counter` struct. This implementation -specifies the `Item` type is `u32`: +handle. To examine the difference between the two concepts, we’ll look at an +implementation of the `Iterator` trait on a type named `Counter` that specifies +the `Item` type is `u32`: Filename: src/lib.rs @@ -77,17 +75,21 @@ definition that uses associated types, we can only choose what the type of We don’t have to specify that we want an iterator of `u32` values everywhere that we call `next` on `Counter`. +Associated types also become part of the trait’s contract: implementors of the +trait must provide a type to stand in for the associated type placeholder. +Associated types often have a name that describes how the type will be used, +and documenting the associated type in the API documentation is good practice. + ### Default Generic Type Parameters and Operator Overloading When we use generic type parameters, we can specify a default concrete type for the generic type. This eliminates the need for implementors of the trait to -specify a concrete type if the default type works. The syntax for specifying a -default type for a generic type is `` when -declaring the generic type. +specify a concrete type if the default type works. You specify a default type +when declaring a generic type with the `` syntax. -A great example of a situation where this technique is useful is with operator -overloading. *Operator overloading* is customizing the behavior of an operator -(such as `+`) in particular situations. +A great example of a situation where this technique is useful is with *operator +overloading*, in which you customize the behavior of an operator (such as `+`) +in particular situations. Rust doesn’t allow you to create your own operators or overload arbitrary operators. But you can overload the operations and corresponding traits listed @@ -241,10 +243,11 @@ trait to use based on the type of `self`. However, associated functions that are not methods don’t have a `self` parameter. When there are multiple types or traits that define non-method functions with the same function name, Rust doesn't always know which type you -mean unless you use *fully qualified syntax*. For example, the `Animal` trait -in Listing 19-19 has the associated non-method function `baby_name`, and the -`Animal` trait is implemented for the struct `Dog`. There’s also an associated -non-method function `baby_name` defined on `Dog` directly. +mean unless you use *fully qualified syntax*. For example, in Listing 19-19 we +create a trait for an animal shelter that wants to name all baby dogs *Spot*. +We make an `Animal` trait with an associated non-method function `baby_name`. +The `Animal` trait is implemented for the struct `Dog`, on which we also +provide an associated non-method function `baby_name` directly. Filename: src/main.rs @@ -256,12 +259,11 @@ non-method function `baby_name` defined on `Dog` directly. type with an associated function of the same name that also implements the trait -This code is for an animal shelter that wants to name all puppies Spot, which -is implemented in the `baby_name` associated function that is defined on `Dog`. -The `Dog` type also implements the trait `Animal`, which describes -characteristics that all animals have. Baby dogs are called puppies, and that -is expressed in the implementation of the `Animal` trait on `Dog` in the -`baby_name` function associated with the `Animal` trait. +We implement the code for naming all puppies Spot in the `baby_name` associated +function that is defined on `Dog`. The `Dog` type also implements the trait +`Animal`, which describes characteristics that all animals have. Baby dogs are +called puppies, and that is expressed in the implementation of the `Animal` +trait on `Dog` in the `baby_name` function associated with the `Animal` trait. In `main`, we call the `Dog::baby_name` function, which calls the associated function defined on `Dog` directly. This code prints the following: @@ -334,15 +336,18 @@ to identify which implementation you want to call. ### Using Supertraits to Require One Trait’s Functionality Within Another Trait -Sometimes, you might need one trait to use another trait’s functionality. In -this case, you need to rely on the dependent trait also being implemented. -The trait you rely on is a *supertrait* of the trait you’re implementing. +Sometimes, you might write a trait definition that depends on another trait: +for a type to implement the first trait, you want to require that type to also +implement the second trait. You would do this so that your trait definition can +make use of the associated items of the second trait. The trait your trait +definition is relying on is called a *supertrait* of your trait. For example, let’s say we want to make an `OutlinePrint` trait with an -`outline_print` method that will print a value framed in asterisks. That is, -given a `Point` struct that implements `Display` to result in `(x, y)`, when we -call `outline_print` on a `Point` instance that has `1` for `x` and `3` for -`y`, it should print the following: +`outline_print` method that will print a given value formatted so that it's +framed in asterisks. That is, given a `Point` struct that implements the +standard library trait `Display` to result in `(x, y)`, when we call +`outline_print` on a `Point` instance that has `1` for `x` and `3` for `y`, it +should print the following: ```text ********** @@ -352,12 +357,13 @@ call `outline_print` on a `Point` instance that has `1` for `x` and `3` for ********** ``` -In the implementation of `outline_print`, we want to use the `Display` trait’s -functionality. Therefore, we need to specify that the `OutlinePrint` trait will -work only for types that also implement `Display` and provide the functionality -that `OutlinePrint` needs. We can do that in the trait definition by specifying -`OutlinePrint: Display`. This technique is similar to adding a trait bound to -the trait. Listing 19-22 shows an implementation of the `OutlinePrint` trait. +In the implementation of the `outline_print` method, we want to use the +`Display` trait’s functionality. Therefore, we need to specify that the +`OutlinePrint` trait will work only for types that also implement `Display` and +provide the functionality that `OutlinePrint` needs. We can do that in the +trait definition by specifying `OutlinePrint: Display`. This technique is +similar to adding a trait bound to the trait. Listing 19-22 shows an +implementation of the `OutlinePrint` trait. Filename: src/main.rs @@ -406,18 +412,18 @@ it within an outline of asterisks. ### Using the Newtype Pattern to Implement External Traits on External Types In Chapter 10 in the [“Implementing a Trait on a -Type”][implementing-a-trait-on-a-type] section, we mentioned -the orphan rule that states we’re allowed to implement a trait on a type as -long as either the trait or the type are local to our crate. It’s possible to -get around this restriction using the *newtype pattern*, which involves -creating a new type in a tuple struct. (We covered tuple structs in the -[“Using Tuple Structs without Named Fields to Create Different -Types”][tuple-structs] section of Chapter 5.) The tuple struct -will have one field and be a thin wrapper around the type we want to implement -a trait for. Then the wrapper type is local to our crate, and we can implement -the trait on the wrapper. *Newtype* is a term that originates from the Haskell -programming language. There is no runtime performance penalty for using this -pattern, and the wrapper type is elided at compile time. +Type”][implementing-a-trait-on-a-type] section, we mentioned the +orphan rule that states we’re only allowed to implement a trait on a type if +either the trait or the type are local to our crate. It’s possible to get +around this restriction using the *newtype pattern*, which involves creating a +new type in a tuple struct. (We covered tuple structs in the [“Using Tuple +Structs without Named Fields to Create Different Types”][tuple-structs] section of Chapter 5.) The tuple struct will have one field and be a +thin wrapper around the type we want to implement a trait for. Then the wrapper +type is local to our crate, and we can implement the trait on the wrapper. +*Newtype* is a term that originates from the Haskell programming language. +There is no runtime performance penalty for using this pattern, and the wrapper +type is elided at compile time. As an example, let’s say we want to implement `Display` on `Vec`, which the orphan rule prevents us from doing directly because the `Display` trait and the @@ -450,9 +456,8 @@ the inner type would be a solution. If we don’t want the `Wrapper` type to hav all the methods of the inner type—for example, to restrict the `Wrapper` type’s behavior—we would have to implement just the methods we do want manually. -Now you know how the newtype pattern is used in relation to traits; it’s also a -useful pattern even when traits are not involved. Let’s switch focus and look -at some advanced ways to interact with Rust’s type system. +This newtype pattern is also useful even when traits are not involved. Let’s +switch focus and look at some advanced ways to interact with Rust’s type system. [newtype]: ch19-03-advanced-traits.html#using-the-newtype-pattern-to-implement-external-traits-on-external-types [implementing-a-trait-on-a-type]: diff --git a/src/doc/book/src/ch19-04-advanced-types.md b/src/doc/book/src/ch19-04-advanced-types.md index 07450ce90e..2dfed23cca 100644 --- a/src/doc/book/src/ch19-04-advanced-types.md +++ b/src/doc/book/src/ch19-04-advanced-types.md @@ -1,10 +1,10 @@ ## Advanced Types -The Rust type system has some features that we’ve mentioned in this book but -haven’t yet discussed. We’ll start by discussing newtypes in general as we -examine why newtypes are useful as types. Then we’ll move on to type aliases, a -feature similar to newtypes but with slightly different semantics. We’ll also -discuss the `!` type and dynamically sized types. +The Rust type system has some features that we’ve so far mentioned but haven’t +yet discussed. We’ll start by discussing newtypes in general as we examine why +newtypes are useful as types. Then we’ll move on to type aliases, a feature +similar to newtypes but with slightly different semantics. We’ll also discuss +the `!` type and dynamically sized types. ### Using the Newtype Pattern for Type Safety and Abstraction @@ -12,15 +12,16 @@ discuss the `!` type and dynamically sized types. > Newtype Pattern to Implement External Traits on External > Types.”][using-the-newtype-pattern] -The newtype pattern is useful for tasks beyond those we’ve discussed so far, -including statically enforcing that values are never confused and indicating -the units of a value. You saw an example of using newtypes to indicate units in -Listing 19-15: recall that the `Millimeters` and `Meters` structs wrapped `u32` -values in a newtype. If we wrote a function with a parameter of type -`Millimeters`, we couldn’t compile a program that accidentally tried to call -that function with a value of type `Meters` or a plain `u32`. +The newtype pattern is also useful for tasks beyond those we’ve discussed so +far, including statically enforcing that values are never confused and +indicating the units of a value. You saw an example of using newtypes to +indicate units in Listing 19-15: recall that the `Millimeters` and `Meters` +structs wrapped `u32` values in a newtype. If we wrote a function with a +parameter of type `Millimeters`, we couldn’t compile a program that +accidentally tried to call that function with a value of type `Meters` or a +plain `u32`. -Another use of the newtype pattern is in abstracting away some implementation +We can also use the newtype pattern to abstract away some implementation details of a type: the new type can expose a public API that is different from the API of the private inner type. @@ -37,9 +38,9 @@ section of Chapter 17. ### Creating Type Synonyms with Type Aliases -Along with the newtype pattern, Rust provides the ability to declare a *type -alias* to give an existing type another name. For this we use the `type` -keyword. For example, we can create the alias `Kilometers` to `i32` like so: +Rust provides the ability to declare a *type alias* to give an existing type +another name. For this we use the `type` keyword. For example, we can create +the alias `Kilometers` to `i32` like so: ```rust {{#rustdoc_include ../listings/ch19-advanced-features/no-listing-04-kilometers-alias/src/main.rs:here}} @@ -57,7 +58,9 @@ values of type `i32`: Because `Kilometers` and `i32` are the same type, we can add values of both types and we can pass `Kilometers` values to functions that take `i32` parameters. However, using this method, we don’t get the type checking benefits -that we get from the newtype pattern discussed earlier. +that we get from the newtype pattern discussed earlier. In other words, if we +mix up `Kilometers` and `i32` values somewhere, the compiler will not give us +an error. The main use case for type synonyms is to reduce repetition. For example, we might have a lengthy type like this: @@ -112,7 +115,7 @@ alias declaration: ``` Because this declaration is in the `std::io` module, we can use the fully -qualified alias `std::io::Result`—that is, a `Result` with the `E` +qualified alias `std::io::Result`; that is, a `Result` with the `E` filled in as `std::io::Error`. The `Write` trait function signatures end up looking like this: @@ -141,7 +144,8 @@ never are called *diverging functions*. We can’t create values of the type `!` so `bar` can never possibly return. But what use is a type you can never create values for? Recall the code from -Listing 2-5; we’ve reproduced part of it here in Listing 19-26. +Listing 2-5, part of the number guessing game; we’ve reproduced a bit of it +here in Listing 19-26. ```rust,ignore {{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs:ch19}} @@ -151,9 +155,9 @@ Listing 2-5; we’ve reproduced part of it here in Listing 19-26. `continue` At the time, we skipped over some details in this code. In Chapter 6 in [“The -`match` Control Flow Operator”][the-match-control-flow-operator] section, we discussed that `match` arms must all return the same type. So, -for example, the following code doesn’t work: +`match` Control Flow Operator”][the-match-control-flow-operator] +section, we discussed that `match` arms must all return the same type. So, for +example, the following code doesn’t work: ```rust,ignore,does_not_compile {{#rustdoc_include ../listings/ch19-advanced-features/no-listing-08-match-arms-different-types/src/main.rs:here}} @@ -175,9 +179,9 @@ be coerced into any other type. We’re allowed to end this `match` arm with back to the top of the loop, so in the `Err` case, we never assign a value to `guess`. -The never type is useful with the `panic!` macro as well. Remember the `unwrap` -function that we call on `Option` values to produce a value or panic? Here -is its definition: +The never type is useful with the `panic!` macro as well. Recall the `unwrap` +function that we call on `Option` values to produce a value or panic with +this definition: ```rust,ignore {{#rustdoc_include ../listings/ch19-advanced-features/no-listing-09-unwrap-definition/src/lib.rs:here}} @@ -201,11 +205,11 @@ when it got to the `break`. ### Dynamically Sized Types and the `Sized` Trait -Due to Rust’s need to know certain details, such as how much space to allocate -for a value of a particular type, there is a corner of its type system that can -be confusing: the concept of *dynamically sized types*. Sometimes referred to -as *DSTs* or *unsized types*, these types let us write code using values whose -size we can know only at runtime. +Rust needs to know certain details about its types, such as how much space to +allocate for a value of a particular type. This leaves one corner of its type +system a little confusing at first: the concept of *dynamically sized types*. +Sometimes referred to as *DSTs* or *unsized types*, these types let us write +code using values whose size we can know only at runtime. Let’s dig into the details of a dynamically sized type called `str`, which we’ve been using throughout the book. That’s right, not `&str`, but `str` on @@ -225,12 +229,11 @@ storage and `s2` needs 15. This is why it’s not possible to create a variable holding a dynamically sized type. So what do we do? In this case, you already know the answer: we make the types -of `s1` and `s2` a `&str` rather than a `str`. Recall that in the [“String -Slices”][string-slices] section of Chapter 4, we said the slice -data structure stores the starting position and the length of the slice. - -So although a `&T` is a single value that stores the memory address of where -the `T` is located, a `&str` is *two* values: the address of the `str` and its +of `s1` and `s2` a `&str` rather than a `str`. Recall from the [“String +Slices”][string-slices] section of Chapter 4 that the slice data +structure just stores the starting position and the length of the slice. So +although a `&T` is a single value that stores the memory address of where the +`T` is located, a `&str` is *two* values: the address of the `str` and its length. As such, we can know the size of a `&str` value at compile time: it’s twice the length of a `usize`. That is, we always know the size of a `&str`, no matter how long the string it refers to is. In general, this is the way in @@ -249,11 +252,11 @@ ignore --> section, we mentioned that to use traits as trait objects, we must put them behind a pointer, such as `&dyn Trait` or `Box` (`Rc` would work too). -To work with DSTs, Rust has a particular trait called the `Sized` trait to -determine whether or not a type’s size is known at compile time. This trait is -automatically implemented for everything whose size is known at compile time. -In addition, Rust implicitly adds a bound on `Sized` to every generic function. -That is, a generic function definition like this: +To work with DSTs, Rust provides the `Sized` trait to determine whether or not +a type’s size is known at compile time. This trait is automatically implemented +for everything whose size is known at compile time. In addition, Rust +implicitly adds a bound on `Sized` to every generic function. That is, a +generic function definition like this: ```rust,ignore {{#rustdoc_include ../listings/ch19-advanced-features/no-listing-12-generic-fn-definition/src/lib.rs}} diff --git a/src/doc/book/src/ch19-05-advanced-functions-and-closures.md b/src/doc/book/src/ch19-05-advanced-functions-and-closures.md index 61907db277..69624f056e 100644 --- a/src/doc/book/src/ch19-05-advanced-functions-and-closures.md +++ b/src/doc/book/src/ch19-05-advanced-functions-and-closures.md @@ -7,12 +7,20 @@ including function pointers and returning closures. We’ve talked about how to pass closures to functions; you can also pass regular functions to functions! This technique is useful when you want to pass a -function you’ve already defined rather than defining a new closure. Doing this +function you’ve already defined rather than defining a new closure. Functions +coerce to the type `fn` (with a lowercase f), not to be confused with the `Fn` +closure trait. The `fn` type is called a *function pointer*. Passing functions with function pointers will allow you to use functions as arguments to other -functions. Functions coerce to the type `fn` (with a lowercase f), not to be -confused with the `Fn` closure trait. The `fn` type is called a *function -pointer*. The syntax for specifying that a parameter is a function pointer is -similar to that of closures, as shown in Listing 19-27. +functions. + +The syntax for specifying that a parameter is a function pointer is similar to +that of closures, as shown in Listing 19-27, where we’ve defined a function +`add_one` that adds one to its parameter. The function `do_twice` takes two +parameters: a function pointer to any function that takes an `i32` parameter +and returns an `i32`, and one `i32 value`. The `do_twice` function calls the +function `f` twice, passing it the `arg` value, then adds the two function call +results together. The `main` function calls `do_twice` with the arguments +`add_one` and `5`. Filename: src/main.rs @@ -33,18 +41,19 @@ parameter type directly rather than declaring a generic type parameter with one of the `Fn` traits as a trait bound. Function pointers implement all three of the closure traits (`Fn`, `FnMut`, and -`FnOnce`), so you can always pass a function pointer as an argument for a +`FnOnce`), meaning you can always pass a function pointer as an argument for a function that expects a closure. It’s best to write functions using a generic type and one of the closure traits so your functions can accept either functions or closures. -An example of where you would want to only accept `fn` and not closures is when -interfacing with external code that doesn’t have closures: C functions can -accept functions as arguments, but C doesn’t have closures. +That said, one example of where you would want to only accept `fn` and not +closures is when interfacing with external code that doesn’t have closures: C +functions can accept functions as arguments, but C doesn’t have closures. As an example of where you could use either a closure defined inline or a named -function, let’s look at a use of `map`. To use the `map` function to turn a -vector of numbers into a vector of strings, we could use a closure, like this: +function, let’s look at a use of the `map` method provided by the `Iterator` +trait in the standard library. To use the `map` function to turn a vector of +numbers into a vector of strings, we could use a closure, like this: ```rust {{#rustdoc_include ../listings/ch19-advanced-features/no-listing-15-map-closure/src/main.rs:here}} @@ -83,7 +92,7 @@ compile to the same code, so use whichever style is clearer to you. Closures are represented by traits, which means you can’t return closures directly. In most cases where you might want to return a trait, you can instead use the concrete type that implements the trait as the return value of the -function. But you can’t do that with closures because they don’t have a +function. However, you can’t do that with closures because they don’t have a concrete type that is returnable; you’re not allowed to use the function pointer `fn` as a return type, for example. diff --git a/src/doc/book/src/ch19-06-macros.md b/src/doc/book/src/ch19-06-macros.md index 637131b925..7731869eae 100644 --- a/src/doc/book/src/ch19-06-macros.md +++ b/src/doc/book/src/ch19-06-macros.md @@ -46,9 +46,9 @@ opposed to functions you can define anywhere and call anywhere. ### Declarative Macros with `macro_rules!` for General Metaprogramming -The most widely used form of macros in Rust is *declarative macros*. These are -also sometimes referred to as “macros by example,” “`macro_rules!` macros,” or -just plain “macros.” At their core, declarative macros allow you to write +The most widely used form of macros in Rust is the *declarative macro*. These +are also sometimes referred to as “macros by example,” “`macro_rules!` macros,” +or just plain “macros.” At their core, declarative macros allow you to write something similar to a Rust `match` expression. As discussed in Chapter 6, `match` expressions are control structures that take an expression, compare the resulting value of the expression to patterns, and then run the code associated @@ -107,15 +107,16 @@ one arm. Valid pattern syntax in macro definitions is different than the pattern syntax covered in Chapter 18 because macro patterns are matched against Rust code structure rather than values. Let’s walk through what the pattern pieces in -Listing 19-28 mean; for the full macro pattern syntax, see [the reference]. +Listing 19-28 mean; for the full macro pattern syntax, see the [Rust +Reference][ref]. -[the reference]: ../reference/macros-by-example.html - -First, a set of parentheses encompasses the whole pattern. A dollar sign (`$`) -is next, followed by a set of parentheses that captures values that match the -pattern within the parentheses for use in the replacement code. Within `$()` is -`$x:expr`, which matches any Rust expression and gives the expression the name -`$x`. +First, we use a set of parentheses to encompass the whole pattern. We use a +dollar sign (`$`) to declare a variable in the macro system that will contain +the Rust code matching the pattern. The dollar sign makes it clear this is a +macro variable as opposed to a regular Rust variable. Next comes a set of +parentheses that captures values that match the pattern within the parentheses +for use in the replacement code. Within `$()` is `$x:expr`, which matches any +Rust expression and gives the expression the name `$x`. The comma following `$()` indicates that a literal comma separator character could optionally appear after the code that matches the code in `$()`. The `*` @@ -144,32 +145,23 @@ will be the following: We’ve defined a macro that can take any number of arguments of any type and can generate code to create a vector containing the specified elements. -There are some strange edge cases with `macro_rules!`. In the future, Rust will -have a second kind of declarative macro that will work in a similar fashion but -fix some of these edge cases. After that update, `macro_rules!` will be -effectively deprecated. With this in mind, as well as the fact that most Rust -programmers will *use* macros more than *write* macros, we won’t discuss -`macro_rules!` any further. To learn more about how to write macros, consult -the online documentation or other resources, such as [“The Little Book of Rust -Macros”][tlborm] started by Daniel Keep and continued by Lukas Wirth. - -[tlborm]: https://veykril.github.io/tlborm/ +To learn more about how to write macros, consult the online documentation or +other resources, such as [“The Little Book of Rust Macros”][tlborm] started by +Daniel Keep and continued by Lukas Wirth. ### Procedural Macros for Generating Code from Attributes -The second form of macros is *procedural macros*, which act more like functions -(and are a type of procedure). Procedural macros accept some code as an input, -operate on that code, and produce some code as an output rather than matching -against patterns and replacing the code with other code as declarative macros -do. - -The three kinds of procedural macros (custom derive, attribute-like, and -function-like) all work in a similar fashion. +The second form of macros is the *procedural macro*, which acts more like a +function (and is a type of procedure). Procedural macros accept some code as an +input, operate on that code, and produce some code as an output rather than +matching against patterns and replacing the code with other code as declarative +macros do. The three kinds of procedural macros are custom derive, +attribute-like, and function-like, and all work in a similar fashion. When creating procedural macros, the definitions must reside in their own crate with a special crate type. This is for complex technical reasons that we hope -to eliminate in the future. Defining procedural macros looks like the code in -Listing 19-29, where `some_attribute` is a placeholder for using a specific +to eliminate in the future. In Listing 19-29, we show how to define a +procedural macro, where `some_attribute` is a placeholder for using a specific macro variety. Filename: src/lib.rs @@ -202,8 +194,8 @@ other forms different. Let’s create a crate named `hello_macro` that defines a trait named `HelloMacro` with one associated function named `hello_macro`. Rather than -making our crate users implement the `HelloMacro` trait for each of their -types, we’ll provide a procedural macro so users can annotate their type with +making our users implement the `HelloMacro` trait for each of their types, +we’ll provide a procedural macro so users can annotate their type with `#[derive(HelloMacro)]` to get a default implementation of the `hello_macro` function. The default implementation will print `Hello, Macro! My name is TypeName!` where `TypeName` is the name of the type on which this trait has @@ -310,9 +302,6 @@ We’ve introduced three new crates: `proc_macro`, [`syn`], and [`quote`]. The dependencies in *Cargo.toml*. The `proc_macro` crate is the compiler’s API that allows us to read and manipulate Rust code from our code. -[`syn`]: https://crates.io/crates/syn -[`quote`]: https://crates.io/crates/quote - The `syn` crate parses Rust code from a string into a data structure that we can perform operations on. The `quote` crate turns `syn` data structures back into Rust code. These crates make it much simpler to parse any sort of Rust @@ -322,7 +311,7 @@ task. The `hello_macro_derive` function will be called when a user of our library specifies `#[derive(HelloMacro)]` on a type. This is possible because we’ve annotated the `hello_macro_derive` function here with `proc_macro_derive` and -specified the name, `HelloMacro`, which matches our trait name; this is the +specified the name `HelloMacro`, which matches our trait name; this is the convention most procedural macros follow. The `hello_macro_derive` function first converts the `input` from a @@ -360,8 +349,6 @@ with the `ident` (identifier, meaning the name) of `Pancakes`. There are more fields on this struct for describing all sorts of Rust code; check the [`syn` documentation for `DeriveInput`][syn-docs] for more information. -[syn-docs]: https://docs.rs/syn/1.0/syn/struct.DeriveInput.html - Soon we’ll define the `impl_hello_macro` function, which is where we’ll build the new Rust code we want to include. But before we do, note that the output for our derive macro is also a `TokenStream`. The returned `TokenStream` is @@ -409,11 +396,9 @@ enter `#name`, and `quote!` will replace it with the value in the variable `name`. You can even do some repetition similar to the way regular macros work. Check out [the `quote` crate’s docs][quote-docs] for a thorough introduction. -[quote-docs]: https://docs.rs/quote - We want our procedural macro to generate an implementation of our `HelloMacro` trait for the type the user annotated, which we can get by using `#name`. The -trait implementation has one function, `hello_macro`, whose body contains the +trait implementation has the one function `hello_macro`, whose body contains the functionality we want to provide: printing `Hello, Macro! My name is` and then the name of the annotated type. @@ -490,8 +475,6 @@ Metaprogramming”][decl] earlier. Function-like macros take a using Rust code as the other two types of procedural macros do. An example of a function-like macro is an `sql!` macro that might be called like so: -[decl]: #declarative-macros-with-macro_rules-for-general-metaprogramming - ```rust,ignore let sql = sql!(SELECT * FROM posts WHERE id=1); ``` @@ -511,12 +494,20 @@ generate. ## Summary -Whew! Now you have some Rust features in your toolbox that you won’t use often, -but you’ll know they’re available in very particular circumstances. We’ve -introduced several complex topics so that when you encounter them in error -message suggestions or in other peoples’ code, you’ll be able to recognize -these concepts and syntax. Use this chapter as a reference to guide you to -solutions. +Whew! Now you have some Rust features in your toolbox that you likely won’t use +often, but you’ll know they’re available in very particular circumstances. +We’ve introduced several complex topics so that when you encounter them in +error message suggestions or in other peoples’ code, you’ll be able to +recognize these concepts and syntax. Use this chapter as a reference to guide +you to solutions. Next, we’ll put everything we’ve discussed throughout the book into practice and do one more project! + +[ref]: ../reference/macros-by-example.html +[tlborm]: https://veykril.github.io/tlborm/ +[`syn`]: https://crates.io/crates/syn +[`quote`]: https://crates.io/crates/quote +[syn-docs]: https://docs.rs/syn/1.0/syn/struct.DeriveInput.html +[quote-docs]: https://docs.rs/quote +[decl]: #declarative-macros-with-macro_rules-for-general-metaprogramming diff --git a/src/doc/book/src/ch20-00-final-project-a-web-server.md b/src/doc/book/src/ch20-00-final-project-a-web-server.md index d260041e15..1004eaf3f1 100644 --- a/src/doc/book/src/ch20-00-final-project-a-web-server.md +++ b/src/doc/book/src/ch20-00-final-project-a-web-server.md @@ -12,7 +12,7 @@ Figure 20-1 in a web browser. Figure 20-1: Our final shared project -Here is the plan to build the web server: +Here is our plan for building the web server: 1. Learn a bit about TCP and HTTP. 2. Listen for TCP connections on a socket. @@ -20,15 +20,14 @@ Here is the plan to build the web server: 4. Create a proper HTTP response. 5. Improve the throughput of our server with a thread pool. -But before we get started, we should mention one detail: the method we’ll use -won’t be the best way to build a web server with Rust. A number of -production-ready crates are available on [crates.io](https://crates.io/) that -provide more complete web server and thread pool implementations than we’ll -build. - -However, our intention in this chapter is to help you learn, not to take the -easy route. Because Rust is a systems programming language, we can choose the -level of abstraction we want to work with and can go to a lower level than is -possible or practical in other languages. We’ll write the basic HTTP server and -thread pool manually so you can learn the general ideas and techniques behind -the crates you might use in the future. +Before we get started, we should mention one detail: the method we’ll use won’t +be the best way to build a web server with Rust. Community members have +published a number of production-ready crates available on +[crates.io](https://crates.io/) that provide more complete web server and +thread pool implementations than we’ll build. However, our intention in this +chapter is to help you learn, not to take the easy route. Because Rust is a +systems programming language, we can choose the level of abstraction we want to +work with and can go to a lower level than is possible or practical in other +languages. We’ll therefore write the basic HTTP server and thread pool manually +so you can learn the general ideas and techniques behind the crates you might +use in the future. diff --git a/src/doc/book/src/ch20-01-single-threaded.md b/src/doc/book/src/ch20-01-single-threaded.md index 0e1b55e352..993239a981 100644 --- a/src/doc/book/src/ch20-01-single-threaded.md +++ b/src/doc/book/src/ch20-01-single-threaded.md @@ -5,12 +5,11 @@ let’s look at a quick overview of the protocols involved in building web servers. The details of these protocols are beyond the scope of this book, but a brief overview will give you the information you need. -The two main protocols involved in web servers are the *Hypertext Transfer -Protocol* *(HTTP)* and the *Transmission Control Protocol* *(TCP)*. Both -protocols are *request-response* protocols, meaning a *client* initiates -requests and a *server* listens to the requests and provides a response to the -client. The contents of those requests and responses are defined by the -protocols. +The two main protocols involved in web servers are *Hypertext Transfer +Protocol* *(HTTP)* and *Transmission Control Protocol* *(TCP)*. Both protocols +are *request-response* protocols, meaning a *client* initiates requests and a +*server* listens to the requests and provides a response to the client. The +contents of those requests and responses are defined by the protocols. TCP is the lower-level protocol that describes the details of how information gets from one server to another but doesn’t specify what that information is. @@ -32,8 +31,8 @@ $ cd hello ``` Now enter the code in Listing 20-1 in *src/main.rs* to start. This code will -listen at the address `127.0.0.1:7878` for incoming TCP streams. When it gets -an incoming stream, it will print `Connection established!`. +listen at the local address `127.0.0.1:7878` for incoming TCP streams. When it +gets an incoming stream, it will print `Connection established!`. Filename: src/main.rs @@ -48,33 +47,34 @@ Using `TcpListener`, we can listen for TCP connections at the address `127.0.0.1:7878`. In the address, the section before the colon is an IP address representing your computer (this is the same on every computer and doesn’t represent the authors’ computer specifically), and `7878` is the port. We’ve -chosen this port for two reasons: HTTP isn’t normally accepted on this port, and -7878 is *rust* typed on a telephone. +chosen this port for two reasons: HTTP isn’t normally accepted on this port so +our server is unlikely to conflict with any other web server you might have +running on your machine, and 7878 is *rust* typed on a telephone. The `bind` function in this scenario works like the `new` function in that it -will return a new `TcpListener` instance. The reason the function is called -`bind` is that in networking, connecting to a port to listen to is known as -“binding to a port.” - -The `bind` function returns a `Result`, which indicates that binding -might fail. For example, connecting to port 80 requires administrator -privileges (nonadministrators can listen only on ports higher than 1023), so if -we tried to connect to port 80 without being an administrator, binding wouldn’t -work. As another example, binding wouldn’t work if we ran two instances of our -program and so had two programs listening to the same port. Because we’re -writing a basic server just for learning purposes, we won’t worry about -handling these kinds of errors; instead, we use `unwrap` to stop the program if -errors happen. +will return a new `TcpListener` instance. The function is called `bind` +because, in networking, connecting to a port to listen to is known as “binding +to a port.” + +The `bind` function returns a `Result`, which indicates that it’s +possible for binding to fail. For example, connecting to port 80 requires +administrator privileges (nonadministrators can listen only on ports higher +than 1023), so if we tried to connect to port 80 without being an +administrator, binding wouldn’t work. Binding also wouldn’t work, for example, +if we ran two instances of our program and so had two programs listening to the +same port. Because we’re writing a basic server just for learning purposes, we +won’t worry about handling these kinds of errors; instead, we use `unwrap` to +stop the program if errors happen. The `incoming` method on `TcpListener` returns an iterator that gives us a sequence of streams (more specifically, streams of type `TcpStream`). A single *stream* represents an open connection between the client and the server. A *connection* is the name for the full request and response process in which a client connects to the server, the server generates a response, and the server -closes the connection. As such, `TcpStream` will read from itself to see what -the client sent and then allow us to write our response to the stream. Overall, -this `for` loop will process each connection in turn and produce a series of -streams for us to handle. +closes the connection. As such, we will read from the `TcpStream` to see what +the client sent and then write our response to the stream to send data back to +the client. Overall, this `for` loop will process each connection in turn and +produce a series of streams for us to handle. For now, our handling of the stream consists of calling `unwrap` to terminate our program if the stream has any errors; if there aren’t any errors, the @@ -114,9 +114,9 @@ connections by retrying, because the problem might be temporary. The important factor is that we’ve successfully gotten a handle to a TCP connection! Remember to stop the program by pressing ctrl-c -when you’re done running a particular version of the code. Then restart `cargo -run` after you’ve made each set of code changes to make sure you’re running the -newest code. +when you’re done running a particular version of the code. Then restart the +program by invoking the `cargo run` command after you’ve made each set of code +changes to make sure you’re running the newest code. ### Reading the Request @@ -136,33 +136,34 @@ look like Listing 20-2. Listing 20-2: Reading from the `TcpStream` and printing the data -We bring `std::io::prelude` into scope to get access to certain traits that let -us read from and write to the stream. In the `for` loop in the `main` function, -instead of printing a message that says we made a connection, we now call the -new `handle_connection` function and pass the `stream` to it. - -In the `handle_connection` function, we’ve made the `stream` parameter mutable. -The reason is that the `TcpStream` instance keeps track of what data it returns -to us internally. It might read more data than we asked for and save that data -for the next time we ask for data. It therefore needs to be `mut` because its -internal state might change; usually, we think of “reading” as not needing -mutation, but in this case we need the `mut` keyword. - -Next, we need to actually read from the stream. We do this in two steps: -first, we declare a `buffer` on the stack to hold the data that is read in. -We’ve made the buffer 1024 bytes in size, which is big enough to hold the -data of a basic request and sufficient for our purposes in this chapter. If -we wanted to handle requests of an arbitrary size, buffer management would -need to be more complicated; we’ll keep it simple for now. We pass the buffer -to `stream.read`, which will read bytes from the `TcpStream` and put them in -the buffer. - -Second, we convert the bytes in the buffer to a string and print that string. -The `String::from_utf8_lossy` function takes a `&[u8]` and produces a `String` -from it. The “lossy” part of the name indicates the behavior of this function -when it sees an invalid UTF-8 sequence: it will replace the invalid sequence -with `�`, the `U+FFFD REPLACEMENT CHARACTER`. You might see replacement -characters for characters in the buffer that aren’t filled by request data. +We bring `std::io::prelude` and `std::io::BufReader` into scope to get access +to traits and types that let us read from and write to the stream. In the `for` +loop in the `main` function, instead of printing a message that says we made a +connection, we now call the new `handle_connection` function and pass the +`stream` to it. + +In the `handle_connection` function, we create a new `BufReader` instance that +wraps a mutable reference to the `stream`. `BufReader` adds buffering by +managing calls to the `std::io::Read` trait methods for us. + +We create a variable named `http_request` to collect the lines of the request +the browser sends to our server. We indicate that we want to collect these +lines in a vector by adding the `Vec<_>` type annotation. + +`BufReader` implements the `std::io::BufRead` trait, which provides the `lines` +method. The `lines` method returns an iterator of `Result` by splitting the stream of data whenever it sees a newline +byte. To get each `String`, we map and `unwrap` each `Result`. The `Result` +might be an error if the data isn’t valid UTF-8 or if there was a problem +reading from the stream. Again, a production program should handle these errors +more gracefully, but we’re choosing to stop the program in the error case for +simplicity. + +The browser signals the end of an HTTP request by sending two newline +characters in a row, so to get one request from the stream, we take lines until +we get a line that is the empty string. Once we’ve collected the lines into the +vector, we’re printing them out using pretty debug formatting so we can take a +look at the instructions the web browser is sending to our server. Let’s try this code! Start the program and make a request in a web browser again. Note that we’ll still get an error page in the browser, but our @@ -173,23 +174,30 @@ $ cargo run Compiling hello v0.1.0 (file:///projects/hello) Finished dev [unoptimized + debuginfo] target(s) in 0.42s Running `target/debug/hello` -Request: GET / HTTP/1.1 -Host: 127.0.0.1:7878 -User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 -Firefox/52.0 -Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -Accept-Language: en-US,en;q=0.5 -Accept-Encoding: gzip, deflate -Connection: keep-alive -Upgrade-Insecure-Requests: 1 -������������������������������������ +Request: [ + "GET / HTTP/1.1", + "Host: 127.0.0.1:7878", + "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:99.0) Gecko/20100101 Firefox/99.0", + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language: en-US,en;q=0.5", + "Accept-Encoding: gzip, deflate, br", + "DNT: 1", + "Connection: keep-alive", + "Upgrade-Insecure-Requests: 1", + "Sec-Fetch-Dest: document", + "Sec-Fetch-Mode: navigate", + "Sec-Fetch-Site: none", + "Sec-Fetch-User: ?1", + "Cache-Control: max-age=0", +] ``` Depending on your browser, you might get slightly different output. Now that we’re printing the request data, we can see why we get multiple connections -from one browser request by looking at the path after `Request: GET`. If the -repeated connections are all requesting */*, we know the browser is trying to -fetch */* repeatedly because it’s not getting a response from our program. +from one browser request by looking at the path after `GET` in the first line +of the request. If the repeated connections are all requesting */*, we know the +browser is trying to fetch */* repeatedly because it’s not getting a response +from our program. Let’s break down this request data to understand what the browser is asking of our program. @@ -207,7 +215,8 @@ message-body The first line is the *request line* that holds information about what the client is requesting. The first part of the request line indicates the *method* being used, such as `GET` or `POST`, which describes how the client is making -this request. Our client used a `GET` request. +this request. Our client used a `GET` request, which means it is asking for +information. The next part of the request line is */*, which indicates the *Uniform Resource Identifier* *(URI)* the client is requesting: a URI is almost, but not quite, @@ -236,8 +245,8 @@ Now that we know what the browser is asking for, let’s send back some data! ### Writing a Response -Now we’ll implement sending data in response to a client request. Responses -have the following format: +We’re going to implement sending data in response to a client request. +Responses have the following format: ```text HTTP-Version Status-Code Reason-Phrase CRLF @@ -275,32 +284,28 @@ the stream The first new line defines the `response` variable that holds the success message’s data. Then we call `as_bytes` on our `response` to convert the string -data to bytes. The `write` method on `stream` takes a `&[u8]` and sends those -bytes directly down the connection. - -Because the `write` operation could fail, we use `unwrap` on any error result -as before. Again, in a real application you would add error handling here. -Finally, `flush` will wait and prevent the program from continuing until all -the bytes are written to the connection; `TcpStream` contains an internal -buffer to minimize calls to the underlying operating system. +data to bytes. The `write_all` method on `stream` takes a `&[u8]` and sends +those bytes directly down the connection. Because the `write_all` operation +could fail, we use `unwrap` on any error result as before. Again, in a real +application you would add error handling here. With these changes, let’s run our code and make a request. We’re no longer printing any data to the terminal, so we won’t see any output other than the output from Cargo. When you load *127.0.0.1:7878* in a web browser, you should -get a blank page instead of an error. You’ve just hand-coded an HTTP request -and response! +get a blank page instead of an error. You’ve just hand-coded receiving an HTTP +request and sending a response! ### Returning Real HTML Let’s implement the functionality for returning more than a blank page. Create -a new file, *hello.html*, in the root of your project directory, not in the +the new file *hello.html* in the root of your project directory, not in the *src* directory. You can input any HTML you want; Listing 20-4 shows one possibility. Filename: hello.html ```html -{{#include ../listings/ch20-web-server/listing-20-04/hello.html}} +{{#include ../listings/ch20-web-server/listing-20-05/hello.html}} ``` Listing 20-4: A sample HTML file to return in a @@ -320,24 +325,26 @@ and send it. Listing 20-5: Sending the contents of *hello.html* as the body of the response -We’ve added a line at the top to bring the standard library’s filesystem module -into scope. The code for reading the contents of a file to a string should look -familiar; we used it in Chapter 12 when we read the contents of a file for our -I/O project in Listing 12-4. +We’ve added `fs` to the `use` statement to bring the standard library’s +filesystem module into scope. The code for reading the contents of a file to a +string should look familiar; we used it in Chapter 12 when we read the contents +of a file for our I/O project in Listing 12-4. Next, we use `format!` to add the file’s contents as the body of the success response. To ensure a valid HTTP response, we add the `Content-Length` header -which is set to the size of our response body, in this case the size of `hello.html`. +which is set to the size of our response body, in this case the size of +`hello.html`. Run this code with `cargo run` and load *127.0.0.1:7878* in your browser; you should see your HTML rendered! -Currently, we’re ignoring the request data in `buffer` and just sending back -the contents of the HTML file unconditionally. That means if you try requesting -*127.0.0.1:7878/something-else* in your browser, you’ll still get back this -same HTML response. Our server is very limited and is not what most web servers -do. We want to customize our responses depending on the request and only send -back the HTML file for a well-formed request to */*. +Currently, we’re ignoring the request data in `http_request` and just sending +back the contents of the HTML file unconditionally. That means if you try +requesting *127.0.0.1:7878/something-else* in your browser, you’ll still get +back this same HTML response. At the moment, our server is very limited and +does not do what most web servers do. We want to customize our responses +depending on the request and only send back the HTML file for a well-formed +request to */*. ### Validating the Request and Selectively Responding @@ -355,20 +362,23 @@ received against what we know a request for */* looks like and adds `if` and {{#rustdoc_include ../listings/ch20-web-server/listing-20-06/src/main.rs:here}} ``` -Listing 20-6: Matching the request and handling requests -to */* differently from other requests +Listing 20-6: Handling requests to */* differently from +other requests + +We’re only going to be looking at the first line of the HTTP request, so rather +than reading the entire request into a vector, we’re calling `next` to get the +first item from the iterator. The first `unwrap` takes care of the `Option` and +stops the program if the iterator has no items. The second `unwrap` handles the +`Result` and has the same effect as the `unwrap` that was in the `map` added in +Listing 20-2. -First, we hardcode the data corresponding to the */* request into the `get` -variable. Because we’re reading raw bytes into the buffer, we transform `get` -into a byte string by adding the `b""` byte string syntax at the start of the -content data. Then we check whether `buffer` starts with the bytes in `get`. If -it does, it means we’ve received a well-formed request to */*, which is the -success case we’ll handle in the `if` block that returns the contents of our +Next, we check the `request_line` to see if it equals the request line of a GET +request to the */* path. If it does, the `if` block returns the contents of our HTML file. -If `buffer` does *not* start with the bytes in `get`, it means we’ve received -some other request. We’ll add code to the `else` block in a moment to respond -to all other requests. +If the `request_line` does *not* equal the GET request to the */* path, it +means we’ve received some other request. We’ll add code to the `else` block in +a moment to respond to all other requests. Run this code now and request *127.0.0.1:7878*; you should get the HTML in *hello.html*. If you make any other request, such as @@ -389,23 +399,23 @@ indicating the response to the end user. Listing 20-7: Responding with status code 404 and an error page if anything other than */* was requested -Here, our response has a status line with status code 404 and the reason -phrase `NOT FOUND`. The body of the response will be the HTML in the file -*404.html*. You’ll need to create a *404.html* file next to *hello.html* for -the error page; again feel free to use any HTML you want or use the example -HTML in Listing 20-8. +Here, our response has a status line with status code 404 and the reason phrase +`NOT FOUND`. The body of the response will be the HTML in the file *404.html*. +You’ll need to create a *404.html* file next to *hello.html* for the error +page; again feel free to use any HTML you want or use the example HTML in +Listing 20-8. Filename: 404.html ```html -{{#include ../listings/ch20-web-server/listing-20-08/404.html}} +{{#include ../listings/ch20-web-server/listing-20-07/404.html}} ``` Listing 20-8: Sample content for the page to send back with any 404 response -With these changes, run your server again. Requesting *127.0.0.1:7878* -should return the contents of *hello.html*, and any other request, like +With these changes, run your server again. Requesting *127.0.0.1:7878* should +return the contents of *hello.html*, and any other request, like *127.0.0.1:7878/foo*, should return the error HTML from *404.html*. ### A Touch of Refactoring diff --git a/src/doc/book/src/ch20-02-multithreaded.md b/src/doc/book/src/ch20-02-multithreaded.md index af52f057ed..bd1dc25ab9 100644 --- a/src/doc/book/src/ch20-02-multithreaded.md +++ b/src/doc/book/src/ch20-02-multithreaded.md @@ -21,14 +21,18 @@ for 5 seconds before responding. {{#rustdoc_include ../listings/ch20-web-server/listing-20-10/src/main.rs:here}} ``` -Listing 20-10: Simulating a slow request by recognizing -*/sleep* and sleeping for 5 seconds +Listing 20-10: Simulating a slow request by sleeping for +5 seconds -This code is a bit messy, but it’s good enough for simulation purposes. We -created a second request `sleep`, whose data our server recognizes. We added an -`else if` after the `if` block to check for the request to */sleep*. When that -request is received, the server will sleep for 5 seconds before rendering the -successful HTML page. +We switched from `if` to `match` now that we have three cases. We need to +explicitly match on a slice of `request_line` to pattern match against the +string literal values; `match` doesn’t do automatic referencing and +dereferencing like the equality method does. + +The first arm is the same as the `if` block from Listing 20-9. The second arm +matches a request to */sleep*. When that request is received, the server will +sleep for 5 seconds before rendering the successful HTML page. The third arm is +the same as the `else` block from Listing 20-9. You can see how primitive our server is: real libraries would handle the recognition of multiple requests in a much less verbose way! @@ -39,9 +43,8 @@ you enter the */* URI a few times, as before, you’ll see it respond quickly. But if you enter */sleep* and then load */*, you’ll see that */* waits until `sleep` has slept for its full 5 seconds before loading. -There are multiple ways we could change how our web server works to avoid -having more requests back up behind a slow request; the one we’ll implement is -a thread pool. +There are multiple techniques we could use to avoid requests backing up behind +a slow request; the one we’ll implement is a thread pool. ### Improving Throughput with a Thread Pool @@ -60,21 +63,22 @@ for each request as it came in, someone making 10 million requests to our server could create havoc by using up all our server’s resources and grinding the processing of requests to a halt. -Rather than spawning unlimited threads, we’ll have a fixed number of threads -waiting in the pool. As requests come in, they’ll be sent to the pool for +Rather than spawning unlimited threads, then, we’ll have a fixed number of +threads waiting in the pool. Requests that come in are sent to the pool for processing. The pool will maintain a queue of incoming requests. Each of the threads in the pool will pop off a request from this queue, handle the request, -and then ask the queue for another request. With this design, we can process -`N` requests concurrently, where `N` is the number of threads. If each thread -is responding to a long-running request, subsequent requests can still back up -in the queue, but we’ve increased the number of long-running requests we can -handle before reaching that point. +and then ask the queue for another request. With this design, we can process up +to `N` requests concurrently, where `N` is the number of threads. If each +thread is responding to a long-running request, subsequent requests can still +back up in the queue, but we’ve increased the number of long-running requests +we can handle before reaching that point. This technique is just one of many ways to improve the throughput of a web -server. Other options you might explore are the fork/join model and the -single-threaded async I/O model. If you’re interested in this topic, you can -read more about other solutions and try to implement them in Rust; with a -low-level language like Rust, all of these options are possible. +server. Other options you might explore are the *fork/join model*, the +*single-threaded async I/O model*, or the *multi-threaded async I/O model*. If +you’re interested in this topic, you can read more about other solutions and +try to implement them; with a low-level language like Rust, all of these +options are possible. Before we begin implementing a thread pool, let’s talk about what using the pool should look like. When you’re trying to design code, writing the client @@ -86,15 +90,21 @@ designing the public API. Similar to how we used test-driven development in the project in Chapter 12, we’ll use compiler-driven development here. We’ll write the code that calls the functions we want, and then we’ll look at errors from the compiler to determine -what we should change next to get the code to work. +what we should change next to get the code to work. Before we do that, however, +we’ll explore the technique we’re not going to use as a starting point. + + + -#### Code Structure If We Could Spawn a Thread for Each Request +#### Spawning a Thread for Each Request First, let’s explore how our code might look if it did create a new thread for every connection. As mentioned earlier, this isn’t our final plan due to the problems with potentially spawning an unlimited number of threads, but it is a -starting point. Listing 20-11 shows the changes to make to `main` to spawn a -new thread to handle each stream within the `for` loop. +starting point to get a working multithreaded server first. Then we’ll add the +thread pool as an improvement, and contrasting the two solutions will be +easier. Listing 20-11 shows the changes to make to `main` to spawn a new thread +to handle each stream within the `for` loop. Filename: src/main.rs @@ -108,11 +118,14 @@ stream As you learned in Chapter 16, `thread::spawn` will create a new thread and then run the code in the closure in the new thread. If you run this code and load */sleep* in your browser, then */* in two more browser tabs, you’ll indeed see -that the requests to */* don’t have to wait for */sleep* to finish. But as we -mentioned, this will eventually overwhelm the system because you’d be making +that the requests to */* don’t have to wait for */sleep* to finish. However, as +we mentioned, this will eventually overwhelm the system because you’d be making new threads without any limit. -#### Creating a Similar Interface for a Finite Number of Threads + + + +#### Creating a Finite Number of Threads We want our thread pool to work in a similar, familiar way so switching from threads to a thread pool doesn’t require large changes to the code that uses @@ -134,7 +147,10 @@ run for each stream. We need to implement `pool.execute` so it takes the closure and gives it to a thread in the pool to run. This code won’t yet compile, but we’ll try so the compiler can guide us in how to fix it. -#### Building the `ThreadPool` Struct Using Compiler Driven Development + + + +#### Building `ThreadPool` Using Compiler Driven Development Make the changes in Listing 20-12 to *src/main.rs*, and then let’s use the compiler errors from `cargo check` to drive our development. Here is the first @@ -161,17 +177,13 @@ definition of a `ThreadPool` struct that we can have for now: {{#rustdoc_include ../listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/lib.rs}} ``` -Then create a new directory, *src/bin*, and move the binary crate rooted in -*src/main.rs* into *src/bin/main.rs*. Doing so will make the library crate the -primary crate in the *hello* directory; we can still run the binary in -*src/bin/main.rs* using `cargo run`. After moving the *main.rs* file, edit it -to bring the library crate in and bring `ThreadPool` into scope by adding the -following code to the top of *src/bin/main.rs*: +Then edit *main.rs* file to bring `ThreadPool` into scope from the library +crate by adding the following code to the top of *src/main.rs*: -Filename: src/bin/main.rs +Filename: src/main.rs ```rust,ignore -{{#rustdoc_include ../listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/bin/main.rs:here}} +{{#rustdoc_include ../listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/main.rs:here}} ``` This code still won’t work, but let’s check it again to get the next error that @@ -206,12 +218,11 @@ Let’s check the code again: ``` Now the error occurs because we don’t have an `execute` method on `ThreadPool`. -Recall from the [“Creating a Similar Interface for a Finite Number of -Threads”](#creating-a-similar-interface-for-a-finite-number-of-threads) section that we decided our thread pool should have an interface -similar to `thread::spawn`. In addition, we’ll implement the `execute` function -so it takes the closure it’s given and gives it to an idle thread in the pool -to run. +Recall from the [“Creating a Finite Number of +Threads”](#creating-a-finite-number-of-threads) section that we +decided our thread pool should have an interface similar to `thread::spawn`. In +addition, we’ll implement the `execute` function so it takes the closure it’s +given and gives it to an idle thread in the pool to run. We’ll define the `execute` method on `ThreadPool` to take a closure as a parameter. Recall from the [“Moving Captured Values Out of the Closure and the @@ -294,29 +305,29 @@ zero by using the `assert!` macro, as shown in Listing 20-13. Listing 20-13: Implementing `ThreadPool::new` to panic if `size` is zero -We’ve added some documentation for our `ThreadPool` with doc comments. Note -that we followed good documentation practices by adding a section that calls -out the situations in which our function can panic, as discussed in Chapter 14. -Try running `cargo doc --open` and clicking the `ThreadPool` struct to see what -the generated docs for `new` look like! +We’ve also added some documentation for our `ThreadPool` with doc comments. +Note that we followed good documentation practices by adding a section that +calls out the situations in which our function can panic, as discussed in +Chapter 14. Try running `cargo doc --open` and clicking the `ThreadPool` struct +to see what the generated docs for `new` look like! -Instead of adding the `assert!` macro as we’ve done here, we could make `new` -return a `Result` like we did with `Config::new` in the I/O project in Listing -12-9. But we’ve decided in this case that trying to create a thread pool -without any threads should be an unrecoverable error. If you’re feeling -ambitious, try to write a version of `new` with the following signature to -compare both versions: +Instead of adding the `assert!` macro as we’ve done here, we could change `new` +into `build` and return a `Result` like we did with `Config::build` in the I/O +project in Listing 12-9. But we’ve decided in this case that trying to create a +thread pool without any threads should be an unrecoverable error. If you’re +feeling ambitious, try to write a function named `build` with the following +signature to compare with the `new` function: ```rust,ignore -pub fn new(size: usize) -> Result { +pub fn build(size: usize) -> Result { ``` #### Creating Space to Store the Threads Now that we have a way to know we have a valid number of threads to store in the pool, we can create those threads and store them in the `ThreadPool` struct -before returning it. But how do we “store” a thread? Let’s take another look at -the `thread::spawn` signature: +before returning the struct. But how do we “store” a thread? Let’s take another +look at the `thread::spawn` signature: ```rust,ignore pub fn spawn(f: F) -> JoinHandle @@ -351,15 +362,13 @@ using `thread::JoinHandle` as the type of the items in the vector in `ThreadPool`. Once a valid size is received, our `ThreadPool` creates a new vector that can -hold `size` items. We haven’t used the `with_capacity` function in this book -yet, which performs the same task as `Vec::new` but with an important -difference: it preallocates space in the vector. Because we know we need to -store `size` elements in the vector, doing this allocation up front is slightly -more efficient than using `Vec::new`, which resizes itself as elements are -inserted. +hold `size` items. The `with_capacity` function performs the same task as +`Vec::new` but with an important difference: it preallocates space in the +vector. Because we know we need to store `size` elements in the vector, doing +this allocation up front is slightly more efficient than using `Vec::new`, +which resizes itself as elements are inserted. -When you run `cargo check` again, you’ll get a few more warnings, but it should -succeed. +When you run `cargo check` again, it should succeed. #### A `Worker` Struct Responsible for Sending Code from the `ThreadPool` to a Thread @@ -374,10 +383,11 @@ implement it manually. We’ll implement this behavior by introducing a new data structure between the `ThreadPool` and the threads that will manage this new behavior. We’ll call -this data structure `Worker`, which is a common term in pooling -implementations. Think of people working in the kitchen at a restaurant: the -workers wait until orders come in from customers, and then they’re responsible -for taking those orders and filling them. +this data structure *Worker*, which is a common term in pooling +implementations. The Worker picks up code that needs to be run and runs the +code in the Worker’s thread. Think of people working in the kitchen at a +restaurant: the workers wait until orders come in from customers, and then +they’re responsible for taking those orders and filling them. Instead of storing a vector of `JoinHandle<()>` instances in the thread pool, we’ll store instances of the `Worker` struct. Each `Worker` will store a single @@ -386,9 +396,9 @@ take a closure of code to run and send it to the already running thread for execution. We’ll also give each worker an `id` so we can distinguish between the different workers in the pool when logging or debugging. -Let’s make the following changes to what happens when we create a `ThreadPool`. -We’ll implement the code that sends the closure to the thread after we have -`Worker` set up in this way: +Here is the new process that will happen when we create a `ThreadPool`. We’ll +implement the code that sends the closure to the thread after we have `Worker` +set up in this way: 1. Define a `Worker` struct that holds an `id` and a `JoinHandle<()>`. 2. Change `ThreadPool` to hold a vector of `Worker` instances. @@ -417,44 +427,50 @@ because it’s now holding `Worker` instances instead of `JoinHandle<()>` instances. We use the counter in the `for` loop as an argument to `Worker::new`, and we store each new `Worker` in the vector named `workers`. -External code (like our server in *src/bin/main.rs*) doesn’t need to know the +External code (like our server in *src/main.rs*) doesn’t need to know the implementation details regarding using a `Worker` struct within `ThreadPool`, so we make the `Worker` struct and its `new` function private. The `Worker::new` function uses the `id` we give it and stores a `JoinHandle<()>` instance that is created by spawning a new thread using an empty closure. +> Note: If the operating system can’t create a thread because there aren’t +> enough system resources, `thread::spawn` will panic. That will cause our +> whole server to panic, even though the creation of some threads might +> succeed. For simplicity’s sake, this behavior is fine, but in a production +> thread pool implementation, you’d likely want to use +> [`std::thread::Builder`][builder] and its +> [`spawn`][builder-spawn] method that returns `Result` instead. + This code will compile and will store the number of `Worker` instances we specified as an argument to `ThreadPool::new`. But we’re *still* not processing the closure that we get in `execute`. Let’s look at how to do that next. #### Sending Requests to Threads via Channels -Now we’ll tackle the problem that the closures given to `thread::spawn` do +The next problem we’ll tackle is that the closures given to `thread::spawn` do absolutely nothing. Currently, we get the closure we want to execute in the `execute` method. But we need to give `thread::spawn` a closure to run when we create each `Worker` during the creation of the `ThreadPool`. -We want the `Worker` structs that we just created to fetch code to run from a -queue held in the `ThreadPool` and send that code to its thread to run. +We want the `Worker` structs that we just created to fetch the code to run from +a queue held in the `ThreadPool` and send that code to its thread to run. -In Chapter 16, you learned about *channels*—a simple way to communicate between -two threads—that would be perfect for this use case. We’ll use a channel to -function as the queue of jobs, and `execute` will send a job from the -`ThreadPool` to the `Worker` instances, which will send the job to its thread. -Here is the plan: +The channels we learned about in Chapter 16—a simple way to communicate between +two threads—would be perfect for this use case. We’ll use a channel to function +as the queue of jobs, and `execute` will send a job from the `ThreadPool` to +the `Worker` instances, which will send the job to its thread. Here is the plan: -1. The `ThreadPool` will create a channel and hold on to the sending side of - the channel. -2. Each `Worker` will hold on to the receiving side of the channel. +1. The `ThreadPool` will create a channel and hold on to the sender. +2. Each `Worker` will hold on to the receiver. 3. We’ll create a new `Job` struct that will hold the closures we want to send down the channel. -4. The `execute` method will send the job it wants to execute down the sending - side of the channel. -5. In its thread, the `Worker` will loop over its receiving side of the channel - and execute the closures of any jobs it receives. +4. The `execute` method will send the job it wants to execute through the + sender. +5. In its thread, the `Worker` will loop over its receiver and execute the + closures of any jobs it receives. -Let’s start by creating a channel in `ThreadPool::new` and holding the sending -side in the `ThreadPool` instance, as shown in Listing 20-16. The `Job` struct +Let’s start by creating a channel in `ThreadPool::new` and holding the sender +in the `ThreadPool` instance, as shown in Listing 20-16. The `Job` struct doesn’t hold anything for now but will be the type of item we’re sending down the channel. @@ -465,15 +481,15 @@ the channel. ``` Listing 20-16: Modifying `ThreadPool` to store the -sending end of a channel that sends `Job` instances +sender of a channel that transmits `Job` instances In `ThreadPool::new`, we create our new channel and have the pool hold the -sending end. This will successfully compile, still with warnings. +sender. This will successfully compile. -Let’s try passing a receiving end of the channel into each worker as the thread -pool creates the channel. We know we want to use the receiving end in the -thread that the workers spawn, so we’ll reference the `receiver` parameter in -the closure. The code in Listing 20-17 won’t quite compile yet. +Let’s try passing a receiver of the channel into each worker as the thread pool +creates the channel. We know we want to use the receiver in the thread that the +workers spawn, so we’ll reference the `receiver` parameter in the closure. The +code in Listing 20-17 won’t quite compile yet. Filename: src/lib.rs @@ -481,11 +497,10 @@ the closure. The code in Listing 20-17 won’t quite compile yet. {{#rustdoc_include ../listings/ch20-web-server/listing-20-17/src/lib.rs:here}} ``` -Listing 20-17: Passing the receiving end of the channel -to the workers +Listing 20-17: Passing the receiver to the workers -We’ve made some small and straightforward changes: we pass the receiving end of -the channel into `Worker::new`, and then we use it inside the closure. +We’ve made some small and straightforward changes: we pass the receiver into +`Worker::new`, and then we use it inside the closure. When we try to check this code, we get this error: @@ -496,9 +511,9 @@ When we try to check this code, we get this error: The code is trying to pass `receiver` to multiple `Worker` instances. This won’t work, as you’ll recall from Chapter 16: the channel implementation that Rust provides is multiple *producer*, single *consumer*. This means we can’t -just clone the consuming end of the channel to fix this code. Even if we could, -that is not the technique we would want to use; instead, we want to distribute -the jobs across threads by sharing the single `receiver` among all the workers. +just clone the consuming end of the channel to fix this code. We also don’t +want to send a message multiple times to multiple consumers; we want one list +of messages with multiple workers such that each message gets processed once. Additionally, taking a job off the channel queue involves mutating the `receiver`, so the threads need a safe way to share and modify `receiver`; @@ -516,12 +531,12 @@ receiver at a time. Listing 20-18 shows the changes we need to make. {{#rustdoc_include ../listings/ch20-web-server/listing-20-18/src/lib.rs:here}} ``` -Listing 20-18: Sharing the receiving end of the channel -among the workers using `Arc` and `Mutex` +Listing 20-18: Sharing the receiver among the workers +using `Arc` and `Mutex` -In `ThreadPool::new`, we put the receiving end of the channel in an `Arc` and a -`Mutex`. For each new worker, we clone the `Arc` to bump the reference count so -the workers can share ownership of the receiving end. +In `ThreadPool::new`, we put the receiver in an `Arc` and a `Mutex`. For each +new worker, we clone the `Arc` to bump the reference count so the workers can +share ownership of the receiver. With these changes, the code compiles! We’re getting there! @@ -531,8 +546,8 @@ Let’s finally implement the `execute` method on `ThreadPool`. We’ll also cha `Job` from a struct to a type alias for a trait object that holds the type of closure that `execute` receives. As discussed in the [“Creating Type Synonyms with Type Aliases”][creating-type-synonyms-with-type-aliases] -section of Chapter 19, type aliases allow us to make long types shorter. Look -at Listing 20-19. +section of Chapter 19, type aliases allow us to make long types shorter for +ease of use. Look at Listing 20-19. Filename: src/lib.rs @@ -577,8 +592,8 @@ you. If we get the lock on the mutex, we call `recv` to receive a `Job` from the channel. A final `unwrap` moves past any errors here as well, which might occur -if the thread holding the sending side of the channel has shut down, similar to -how the `send` method returns `Err` if the receiving side shuts down. +if the thread holding the sender has shut down, similar to how the `send` +method returns `Err` if the receiver shuts down. The call to `recv` blocks, so if there is no job yet, the current thread will wait until a job becomes available. The `Mutex` ensures that only one @@ -617,10 +632,9 @@ warning: field is never read: `thread` 49 | thread: thread::JoinHandle<()>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 3 warnings emitted - +warning: `hello` (lib) generated 3 warnings Finished dev [unoptimized + debuginfo] target(s) in 1.40s - Running `target/debug/main` + Running `target/debug/hello` Worker 0 got a job; executing. Worker 2 got a job; executing. Worker 1 got a job; executing. @@ -663,8 +677,8 @@ processed. The reason is somewhat subtle: the `Mutex` struct has no public the `MutexGuard` within the `LockResult>` that the `lock` method returns. At compile time, the borrow checker can then enforce the rule that a resource guarded by a `Mutex` cannot be accessed unless we hold the -lock. But this implementation can also result in the lock being held longer -than intended if we don’t think carefully about the lifetime of the +lock. However, this implementation can also result in the lock being held +longer than intended if we aren’t mindful of the lifetime of the `MutexGuard`. The code in Listing 20-20 that uses `let job = @@ -680,3 +694,5 @@ ch19-04-advanced-types.html#creating-type-synonyms-with-type-aliases [integer-types]: ch03-02-data-types.html#integer-types [fn-traits]: ch13-01-closures.html#moving-captured-values-out-of-the-closure-and-the-fn-traits +[builder]: ../std/thread/struct.Builder.html +[builder-spawn]: ../std/thread/struct.Builder.html#method.spawn diff --git a/src/doc/book/src/ch20-03-graceful-shutdown-and-cleanup.md b/src/doc/book/src/ch20-03-graceful-shutdown-and-cleanup.md index 6d4edbff68..8de791bd9b 100644 --- a/src/doc/book/src/ch20-03-graceful-shutdown-and-cleanup.md +++ b/src/doc/book/src/ch20-03-graceful-shutdown-and-cleanup.md @@ -8,11 +8,12 @@ class="keystroke">ctrl-c method to halt the main thread, all other threads are stopped immediately as well, even if they’re in the middle of serving a request. -Now we’ll implement the `Drop` trait to call `join` on each of the threads in -the pool so they can finish the requests they’re working on before closing. -Then we’ll implement a way to tell the threads they should stop accepting new -requests and shut down. To see this code in action, we’ll modify our server to -accept only two requests before gracefully shutting down its thread pool. +Next, then, we’ll implement the `Drop` trait to call `join` on each of the +threads in the pool so they can finish the requests they’re working on before +closing. Then we’ll implement a way to tell the threads they should stop +accepting new requests and shut down. To see this code in action, we’ll modify +our server to accept only two requests before gracefully shutting down its +thread pool. ### Implementing the `Drop` Trait on `ThreadPool` @@ -75,7 +76,7 @@ new `Worker`. Make the following changes to fix this error: Filename: src/lib.rs -```rust,ignore +```rust,ignore,does_not_compile {{#rustdoc_include ../listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs:here}} ``` @@ -85,7 +86,7 @@ The following changes will do so: Filename: src/lib.rs -```rust,ignore +```rust,ignore,not_desired_behavior {{#rustdoc_include ../listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs:here}} ``` @@ -97,92 +98,54 @@ cleaned up, so nothing happens in that case. ### Signaling to the Threads to Stop Listening for Jobs -With all the changes we’ve made, our code compiles without any warnings. But -the bad news is this code doesn’t function the way we want it to yet. The key -is the logic in the closures run by the threads of the `Worker` instances: at -the moment, we call `join`, but that won’t shut down the threads because they -`loop` forever looking for jobs. If we try to drop our `ThreadPool` with our -current implementation of `drop`, the main thread will block forever waiting -for the first thread to finish. - -To fix this problem, we’ll modify the threads so they listen for either a `Job` -to run or a signal that they should stop listening and exit the infinite loop. -Instead of `Job` instances, our channel will send one of these two enum -variants. +With all the changes we’ve made, our code compiles without any warnings. +However, the bad news is this code doesn’t function the way we want it to yet. +The key is the logic in the closures run by the threads of the `Worker` +instances: at the moment, we call `join`, but that won’t shut down the threads +because they `loop` forever looking for jobs. If we try to drop our +`ThreadPool` with our current implementation of `drop`, the main thread will +block forever waiting for the first thread to finish. -Filename: src/lib.rs - -```rust,noplayground -{{#rustdoc_include ../listings/ch20-web-server/no-listing-07-define-message-enum/src/lib.rs:here}} -``` +To fix this problem, we’ll need a change in the the `ThreadPool` `drop` +implementation and then a change in the `Worker` loop. -This `Message` enum will either be a `NewJob` variant that holds the `Job` the -thread should run, or it will be a `Terminate` variant that will cause the -thread to exit its loop and stop. - -We need to adjust the channel to use values of type `Message` rather than type -`Job`, as shown in Listing 20-23. +First, we’ll change the `ThreadPool` `drop` implementation to explicitly drop +the `sender` before waiting for the threads to finish. Listing 20-23 shows the +changes to `ThreadPool` to explicitly drop `sender`. We use the same `Option` +and `take` technique as we did with the thread to be able to move `sender` out +of `ThreadPool`: Filename: src/lib.rs -```rust,ignore +```rust,noplayground,not_desired_behavior {{#rustdoc_include ../listings/ch20-web-server/listing-20-23/src/lib.rs:here}} ``` -Listing 20-23: Sending and receiving `Message` values and -exiting the loop if a `Worker` receives `Message::Terminate` +Listing 20-23: Explicitly drop `sender` before joining +the worker threads -To incorporate the `Message` enum, we need to change `Job` to `Message` in two -places: the definition of `ThreadPool` and the signature of `Worker::new`. The -`execute` method of `ThreadPool` needs to send jobs wrapped in the -`Message::NewJob` variant. Then, in `Worker::new` where a `Message` is received -from the channel, the job will be processed if the `NewJob` variant is -received, and the thread will break out of the loop if the `Terminate` variant -is received. - -With these changes, the code will compile and continue to function in the same -way as it did after Listing 20-20. But we’ll get a warning because we aren’t -creating any messages of the `Terminate` variety. Let’s fix this warning by -changing our `Drop` implementation to look like Listing 20-24. +Dropping `sender` closes the channel, which indicates no more messages will be +sent. When that happens, all the calls to `recv` that the workers do in the +infinite loop will return an error. In Listing 20-24, we change the `Worker` +loop to gracefully exit the loop in that case, which means the threads will +finish when the `ThreadPool` `drop` implementation calls `join` on them. Filename: src/lib.rs -```rust,ignore +```rust,noplayground {{#rustdoc_include ../listings/ch20-web-server/listing-20-24/src/lib.rs:here}} ``` -Listing 20-24: Sending `Message::Terminate` to the -workers before calling `join` on each worker thread - -We’re now iterating over the workers twice: once to send one `Terminate` -message for each worker and once to call `join` on each worker’s thread. If we -tried to send a message and `join` immediately in the same loop, we couldn’t -guarantee that the worker in the current iteration would be the one to get the -message from the channel. - -To better understand why we need two separate loops, imagine a scenario with -two workers. If we used a single loop to iterate through each worker, on the -first iteration a terminate message would be sent down the channel and `join` -called on the first worker’s thread. If that first worker was busy processing a -request at that moment, the second worker would pick up the terminate message -from the channel and shut down. We would be left waiting on the first worker to -shut down, but it never would because the second thread picked up the terminate -message. Deadlock! - -To prevent this scenario, we first put all of our `Terminate` messages on the -channel in one loop; then we join on all the threads in another loop. Each -worker will stop receiving requests on the channel once it gets a terminate -message. So, we can be sure that if we send the same number of terminate -messages as there are workers, each worker will receive a terminate message -before `join` is called on its thread. +Listing 20-24: Explicitly break out of the loop when +`recv` returns an error To see this code in action, let’s modify `main` to accept only two requests before gracefully shutting down the server, as shown in Listing 20-25. -Filename: src/bin/main.rs +Filename: src/main.rs ```rust,ignore -{{#rustdoc_include ../listings/ch20-web-server/listing-20-25/src/bin/main.rs:here}} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-25/src/main.rs:here}} ``` Listing 20-25: Shut down the server after serving two @@ -214,17 +177,15 @@ Can't automate because the output depends on making requests $ cargo run Compiling hello v0.1.0 (file:///projects/hello) Finished dev [unoptimized + debuginfo] target(s) in 1.0s - Running `target/debug/main` + Running `target/debug/hello` Worker 0 got a job; executing. -Worker 3 got a job; executing. Shutting down. -Sending terminate message to all workers. -Shutting down all workers. Shutting down worker 0 -Worker 1 was told to terminate. -Worker 2 was told to terminate. -Worker 0 was told to terminate. -Worker 3 was told to terminate. +Worker 3 got a job; executing. +Worker 1 disconnected; shutting down. +Worker 2 disconnected; shutting down. +Worker 3 disconnected; shutting down. +Worker 0 disconnected; shutting down. Shutting down worker 1 Shutting down worker 2 Shutting down worker 3 @@ -232,20 +193,19 @@ Shutting down worker 3 You might see a different ordering of workers and messages printed. We can see how this code works from the messages: workers 0 and 3 got the first two -requests, and then on the third request, the server stopped accepting -connections. When the `ThreadPool` goes out of scope at the end of `main`, its -`Drop` implementation kicks in, and the pool tells all workers to terminate. -The workers each print a message when they see the terminate message, and then -the thread pool calls `join` to shut down each worker thread. +requests. The server stopped accepting connections after the second connection, +and the `Drop` implementation on `ThreadPool` starts executing before worker 3 +even starts its job. Dropping the `sender` disconnects all the workers and +tells them to shut down. The workers each print a message when they disconnect, +and then the thread pool calls `join` to wait for each worker thread to finish. Notice one interesting aspect of this particular execution: the `ThreadPool` -sent the terminate messages down the channel, and before any worker received -the messages, we tried to join worker 0. Worker 0 had not yet received the -terminate message, so the main thread blocked waiting for worker 0 to finish. -In the meantime, each of the workers received the termination messages. When -worker 0 finished, the main thread waited for the rest of the workers to -finish. At that point, they had all received the termination message and were -able to shut down. +dropped the `sender`, and before any worker received an error, we tried to join +worker 0. Worker 0 had not yet gotten an error from `recv`, so the main thread +blocked waiting for worker 0 to finish. In the meantime, worker 3 received a +job and then all threads received an error. When worker 0 finished, the main +thread waited for the rest of the workers to finish. At that point, they had +all exited their loops and stopped. Congrats! We’ve now completed our project; we have a basic web server that uses a thread pool to respond asynchronously. We’re able to perform a graceful @@ -253,16 +213,16 @@ shutdown of the server, which cleans up all the threads in the pool. Here’s the full code for reference: -Filename: src/bin/main.rs +Filename: src/main.rs ```rust,ignore -{{#rustdoc_include ../listings/ch20-web-server/no-listing-08-final-code/src/bin/main.rs}} +{{#rustdoc_include ../listings/ch20-web-server/no-listing-07-final-code/src/main.rs}} ``` Filename: src/lib.rs ```rust,noplayground -{{#rustdoc_include ../listings/ch20-web-server/no-listing-08-final-code/src/lib.rs}} +{{#rustdoc_include ../listings/ch20-web-server/no-listing-07-final-code/src/lib.rs}} ``` We could do more here! If you want to continue enhancing this project, here are diff --git a/src/doc/book/src/title-page.md b/src/doc/book/src/title-page.md index fdbb52711b..2ca33e7515 100644 --- a/src/doc/book/src/title-page.md +++ b/src/doc/book/src/title-page.md @@ -2,7 +2,7 @@ *by Steve Klabnik and Carol Nichols, with contributions from the Rust Community* -This version of the text assumes you’re using Rust 1.59 (released 2022-02-24) +This version of the text assumes you’re using Rust 1.61 (released 2022-05-18) or later. See the [“Installation” section of Chapter 1][install] to install or update Rust. diff --git a/src/doc/book/tools/src/bin/concat_chapters.rs b/src/doc/book/tools/src/bin/concat_chapters.rs index 001c322b6d..79ffec9b70 100644 --- a/src/doc/book/tools/src/bin/concat_chapters.rs +++ b/src/doc/book/tools/src/bin/concat_chapters.rs @@ -11,7 +11,7 @@ use std::process::exit; use regex::Regex; -static PATTERNS: &'static [(&'static str, &'static str)] = &[ +static PATTERNS: &[(&str, &str)] = &[ (r"ch(\d\d)-\d\d-.*\.md", "chapter$1.md"), (r"appendix-(\d\d).*\.md", "appendix.md"), ]; @@ -123,5 +123,5 @@ fn ensure_dir_exists(dir_string: &str) -> io::Result<&Path> { if !path.exists() { create_dir(path)?; } - Ok(&path) + Ok(path) } diff --git a/src/doc/book/tools/src/bin/convert_quotes.rs b/src/doc/book/tools/src/bin/convert_quotes.rs index c8cfd456d1..b4a9bdce2e 100644 --- a/src/doc/book/tools/src/bin/convert_quotes.rs +++ b/src/doc/book/tools/src/bin/convert_quotes.rs @@ -1,5 +1,5 @@ use std::io; -use std::io::{Read, Write}; +use std::io::Read; fn main() { let mut is_in_code_block = false; @@ -21,13 +21,13 @@ fn main() { if is_in_code_block { is_in_inline_code = false; is_in_html_tag = false; - write!(io::stdout(), "{}\n", line).unwrap(); + println!("{}", line); } else { let modified_line = &mut String::new(); let mut previous_char = std::char::REPLACEMENT_CHARACTER; - let mut chars_in_line = line.chars(); + let chars_in_line = line.chars(); - while let Some(possible_match) = chars_in_line.next() { + for possible_match in chars_in_line { // Check if inside inline code. if possible_match == '`' { is_in_inline_code = !is_in_inline_code; @@ -72,7 +72,7 @@ fn main() { modified_line.push(char_to_push); previous_char = char_to_push; } - write!(io::stdout(), "{}\n", modified_line).unwrap(); + println!("{}", modified_line); } } } diff --git a/src/doc/book/tools/src/bin/lfp.rs b/src/doc/book/tools/src/bin/lfp.rs index caab7b26e5..c4d4bce036 100644 --- a/src/doc/book/tools/src/bin/lfp.rs +++ b/src/doc/book/tools/src/bin/lfp.rs @@ -57,7 +57,7 @@ fn main() { } } -const USAGE: &'static str = " +const USAGE: &str = " counter Usage: lfp @@ -102,14 +102,10 @@ fn is_file_of_interest(path: &path::Path) -> bool { } fn is_line_of_interest(line: &str) -> bool { - !line - .split_whitespace() - .filter(|sub_string| { - sub_string.contains("file://") - && !sub_string.contains("file:///projects/") - }) - .collect::>() - .is_empty() + line.split_whitespace().any(|sub_string| { + sub_string.contains("file://") + && !sub_string.contains("file:///projects/") + }) } #[derive(Debug)] diff --git a/src/doc/book/tools/src/bin/link2print.rs b/src/doc/book/tools/src/bin/link2print.rs index 9688d10bf5..1e92ecbccd 100644 --- a/src/doc/book/tools/src/bin/link2print.rs +++ b/src/doc/book/tools/src/bin/link2print.rs @@ -4,7 +4,7 @@ use regex::{Captures, Regex}; use std::collections::HashMap; use std::io; -use std::io::{Read, Write}; +use std::io::Read; fn main() { write_md(parse_links(parse_references(read_md()))); @@ -19,7 +19,7 @@ fn read_md() -> String { } fn write_md(output: String) { - write!(io::stdout(), "{}", output).unwrap(); + print!("{}", output); } fn parse_references(buffer: String) -> (String, HashMap) { @@ -49,7 +49,7 @@ fn parse_links((buffer, ref_map): (String, HashMap)) -> String { Regex::new(r###"^E\d{4}$"###).expect("could not create regex"); let output = re.replace_all(&buffer, |caps: &Captures<'_>| { match caps.name("pre") { - Some(pre_section) => format!("{}", pre_section.as_str()), + Some(pre_section) => pre_section.as_str().to_string(), None => { let name = caps.name("name").expect("could not get name").as_str(); // Really we should ignore text inside code blocks, @@ -71,13 +71,13 @@ fn parse_links((buffer, ref_map): (String, HashMap)) -> String { Some(key) => { match key.as_str() { // `[name][]` - "" => format!("{}", ref_map.get(&name.to_uppercase()).expect(&format!("could not find url for the link text `{}`", name))), + "" => ref_map.get(&name.to_uppercase()).unwrap_or_else(|| panic!("could not find url for the link text `{}`", name)).to_string(), // `[name][reference]` - _ => format!("{}", ref_map.get(&key.as_str().to_uppercase()).expect(&format!("could not find url for the link text `{}`", key.as_str()))), + _ => ref_map.get(&key.as_str().to_uppercase()).unwrap_or_else(|| panic!("could not find url for the link text `{}`", key.as_str())).to_string(), } } // `[name]` as reference - None => format!("{}", ref_map.get(&name.to_uppercase()).expect(&format!("could not find url for the link text `{}`", name))), + None => ref_map.get(&name.to_uppercase()).unwrap_or_else(|| panic!("could not find url for the link text `{}`", name)).to_string(), } } }; diff --git a/src/doc/book/tools/src/bin/release_listings.rs b/src/doc/book/tools/src/bin/release_listings.rs index 56a38e020c..c371d7b308 100644 --- a/src/doc/book/tools/src/bin/release_listings.rs +++ b/src/doc/book/tools/src/bin/release_listings.rs @@ -146,10 +146,10 @@ fn copy_cleaned_rust_file( for line in from_buf.lines() { let line = line?; - if !ANCHOR_OR_SNIP_COMMENTS.is_match(&line) { - if item_name != "lib.rs" || !EMPTY_MAIN.is_match(&line) { - writeln!(&mut to_buf, "{}", line)?; - } + if !ANCHOR_OR_SNIP_COMMENTS.is_match(&line) + && (item_name != "lib.rs" || !EMPTY_MAIN.is_match(&line)) + { + writeln!(&mut to_buf, "{}", line)?; } } diff --git a/src/doc/book/tools/src/bin/remove_hidden_lines.rs b/src/doc/book/tools/src/bin/remove_hidden_lines.rs index 45ce031aa3..dc3c593570 100644 --- a/src/doc/book/tools/src/bin/remove_hidden_lines.rs +++ b/src/doc/book/tools/src/bin/remove_hidden_lines.rs @@ -14,7 +14,7 @@ fn read_md() -> String { } fn write_md(output: String) { - write!(io::stdout(), "{}", output).unwrap(); + print!("{}", output); } fn remove_hidden_lines(input: &str) -> String { diff --git a/src/doc/book/tools/src/bin/remove_links.rs b/src/doc/book/tools/src/bin/remove_links.rs index edccc53c1a..b3f78d70a0 100644 --- a/src/doc/book/tools/src/bin/remove_links.rs +++ b/src/doc/book/tools/src/bin/remove_links.rs @@ -3,7 +3,7 @@ extern crate regex; use regex::{Captures, Regex}; use std::collections::HashSet; use std::io; -use std::io::{Read, Write}; +use std::io::Read; fn main() { let mut buffer = String::new(); @@ -41,5 +41,5 @@ fn main() { caps.get(0).unwrap().as_str().to_string() }); - write!(io::stdout(), "{}", out).unwrap(); + print!("{}", out); } diff --git a/src/doc/book/tools/src/bin/remove_markup.rs b/src/doc/book/tools/src/bin/remove_markup.rs index 06f6a6ba98..c42e588e75 100644 --- a/src/doc/book/tools/src/bin/remove_markup.rs +++ b/src/doc/book/tools/src/bin/remove_markup.rs @@ -2,7 +2,7 @@ extern crate regex; use regex::{Captures, Regex}; use std::io; -use std::io::{Read, Write}; +use std::io::Read; fn main() { write_md(remove_markup(read_md())); @@ -17,7 +17,7 @@ fn read_md() -> String { } fn write_md(output: String) { - write!(io::stdout(), "{}", output).unwrap(); + print!("{}", output); } fn remove_markup(input: String) -> String { diff --git a/src/doc/book/tools/update-rustc.sh b/src/doc/book/tools/update-rustc.sh index 5c9f178b1c..45a0ce4f67 100755 --- a/src/doc/book/tools/update-rustc.sh +++ b/src/doc/book/tools/update-rustc.sh @@ -43,7 +43,7 @@ find -s listings -name output.txt -print0 | while IFS= read -r -d '' f; do # Save the hash from the first test binary; we're going to keep it to # minimize diff churn - test_binary_hash=$(sed -E -ne 's@.*Running [^[:space:]]+ \(target/debug/deps/[^-]*-([^\s]*)\)@\1@p' "${full_output_path}" | head -n 1) + test_binary_hash=$(sed -E -ne 's@.*Running [^[:space:]]+( [^[:space:]\(\)]+)? \(target/debug/deps/[^-]*-([^\s]*)\)@\2@p' "${full_output_path}" | head -n 1) # Act like this is the first time this listing has been built cargo clean @@ -70,7 +70,7 @@ find -s listings -name output.txt -print0 | while IFS= read -r -d '' f; do # Restore the previous test binary hash, if there is one if [ -n "${test_binary_hash}" ]; then - replacement='s@Running ([^[:space:]]+) \(target/debug/deps/([^-]*)-([^\s]*)\)@Running \1 (target/debug/deps/\2-' + replacement='s@Running ([^[:space:]]+)( [^[:space:]\(\)]+)? \(target/debug/deps/([^-]*)-([^\s]*)\)@Running \1\2 (target/debug/deps/\3-' replacement+="${test_binary_hash}" replacement+=')@g' sed -i '' -E -e "${replacement}" "${full_output_path}" diff --git a/src/doc/embedded-book/src/intro/index.md b/src/doc/embedded-book/src/intro/index.md index 01126d8770..7a600fee01 100644 --- a/src/doc/embedded-book/src/intro/index.md +++ b/src/doc/embedded-book/src/intro/index.md @@ -72,6 +72,9 @@ translation listed here, please open a PR to add it. * [Japanese](https://tomoyuki-nakabayashi.github.io/book/) ([repository](https://github.com/tomoyuki-nakabayashi/book)) +* [Chinese](https://xxchang.github.io/book/) + ([repository](https://github.com/XxChang/book)) + ## How to Use This Book This book generally assumes that you’re reading it front-to-back. Later diff --git a/src/doc/embedded-book/src/start/registers.md b/src/doc/embedded-book/src/start/registers.md index cbf885094a..09f695a0a5 100644 --- a/src/doc/embedded-book/src/start/registers.md +++ b/src/doc/embedded-book/src/start/registers.md @@ -22,7 +22,7 @@ You may well find that the code you need to access the peripherals in your micro ## Board Crate -A board crate is the perfect starting point, if you're new to embedded Rust. They nicely abstract the HW details that might be overwelming when starting studying this subject, and makes standard tasks easy, like turning a LED on or off. The functionality they exposes varies a lot between boards. Since this book aims at staying hardware agnostic, the board crates won't be covered by this book. +A board crate is the perfect starting point, if you're new to embedded Rust. They nicely abstract the HW details that might be overwelming when starting studying this subject, and makes standard tasks easy, like turning a LED on or off. The functionality it exposes varies a lot between boards. Since this book aims at staying hardware agnostic, the board crates won't be covered by this book. If you want to experiment with the STM32F3DISCOVERY board, it is highly recommmand to take a look at the [stm32f3-discovery] board crate, which provides functionality to blink the board LEDs, access its compass, bluetooth and more. The [Discovery] book offers a great introduction to the use of a board crate. diff --git a/src/doc/nomicon/.github/workflows/main.yml b/src/doc/nomicon/.github/workflows/main.yml index cf0fafe258..7ace896eba 100644 --- a/src/doc/nomicon/.github/workflows/main.yml +++ b/src/doc/nomicon/.github/workflows/main.yml @@ -6,7 +6,7 @@ jobs: name: Test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Update rustup run: rustup self update - name: Install Rust diff --git a/src/doc/nomicon/src/borrow-splitting.md b/src/doc/nomicon/src/borrow-splitting.md index 51187eae81..3d13ff9542 100644 --- a/src/doc/nomicon/src/borrow-splitting.md +++ b/src/doc/nomicon/src/borrow-splitting.md @@ -1,10 +1,10 @@ # Splitting Borrows The mutual exclusion property of mutable references can be very limiting when -working with a composite structure. The borrow checker understands some basic -stuff, but will fall over pretty easily. It does understand structs -sufficiently to know that it's possible to borrow disjoint fields of a struct -simultaneously. So this works today: +working with a composite structure. The borrow checker (a.k.a. borrowck) +understands some basic stuff, but will fall over pretty easily. It does +understand structs sufficiently to know that it's possible to borrow disjoint +fields of a struct simultaneously. So this works today: ```rust struct Foo { diff --git a/src/doc/nomicon/src/destructors.md b/src/doc/nomicon/src/destructors.md index 3d99961389..e70c5e1d48 100644 --- a/src/doc/nomicon/src/destructors.md +++ b/src/doc/nomicon/src/destructors.md @@ -120,7 +120,7 @@ Next variant. In general this works really nicely because you don't need to worry about adding/removing drops when you refactor your data layout. Still there's -certainly many valid usecases for needing to do trickier things with +certainly many valid use cases for needing to do trickier things with destructors. The classic safe solution to overriding recursive drop and allowing moving out diff --git a/src/doc/nomicon/src/exotic-sizes.md b/src/doc/nomicon/src/exotic-sizes.md index 0c59e2ccca..c4a6d2401d 100644 --- a/src/doc/nomicon/src/exotic-sizes.md +++ b/src/doc/nomicon/src/exotic-sizes.md @@ -157,9 +157,9 @@ because that wouldn't make sense. We recommend against modelling C's `void*` type with `*const Void`. A lot of people started doing that but quickly ran into trouble because Rust doesn't really have any safety guards against trying to instantiate -empty types with unsafe code, and if you do it, it's Undefined Behaviour. +empty types with unsafe code, and if you do it, it's Undefined Behavior. This was especially problematic because developers had a habit of converting -raw pointers to references and `&Void` is *also* Undefined Behaviour to +raw pointers to references and `&Void` is *also* Undefined Behavior to construct. `*const ()` (or equivalent) works reasonably well for `void*`, and can be made diff --git a/src/doc/nomicon/src/ffi.md b/src/doc/nomicon/src/ffi.md index 45a1f61e6a..9b0ff98e61 100644 --- a/src/doc/nomicon/src/ffi.md +++ b/src/doc/nomicon/src/ffi.md @@ -718,17 +718,118 @@ void register(int (*f)(int (*)(int), int)) { No `transmute` required! -## FFI and panics +## FFI and unwinding -It’s important to be mindful of `panic!`s when working with FFI. A `panic!` -across an FFI boundary is undefined behavior. If you’re writing code that may -panic, you should run it in a closure with [`catch_unwind`]: +It’s important to be mindful of unwinding when working with FFI. Each +non-`Rust` ABI comes in two variants, one with `-unwind` suffix and one without. If +you expect Rust `panic`s or foreign (e.g. C++) exceptions to cross an FFI +boundary, that boundary must use the appropriate `-unwind` ABI string (note +that compiling with `panic=abort` will still cause `panic!` to immediately +abort the process, regardless of which ABI is specified by the function that +`panic`s). + +Conversely, if you do not expect unwinding to cross an ABI boundary, use one of +the non-`unwind` ABI strings (other than `Rust`, which always permits +unwinding). If an unwinding operation does encounter an ABI boundary that is +not permitted to unwind, the behavior depends on the source of the unwinding +(Rust `panic` or a foreign exception): + +* `panic` will cause the process to safely abort. +* A foreign exception entering Rust will cause undefined behavior. + +Note that the interaction of `catch_unwind` with foreign exceptions **is +undefined**, as is the interaction of `panic` with foreign exception-catching +mechanisms (notably C++'s `try`/`catch`). + +### Rust `panic` with `"C-unwind"` + + +```rust,ignore +#[no_mangle] +extern "C-unwind" fn example() { + panic!("Uh oh"); +} +``` + +This function (when compiled with `panic=unwind`) is permitted to unwind C++ +stack frames. + +```text +[Rust function with `catch_unwind`, which stops the unwinding] + | + ... + | +[C++ frames] + | ^ + | (calls) | (unwinding + v | goes this +[Rust function `example`] | way) + | | + +--- rust function panics --+ +``` + +If the C++ frames have objects, their destructors will be called. + +### C++ `throw` with `"C-unwind"` + + +```rust,ignore +#[link(...)] +extern "C-unwind" { + // A C++ function that may throw an exception + fn may_throw(); +} + +#[no_mangle] +extern "C-unwind" fn rust_passthrough() { + let b = Box::new(5); + unsafe { may_throw(); } + println!("{:?}", &b); +} +``` + +A C++ function with a `try` block may invoke `rust_passthrough` and `catch` an +exception thrown by `may_throw`. + +```text +[C++ function with `try` block that invokes `rust_passthrough`] + | + ... + | +[Rust function `rust_passthrough`] + | ^ + | (calls) | (unwinding + v | goes this +[C++ function `may_throw`] | way) + | | + +--- C++ function throws ----+ +``` + +If `may_throw` does throw an exception, `b` will be dropped. Otherwise, `5` +will be printed. + +### `panic` can be stopped at an ABI boundary + +```rust +#[no_mangle] +extern "C" fn assert_nonzero(input: u32) { + assert!(input != 0) +} +``` + +If `assert_nonzero` is called with the argument `0`, the runtime is guaranteed +to (safely) abort the process, whether or not compiled with `panic=abort`. + +### Catching `panic` preemptively + +If you are writing Rust code that may panic, and you don't wish to abort the +process if it panics, you must use [`catch_unwind`]: ```rust use std::panic::catch_unwind; #[no_mangle] -pub extern fn oh_no() -> i32 { +pub extern "C" fn oh_no() -> i32 { let result = catch_unwind(|| { panic!("Oops!"); }); @@ -742,7 +843,7 @@ fn main() {} ``` Please note that [`catch_unwind`] will only catch unwinding panics, not -those who abort the process. See the documentation of [`catch_unwind`] +those that abort the process. See the documentation of [`catch_unwind`] for more information. [`catch_unwind`]: ../std/panic/fn.catch_unwind.html diff --git a/src/doc/nomicon/src/intro.md b/src/doc/nomicon/src/intro.md index c6ca90f5aa..4e77ffafed 100644 --- a/src/doc/nomicon/src/intro.md +++ b/src/doc/nomicon/src/intro.md @@ -32,7 +32,7 @@ Where The Reference exists to detail the syntax and semantics of every part of t The Reference will tell you the syntax and semantics of references, destructors, and unwinding, but it won't tell you how combining them can lead to exception-safety issues, or how to deal with those issues. -It should be noted that we haven't synced The Rustnomicon and The Reference well, so they may have a duplicate content. +It should be noted that we haven't synced The Rustnomicon and The Reference well, so they may have duplicate content. In general, if the two documents disagree, The Reference should be assumed to be correct (it isn't yet considered normative, it's just better maintained). Topics that are within the scope of this book include: the meaning of (un)safety, unsafe primitives provided by the language and standard library, techniques for creating safe abstractions with those unsafe primitives, subtyping and variance, exception-safety (panic/unwind-safety), working with uninitialized memory, type punning, concurrency, interoperating with other languages (FFI), optimization tricks, how constructs lower to compiler/OS/hardware primitives, how to **not** make the memory model people angry, how you're **going** to make the memory model people angry, and more. diff --git a/src/doc/nomicon/src/phantom-data.md b/src/doc/nomicon/src/phantom-data.md index 726f7ba049..ca1c2c21cf 100644 --- a/src/doc/nomicon/src/phantom-data.md +++ b/src/doc/nomicon/src/phantom-data.md @@ -42,43 +42,186 @@ struct Iter<'a, T: 'a> { and that's it. The lifetime will be bounded, and your iterator will be covariant over `'a` and `T`. Everything Just Works. -Another important example is Vec, which is (approximately) defined as follows: +## Generic parameters and drop-checking + +In the past, there used to be another thing to take into consideration. + +This very documentation used to say: + +> Another important example is Vec, which is (approximately) defined as follows: +> +> ```rust +> struct Vec { +> data: *const T, // *const for variance! +> len: usize, +> cap: usize, +> } +> ``` +> +> Unlike the previous example, it *appears* that everything is exactly as we +> want. Every generic argument to Vec shows up in at least one field. +> Good to go! +> +> Nope. +> +> The drop checker will generously determine that `Vec` does not own any values +> of type T. This will in turn make it conclude that it doesn't need to worry +> about Vec dropping any T's in its destructor for determining drop check +> soundness. This will in turn allow people to create unsoundness using +> Vec's destructor. +> +> In order to tell the drop checker that we *do* own values of type T, and +> therefore may drop some T's when *we* drop, we must add an extra `PhantomData` +> saying exactly that: +> +> ```rust +> use std::marker; +> +> struct Vec { +> data: *const T, // *const for variance! +> len: usize, +> cap: usize, +> _owns_T: marker::PhantomData, +> } +> ``` + +But ever since [RFC 1238](https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html), +**this is no longer true nor necessary**. + +If you were to write: ```rust struct Vec { - data: *const T, // *const for variance! + data: *const T, // `*const` for variance! len: usize, cap: usize, } + +# #[cfg(any())] +impl Drop for Vec { /* … */ } ``` -Unlike the previous example, it *appears* that everything is exactly as we -want. Every generic argument to Vec shows up in at least one field. -Good to go! +then the existence of that `impl Drop for Vec` makes it so Rust will consider +that that `Vec` _owns_ values of type `T` (more precisely: may use values of type `T` +in its `Drop` implementation), and Rust will thus not allow them to _dangle_ should a +`Vec` be dropped. + +**Adding an extra `_owns_T: PhantomData` field is thus _superfluous_ and accomplishes nothing**. + +___ + +But this situation can sometimes lead to overly restrictive code. That's why the +standard library uses an unstable and `unsafe` attribute to opt back into the old +"unchecked" drop-checking behavior, that this very documentation warned about: the +`#[may_dangle]` attribute. -Nope. +### An exception: the special case of the standard library and its unstable `#[may_dangle]` -The drop checker will generously determine that `Vec` does not own any values -of type T. This will in turn make it conclude that it doesn't need to worry -about Vec dropping any T's in its destructor for determining drop check -soundness. This will in turn allow people to create unsoundness using -Vec's destructor. +This section can be skipped if you are only writing your own library code; but if you are +curious about what the standard library does with the actual `Vec` definition, you'll notice +that it still needs to use a `_owns_T: PhantomData` field for soundness. -In order to tell the drop checker that we *do* own values of type T, and -therefore may drop some T's when *we* drop, we must add an extra `PhantomData` -saying exactly that: +
Click here to see why + +Consider the following example: ```rust -use std::marker; +fn main() { + let mut v: Vec<&str> = Vec::new(); + let s: String = "Short-lived".into(); + v.push(&s); + drop(s); +} // <- `v` is dropped here +``` + +with a classical `impl Drop for Vec {` definition, the above [is denied]. + +[is denied]: https://rust.godbolt.org/z/ans15Kqz3 + +Indeed, in this case we have a `Vec` vector of `'s`-lived references +to `str`ings, but in the case of `let s: String`, it is dropped before the `Vec` is, and +thus `'s` **is expired** by the time the `Vec` is dropped, and the +`impl<'s> Drop for Vec<&'s str> {` is used. + +This means that if such `Drop` were to be used, it would be dealing with an _expired_, or +_dangling_ lifetime `'s`. But this is contrary to Rust principles, where by default all +Rust references involved in a function signature are non-dangling and valid to dereference. + +Hence why Rust has to conservatively deny this snippet. + +And yet, in the case of the real `Vec`, the `Drop` impl does not care about `&'s str`, +_since it has no drop glue of its own_: it only wants to deallocate the backing buffer. + +In other words, it would be nice if the above snippet was somehow accepted, by special +casing `Vec`, or by relying on some special property of `Vec`: `Vec` could try to +_promise not to use the `&'s str`s it holds when being dropped_. + +This is the kind of `unsafe` promise that can be expressed with `#[may_dangle]`: + +```rust ,ignore +unsafe impl<#[may_dangle] 's> Drop for Vec<&'s str> { /* … */ } +``` + +or, more generally: + +```rust ,ignore +unsafe impl<#[may_dangle] T> Drop for Vec { /* … */ } +``` + +is the `unsafe` way to opt out of this conservative assumption that Rust's drop +checker makes about type parameters of a dropped instance not being allowed to dangle. + +And when this is done, such as in the standard library, we need to be careful in the +case where `T` has drop glue of its own. In this instance, imagine replacing the +`&'s str`s with a `struct PrintOnDrop<'s> /* = */ (&'s str);` which would have a +`Drop` impl wherein the inner `&'s str` would be dereferenced and printed to the screen. + +Indeed, `Drop for Vec {`, before deallocating the backing buffer, does have to transitively +drop each `T` item when it has drop glue; in the case of `PrintOnDrop<'s>`, it means that +`Drop for Vec>` has to transitively drop the `PrintOnDrop<'s>`s elements before +deallocating the backing buffer. + +So when we said that `'s` `#[may_dangle]`, it was an excessively loose statement. We'd rather want +to say: "`'s` may dangle provided it not be involved in some transitive drop glue". Or, more generally, +"`T` may dangle provided it not be involved in some transitive drop glue". This "exception to the +exception" is a pervasive situation whenever **we own a `T`**. That's why Rust's `#[may_dangle]` is +smart enough to know of this opt-out, and will thus be disabled _when the generic parameter is held +in an owned fashion_ by the fields of the struct. + +Hence why the standard library ends up with: + +```rust +# #[cfg(any())] +// we pinky-swear not to use `T` when dropping a `Vec`… +unsafe impl<#[may_dangle] T> Drop for Vec { + fn drop(&mut self) { + unsafe { + if mem::needs_drop::() { + /* … except here, that is, … */ + ptr::drop_in_place::<[T]>(/* … */); + } + // … + dealloc(/* … */) + // … + } + } +} struct Vec { - data: *const T, // *const for variance! + // … except for the fact that a `Vec` owns `T` items and + // may thus be dropping `T` items on drop! + _owns_T: core::marker::PhantomData, + + ptr: *const T, // `*const` for variance (but this does not express ownership of a `T` *per se*) len: usize, cap: usize, - _marker: marker::PhantomData, } ``` +
+ +___ + Raw pointers that own an allocation is such a pervasive pattern that the standard library made a utility for itself called `Unique` which: diff --git a/src/doc/nomicon/src/subtyping.md b/src/doc/nomicon/src/subtyping.md index c944c1e803..91e870e5e8 100644 --- a/src/doc/nomicon/src/subtyping.md +++ b/src/doc/nomicon/src/subtyping.md @@ -75,7 +75,7 @@ this stuff really works, and how we can mess it up. The core problem is that this rule, naively applied, will lead to *meowing Dogs*. That is, we can convince someone that a Dog is actually a Cat. This completely destroys the fabric -of our static type system, making it worse than useless (and leading to Undefined Behaviour). +of our static type system, making it worse than useless (and leading to Undefined Behavior). Here's a simple example of this happening when we apply subtyping in a completely naive "find and replace" way. diff --git a/src/doc/reference/src/const_eval.md b/src/doc/reference/src/const_eval.md index b46e94e123..c0560376c7 100644 --- a/src/doc/reference/src/const_eval.md +++ b/src/doc/reference/src/const_eval.md @@ -42,9 +42,8 @@ to be run. * The [dereference operator] except for raw pointers. * [Grouped] expressions. * [Cast] expressions, except - * pointer to address casts, - * function pointer to address casts, and - * unsizing casts to trait objects. + * pointer to address casts and + * function pointer to address casts. * Calls of [const functions] and const methods. * [loop], [while] and [`while let`] expressions. * [if], [`if let`] and [match] expressions. diff --git a/src/doc/reference/src/expressions/match-expr.md b/src/doc/reference/src/expressions/match-expr.md index febf60cc37..edbc636582 100644 --- a/src/doc/reference/src/expressions/match-expr.md +++ b/src/doc/reference/src/expressions/match-expr.md @@ -125,7 +125,7 @@ Moreover, by holding a shared reference while evaluating the guard, mutation ins ## Attributes on match arms Outer attributes are allowed on match arms. -The only attributes that have meaning on match arms are [`cfg`], [`cold`], and the [lint check attributes]. +The only attributes that have meaning on match arms are [`cfg`] and the [lint check attributes]. [Inner attributes] are allowed directly after the opening brace of the match expression in the same expression contexts as [attributes on block expressions]. @@ -135,7 +135,6 @@ The only attributes that have meaning on match arms are [`cfg`], [`cold`], and t [_InnerAttribute_]: ../attributes.md [_OuterAttribute_]: ../attributes.md [`cfg`]: ../conditional-compilation.md -[`cold`]: ../attributes/codegen.md#the-cold-attribute [lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes [Range Expression]: range-expr.md diff --git a/src/doc/reference/src/inline-assembly.md b/src/doc/reference/src/inline-assembly.md index dc4bc5475b..6233475a33 100644 --- a/src/doc/reference/src/inline-assembly.md +++ b/src/doc/reference/src/inline-assembly.md @@ -41,7 +41,7 @@ The following ABNF specifies the general syntax: ```text format_string := STRING_LITERAL / RAW_STRING_LITERAL dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout" -reg_spec := / "" +reg_spec := / "\"" "\"" operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_" reg_operand := dir_spec "(" reg_spec ")" operand_expr operand := reg_operand @@ -162,6 +162,7 @@ Here is the list of currently supported register classes: | x86 | `kreg0` | `k0` | Only clobbers | | x86 | `x87_reg` | `st([0-7])` | Only clobbers | | x86 | `mmx_reg` | `mm[0-7]` | Only clobbers | +| x86-64 | `tmm_reg` | `tmm[0-7]` | Only clobbers | | AArch64 | `reg` | `x[0-30]` | `r` | | AArch64 | `vreg` | `v[0-31]` | `w` | | AArch64 | `vreg_low16` | `v[0-15]` | `x` | @@ -185,7 +186,7 @@ Here is the list of currently supported register classes: > > - On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class. > -> - Some register classes are marked as "Only clobbers" which means that they cannot be used for inputs or outputs, only clobbers of the form `out("reg") _` or `lateout("reg") _`. +> - Some register classes are marked as "Only clobbers" which means that registers in these classes cannot be used for inputs or outputs, only clobbers of the form `out() _` or `lateout() _`. Each register class has constraints on which value types they can be used with. This is necessary because the way a value is loaded into a register depends on its type. @@ -204,6 +205,7 @@ The availability of supported types for a particular register class may depend o | x86 | `kreg` | `avx512bw` | `i32`, `i64` | | x86 | `mmx_reg` | N/A | Only clobbers | | x86 | `x87_reg` | N/A | Only clobbers | +| x86 | `tmm_reg` | N/A | Only clobbers | | AArch64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | | AArch64 | `vreg` | `neon` | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`,
`i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | | AArch64 | `preg` | N/A | Only clobbers | @@ -356,7 +358,7 @@ If all references to an operand already have modifiers then the warning is suppr ## ABI clobbers The `clobber_abi` keyword can be used to apply a default set of clobbers to an `asm!` block. -This will automatically insert the necessary clobber constraints as needed for calling a function with a particular calling convention: if the calling convention does not fully preserve the value of a register across a call then a `lateout("reg") _` is implicitly added to the operands list. +This will automatically insert the necessary clobber constraints as needed for calling a function with a particular calling convention: if the calling convention does not fully preserve the value of a register across a call then `lateout("...") _` is implicitly added to the operands list (where the `...` is replaced by the register's name). `clobber_abi` may be specified any number of times. It will insert a clobber for all unique registers in the union of all specified calling conventions. @@ -367,8 +369,8 @@ The following ABIs can be used with `clobber_abi`: | Architecture | ABI name | Clobbered registers | | ------------ | -------- | ------------------- | | x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `k[0-7]`, `st([0-7])` | -| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[0-7]`, `st([0-7])` | -| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[0-7]`, `st([0-7])` | +| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[0-7]`, `st([0-7])`, `tmm[0-7]` | +| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[0-7]`, `st([0-7])`, `tmm[0-7]` | | AArch64 | `"C"`, `"system"`, `"efiapi"` | `x[0-17]`, `x18`\*, `x30`, `v[0-31]`, `p[0-15]`, `ffr` | | ARM | `"C"`, `"system"`, `"efiapi"`, `"aapcs"` | `r[0-3]`, `r12`, `r14`, `s[0-15]`, `d[0-7]`, `d[16-31]` | | RISC-V | `"C"`, `"system"`, `"efiapi"` | `x1`, `x[5-7]`, `x[10-17]`, `x[28-31]`, `f[0-7]`, `f[10-17]`, `f[28-31]`, `v[0-31]` | diff --git a/src/doc/reference/src/items/external-blocks.md b/src/doc/reference/src/items/external-blocks.md index 84f8046f22..dbe30ccc4b 100644 --- a/src/doc/reference/src/items/external-blocks.md +++ b/src/doc/reference/src/items/external-blocks.md @@ -162,6 +162,29 @@ this to satisfy the linking requirements of extern blocks elsewhere in your code (including upstream crates) instead of adding the attribute to each extern block. +#### Linking modifiers: `bundle` + +This modifier is only compatible with the `static` linking kind. +Using any other kind will result in a compiler error. + +When building a rlib or staticlib `+bundle` means that all object files from the native static +library will be added to the rlib or staticlib archive, and then used from it during linking of +the final binary. + +When building a rlib `-bundle` means that the native static library is registered as a dependency +of that rlib "by name", and object files from it are included only during linking of the final +binary, the file search by that name is also performed during final linking. \ +When building a staticlib `-bundle` means that the native static library is simply not included +into the archive and some higher level build system will need to add it later during linking of +the final binary. + +This modifier has no effect when building other targets like executables or dynamic libraries. + +The default for this modifier is `+bundle`. + +More implementation details about this modifier can be found in +[`bundle` documentation for rustc]. + #### Linking modifiers: `whole-archive` This modifier is only compatible with the `static` linking kind. @@ -170,7 +193,10 @@ Using any other kind will result in a compiler error. `+whole-archive` means that the static library is linked as a whole archive without throwing any object files away. -More implementation details about this modifier can be found in [documentation for rustc]. +The default for this modifier is `-whole-archive`. + +More implementation details about this modifier can be found in +[`whole-archive` documentation for rustc]. ### The `link_name` attribute @@ -205,4 +231,5 @@ restrictions as [regular function parameters]. [_Visibility_]: ../visibility-and-privacy.md [attributes]: ../attributes.md [regular function parameters]: functions.md#attributes-on-function-parameters -[documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive +[`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle +[`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive diff --git a/src/doc/reference/src/names/namespaces.md b/src/doc/reference/src/names/namespaces.md index 1b07d9ffdc..14811697cc 100644 --- a/src/doc/reference/src/names/namespaces.md +++ b/src/doc/reference/src/names/namespaces.md @@ -50,7 +50,7 @@ The following is a list of namespaces, with their corresponding entities: * [Attribute macros] * Lifetime Namespace * [Generic lifetime parameters] -* Label Namespace[^rustc-lifetime-shadow] +* Label Namespace * [Loop labels] An example of how overlapping names in different namespaces can be used unambiguously: @@ -115,12 +115,6 @@ For example, the [`cfg` attribute] and the [`cfg` macro] are two different entit It is still an error for a [`use` import] to shadow another macro, regardless of their sub-namespaces. -[^rustc-lifetime-shadow]: `rustc` currently warns about shadowing when using - the same name for a label and lifetime in the same scope, but it still - treats them independently. This is intended as a future-compatibility - warning about a possible extension to the language. See [PR - #24162](https://github.com/rust-lang/rust/pull/24162). - [`cfg` attribute]: ../conditional-compilation.md#the-cfg-attribute [`cfg` macro]: ../conditional-compilation.md#the-cfg-macro [`for`]: ../expressions/loop-expr.md#iterator-loops diff --git a/src/doc/reference/src/paths.md b/src/doc/reference/src/paths.md index 51bd8cad56..cb6b24aa07 100644 --- a/src/doc/reference/src/paths.md +++ b/src/doc/reference/src/paths.md @@ -81,6 +81,9 @@ arguments, then const arguments, then equality constraints. Const arguments must be surrounded by braces unless they are a [literal] or a single segment path. +The synthetic type parameters corresponding to `impl Trait` types are implicit, +and these cannot be explicitly specified. + ## Qualified paths > **Syntax**\ diff --git a/src/doc/reference/src/procedural-macros.md b/src/doc/reference/src/procedural-macros.md index d983394ca9..31f029a633 100644 --- a/src/doc/reference/src/procedural-macros.md +++ b/src/doc/reference/src/procedural-macros.md @@ -52,8 +52,9 @@ type, unlike `Vec`, is cheap to clone. All tokens have an associated `Span`. A `Span` is an opaque value that cannot be modified but can be manufactured. `Span`s represent an extent of source -code within a program and are primarily used for error reporting. You can modify -the `Span` of any token. +code within a program and are primarily used for error reporting. While you +cannot modify a `Span` itself, you can always change the `Span` *associated* +with any token, such as through getting a `Span` from another token. ### Procedural macro hygiene diff --git a/src/doc/reference/src/subtyping.md b/src/doc/reference/src/subtyping.md index 15b0b206a2..40f5a15440 100644 --- a/src/doc/reference/src/subtyping.md +++ b/src/doc/reference/src/subtyping.md @@ -61,25 +61,51 @@ Variance of types is automatically determined as follows | `[T]` and `[T; n]` | | covariant | | `fn() -> T` | | covariant | | `fn(T) -> ()` | | contravariant | -| `fn(T) -> T` | | invariant | | `std::cell::UnsafeCell` | | invariant | | `std::marker::PhantomData` | | covariant | | `dyn Trait + 'a` | covariant | invariant | -The variance of other `struct`, `enum`, `union`, and tuple types is decided by +The variance of other `struct`, `enum`, and `union` types is decided by looking at the variance of the types of their fields. If the parameter is used in positions with different variances then the parameter is invariant. For -example the following struct is covariant in `'a` and `T` and invariant in `'b` +example the following struct is covariant in `'a` and `T` and invariant in `'b`, `'c`, and `U`. ```rust use std::cell::UnsafeCell; -struct Variance<'a, 'b, T, U: 'a> { +struct Variance<'a, 'b, 'c, T, U: 'a> { x: &'a U, // This makes `Variance` covariant in 'a, and would // make it covariant in U, but U is used later y: *const T, // Covariant in T z: UnsafeCell<&'b f64>, // Invariant in 'b w: *mut U, // Invariant in U, makes the whole struct invariant + + f: fn(&'c ()) -> &'c () // Both co- and contravariant, makes 'c invariant + // in the struct. +} +``` + +When used outside of an `struct`, `enum`, or `union`, the variance for parameters is checked at each location separately. + +```rust +# use std::cell::UnsafeCell; +fn generic_tuple<'short, 'long: 'short>( + // 'long is used inside of a tuple in both a co- and invariant position. + x: (&'long u32, UnsafeCell<&'long u32>), +) { + // As the variance at these positions is computed separately, + // we can freely shrink 'long in the covariant position. + let _: (&'short u32, UnsafeCell<&'long u32>) = x; +} + +fn takes_fn_ptr<'short, 'middle: 'short>( + // 'middle is used in both a co- and contravariant position. + f: fn(&'middle ()) -> &'middle (), +) { + // As the variance at these positions is computed separately, + // we can freely shrink 'middle in the covariant position + // and extend it in the contravariant position. + let _: fn(&'static ()) -> &'short () = f; } ``` diff --git a/src/doc/reference/src/tokens.md b/src/doc/reference/src/tokens.md index cdb4f07f75..197c20147d 100644 --- a/src/doc/reference/src/tokens.md +++ b/src/doc/reference/src/tokens.md @@ -24,16 +24,16 @@ Literals are tokens used in [literal expressions]. #### Characters and strings -| | Example | `#` sets | Characters | Escapes | -|----------------------------------------------|-----------------|-------------|-------------|---------------------| -| [Character](#character-literals) | `'H'` | 0 | All Unicode | [Quote](#quote-escapes) & [ASCII](#ascii-escapes) & [Unicode](#unicode-escapes) | -| [String](#string-literals) | `"hello"` | 0 | All Unicode | [Quote](#quote-escapes) & [ASCII](#ascii-escapes) & [Unicode](#unicode-escapes) | -| [Raw string](#raw-string-literals) | `r#"hello"#` | 0 or more\* | All Unicode | `N/A` | -| [Byte](#byte-literals) | `b'H'` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) | -| [Byte string](#byte-string-literals) | `b"hello"` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) | -| [Raw byte string](#raw-byte-string-literals) | `br#"hello"#` | 0 or more\* | All ASCII | `N/A` | +| | Example | `#` sets\* | Characters | Escapes | +|----------------------------------------------|-----------------|------------|-------------|---------------------| +| [Character](#character-literals) | `'H'` | 0 | All Unicode | [Quote](#quote-escapes) & [ASCII](#ascii-escapes) & [Unicode](#unicode-escapes) | +| [String](#string-literals) | `"hello"` | 0 | All Unicode | [Quote](#quote-escapes) & [ASCII](#ascii-escapes) & [Unicode](#unicode-escapes) | +| [Raw string](#raw-string-literals) | `r#"hello"#` | <256 | All Unicode | `N/A` | +| [Byte](#byte-literals) | `b'H'` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) | +| [Byte string](#byte-string-literals) | `b"hello"` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) | +| [Raw byte string](#raw-byte-string-literals) | `br#"hello"#` | <256 | All ASCII | `N/A` | -\* The number of `#`s on each side of the same literal must be equivalent +\* The number of `#`s on each side of the same literal must be equivalent. #### ASCII escapes @@ -148,18 +148,28 @@ which must be _escaped_ by a preceding `U+005C` character (`\`). Line-breaks are allowed in string literals. A line-break is either a newline (`U+000A`) or a pair of carriage return and newline (`U+000D`, `U+000A`). Both byte sequences are normally translated to `U+000A`, but as a special exception, -when an unescaped `U+005C` character (`\`) occurs immediately before the -line-break, then the `U+005C` character, the line-break, and all whitespace at the -beginning of the next line are ignored. Thus `a` and `b` are equal: +when an unescaped `U+005C` character (`\`) occurs immediately before a line +break, then the line break character(s), and all immediately following +` ` (`U+0020`), `\t` (`U+0009`), `\n` (`U+000A`) and `\r` (`U+0000D`) characters +are ignored. Thus `a`, `b` and `c` are equal: ```rust let a = "foobar"; let b = "foo\ bar"; +let c = "foo\ -assert_eq!(a,b); + bar"; + +assert_eq!(a, b); +assert_eq!(b, c); ``` +> Note: Rust skipping additional newlines (like in example `c`) is potentially confusing and +> unexpected. This behavior may be adjusted in the future. Until a decision is made, it is +> recommended to avoid relying on this, i.e. skipping multiple newlines with line continuations. +> See [this issue](https://github.com/rust-lang/reference/pull/1042) for more information. + #### Character escapes Some additional _escapes_ are available in either character or non-raw string @@ -193,7 +203,7 @@ following forms: >    | `#` RAW_STRING_CONTENT `#` Raw string literals do not process any escapes. They start with the character -`U+0072` (`r`), followed by zero or more of the character `U+0023` (`#`) and a +`U+0072` (`r`), followed by fewer than 256 of the character `U+0023` (`#`) and a `U+0022` (double-quote) character. The _raw string body_ can contain any sequence of Unicode characters and is terminated only by another `U+0022` (double-quote) character, followed by the same number of `U+0023` (`#`) characters that preceded @@ -284,7 +294,7 @@ following forms: >    _any ASCII (i.e. 0x00 to 0x7F)_ Raw byte string literals do not process any escapes. They start with the -character `U+0062` (`b`), followed by `U+0072` (`r`), followed by zero or more +character `U+0062` (`b`), followed by `U+0072` (`r`), followed by fewer than 256 of the character `U+0023` (`#`), and a `U+0022` (double-quote) character. The _raw string body_ can contain any sequence of ASCII characters and is terminated only by another `U+0022` (double-quote) character, followed by the same number of diff --git a/src/doc/reference/src/types.md b/src/doc/reference/src/types.md index a7ce5bc824..aed10fd0fd 100644 --- a/src/doc/reference/src/types.md +++ b/src/doc/reference/src/types.md @@ -104,9 +104,6 @@ itself. Such recursion has restrictions: Rec = &'static [Rec]` is not allowed. * The size of a recursive type must be finite; in other words the recursive fields of the type must be [pointer types]. -* Recursive type definitions can cross module boundaries, but not module - *visibility* boundaries, or crate boundaries (in order to simplify the module - system and type checker). An example of a *recursive* type and its use: diff --git a/src/doc/rust-by-example/src/error/multiple_error_types/wrap_error.md b/src/doc/rust-by-example/src/error/multiple_error_types/wrap_error.md index 392b783aed..3da5984936 100644 --- a/src/doc/rust-by-example/src/error/multiple_error_types/wrap_error.md +++ b/src/doc/rust-by-example/src/error/multiple_error_types/wrap_error.md @@ -4,7 +4,7 @@ An alternative to boxing errors is to wrap them in your own error type. ```rust,editable use std::error; -use std::error::Error as _; +use std::error::Error; use std::num::ParseIntError; use std::fmt; diff --git a/src/doc/rust-by-example/src/flow_control/match/guard.md b/src/doc/rust-by-example/src/flow_control/match/guard.md index 9caa65aa00..6dba58f138 100644 --- a/src/doc/rust-by-example/src/flow_control/match/guard.md +++ b/src/doc/rust-by-example/src/flow_control/match/guard.md @@ -3,33 +3,38 @@ A `match` *guard* can be added to filter the arm. ```rust,editable +enum Temperature { + Celsius(i32), + Farenheit(i32), +} + fn main() { - let pair = (2, -2); - // TODO ^ Try different values for `pair` - - println!("Tell me about {:?}", pair); - match pair { - (x, y) if x == y => println!("These are twins"), - // The ^ `if condition` part is a guard - (x, y) if x + y == 0 => println!("Antimatter, kaboom!"), - (x, _) if x % 2 == 1 => println!("The first one is odd"), - _ => println!("No correlation..."), + let temperature = Temperature::Celsius(35); + // ^ TODO try different values for `temperature` + + match temperature { + Temperature::Celsius(t) if t > 30 => println!("{}C is above 30 Celsius", t), + // The `if condition` part ^ is a guard + Temperature::Celsius(t) => println!("{}C is below 30 Celsius", t), + + Temperature::Farenheit(t) if t > 86 => println!("{}F is above 86 Farenheit", t), + Temperature::Farenheit(t) => println!("{}F is below 86 Farenheit", t), } } ``` -Note that the compiler does not check arbitrary expressions for whether all -possible conditions have been checked. Therefore, you must use the `_` pattern -at the end. +Note that the compiler won't take guard conditions into account when checking +if all patterns are covered by the match expression. -```rust,editable +```rust,editable,ignore,mdbook-runnable fn main() { let number: u8 = 4; match number { i if i == 0 => println!("Zero"), i if i > 0 => println!("Greater than zero"), - _ => println!("Fell through"), // This should not be possible to reach + // _ => unreachable!("Should never happen."), + // TODO ^ uncomment to fix compilation } } ``` @@ -37,3 +42,4 @@ fn main() { ### See also: [Tuples](../../primitives/tuples.md) +[Enums](../../custom_types/enum.md) diff --git a/src/doc/rust-by-example/src/generics/phantom.md b/src/doc/rust-by-example/src/generics/phantom.md index 59cf125d11..8743a3ed68 100644 --- a/src/doc/rust-by-example/src/generics/phantom.md +++ b/src/doc/rust-by-example/src/generics/phantom.md @@ -4,7 +4,7 @@ A phantom type parameter is one that doesn't show up at runtime, but is checked statically (and only) at compile time. Data types can use extra generic type parameters to act as markers -or to perform type checking at compile time. These extra parameters +or to perform type checking at compile time. These extra parameters hold no storage values, and have no runtime behavior. In the following example, we combine [std::marker::PhantomData] @@ -16,7 +16,7 @@ use std::marker::PhantomData; // A phantom tuple struct which is generic over `A` with hidden parameter `B`. #[derive(PartialEq)] // Allow equality test for this type. -struct PhantomTuple(A,PhantomData); +struct PhantomTuple(A, PhantomData); // A phantom type struct which is generic over `A` with hidden parameter `B`. #[derive(PartialEq)] // Allow equality test for this type. @@ -42,14 +42,14 @@ fn main() { first: 'Q', phantom: PhantomData, }; - + // Compile-time Error! Type mismatch so these cannot be compared: - //println!("_tuple1 == _tuple2 yields: {}", - // _tuple1 == _tuple2); - + // println!("_tuple1 == _tuple2 yields: {}", + // _tuple1 == _tuple2); + // Compile-time Error! Type mismatch so these cannot be compared: - //println!("_struct1 == _struct2 yields: {}", - // _struct1 == _struct2); + // println!("_struct1 == _struct2 yields: {}", + // _struct1 == _struct2); } ``` @@ -60,4 +60,4 @@ fn main() { [Derive]: ../trait/derive.md [struct]: ../custom_types/structs.md [TupleStructs]: ../custom_types/structs.md -[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html \ No newline at end of file +[std::marker::PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html diff --git a/src/doc/rust-by-example/src/hello/print.md b/src/doc/rust-by-example/src/hello/print.md index 20331ef049..efedeb79df 100644 --- a/src/doc/rust-by-example/src/hello/print.md +++ b/src/doc/rust-by-example/src/hello/print.md @@ -6,8 +6,8 @@ some of which include: * `format!`: write formatted text to [`String`][string] * `print!`: same as `format!` but the text is printed to the console (io::stdout). * `println!`: same as `print!` but a newline is appended. -* `eprint!`: same as `format!` but the text is printed to the standard error (io::stderr). -* `eprintln!`: same as `eprint!`but a newline is appended. +* `eprint!`: same as `print!` but the text is printed to the standard error (io::stderr). +* `eprintln!`: same as `eprint!` but a newline is appended. All parse text in the same fashion. As a plus, Rust checks formatting correctness at compile time. diff --git a/src/doc/rust-by-example/src/macros/dsl.md b/src/doc/rust-by-example/src/macros/dsl.md index fb0c23550d..9aaeda34cd 100644 --- a/src/doc/rust-by-example/src/macros/dsl.md +++ b/src/doc/rust-by-example/src/macros/dsl.md @@ -10,12 +10,12 @@ an expression and have the output printed to console. ```rust,editable macro_rules! calculate { - (eval $e:expr) => {{ + (eval $e:expr) => { { let val: usize = $e; // Force types to be integers println!("{} = {}", stringify!{$e}, val); } - }}; + }; } fn main() { diff --git a/src/doc/rust-by-example/src/primitives/array.md b/src/doc/rust-by-example/src/primitives/array.md index e624f03271..841c71c14d 100644 --- a/src/doc/rust-by-example/src/primitives/array.md +++ b/src/doc/rust-by-example/src/primitives/array.md @@ -6,9 +6,9 @@ at compile time, is part of their type signature `[T; length]`. Slices are similar to arrays, but their length is not known at compile time. Instead, a slice is a two-word object, the first word is a pointer to the data, -and the second word is the length of the slice. The word size is the same as -usize, determined by the processor architecture eg 64 bits on an x86-64. -Slices can be used to borrow a section of an array, and have the type signature +and the second word is the length of the slice. The word size is the same as +usize, determined by the processor architecture e.g. 64 bits on an x86-64. +Slices can be used to borrow a section of an array, and have the type signature `&[T]`. ```rust,editable,ignore,mdbook-runnable @@ -53,6 +53,17 @@ fn main() { assert_eq!(&empty_array, &[]); assert_eq!(&empty_array, &[][..]); // same but more verbose + // Arrays can be safely accessed using `.get`, which returns an + // `Option`. This can be matched as shown below, or used with + // `.expect()` if you would like the program to exit with a nice + // message instead of happily continue. + for i in 0..xs.len() + 1 { // OOPS, one element too far + match xs.get(i) { + Some(xval) => println!("{}: {}", i, xval), + None => println!("Slow down! {} is too far!", i), + } + } + // Out of bound indexing causes compile error //println!("{}", xs[5]); } diff --git a/src/doc/rust-by-example/src/std/arc.md b/src/doc/rust-by-example/src/std/arc.md index 08d1ad31aa..f4c1ce80e7 100644 --- a/src/doc/rust-by-example/src/std/arc.md +++ b/src/doc/rust-by-example/src/std/arc.md @@ -1,8 +1,13 @@ # Arc -When shared ownership between threads is needed, `Arc`(Atomic Reference Counted) can be used. This struct, via the `Clone` implementation can create a reference pointer for the location of a value in the memory heap while increasing the reference counter. As it shares ownership between threads, when the last reference pointer to a value is out of scope, the variable is dropped. +When shared ownership between threads is needed, `Arc`(Atomically Reference +Counted) can be used. This struct, via the `Clone` implementation can create +a reference pointer for the location of a value in the memory heap while +increasing the reference counter. As it shares ownership between threads, when +the last reference pointer to a value is out of scope, the variable is dropped. ```rust,editable +use std::time::Duration; use std::sync::Arc; use std::thread; @@ -11,8 +16,8 @@ fn main() { let apple = Arc::new("the same apple"); for _ in 0..10 { - // Here there is no value specification as it is a pointer to a reference - // in the memory heap. + // Here there is no value specification as it is a pointer to a + // reference in the memory heap. let apple = Arc::clone(&apple); thread::spawn(move || { @@ -21,6 +26,8 @@ fn main() { println!("{:?}", apple); }); } -} + // Make sure all Arc instances are printed from spawned threads. + thread::sleep(Duration::from_secs(1)); +} ``` diff --git a/src/doc/rust-by-example/src/testing/doc_testing.md b/src/doc/rust-by-example/src/testing/doc_testing.md index 642cbe8a58..cdd32cd01f 100644 --- a/src/doc/rust-by-example/src/testing/doc_testing.md +++ b/src/doc/rust-by-example/src/testing/doc_testing.md @@ -3,7 +3,7 @@ The primary way of documenting a Rust project is through annotating the source code. Documentation comments are written in [markdown] and support code blocks in them. Rust takes care about correctness, so these code blocks are -compiled and used as tests. +compiled and used as documentation tests. ```rust,ignore /// First line is a short summary describing function. @@ -48,7 +48,8 @@ pub fn div(a: i32, b: i32) -> i32 { } ``` -Tests can be run with `cargo test`: +Code blocks in documentation are automatically tested +when running the regular `cargo test` command: ```shell $ cargo test @@ -73,8 +74,8 @@ the functionality, which is one of the most important [guidelines][question-instead-of-unwrap]. It allows using examples from docs as complete code snippets. But using `?` makes compilation fail since `main` returns `unit`. The ability to hide some source lines from documentation comes -to the rescue: one may write `fn try_main() -> Result<(), ErrorType>`, hide it and -`unwrap` it in hidden `main`. Sounds complicated? Here's an example: +to the rescue: one may write `fn try_main() -> Result<(), ErrorType>`, hide it +and `unwrap` it in hidden `main`. Sounds complicated? Here's an example: ```rust,ignore /// Using hidden `try_main` in doc tests. diff --git a/src/doc/rust-by-example/src/trait/disambiguating.md b/src/doc/rust-by-example/src/trait/disambiguating.md index c893e9dc8d..ae80d4acb8 100644 --- a/src/doc/rust-by-example/src/trait/disambiguating.md +++ b/src/doc/rust-by-example/src/trait/disambiguating.md @@ -1,9 +1,11 @@ # Disambiguating overlapping traits -A type can implement many different traits. What if two traits both require the same name? For example, many traits might have a method named `get()`. They might even have different return types! +A type can implement many different traits. What if two traits both require +the same name? For example, many traits might have a method named `get()`. +They might even have different return types! -Good news: because each trait implementation gets its own `impl` block, it's -clear which trait's `get` method you're implementing. +Good news: because each trait implementation gets its own `impl` block, it's +clear which trait's `get` method you're implementing. What about when it comes time to _call_ those methods? To disambiguate between them, we have to use Fully Qualified Syntax. @@ -38,12 +40,12 @@ impl AgeWidget for Form { } fn main() { - let form = Form{ + let form = Form { username: "rustacean".to_owned(), age: 28, }; - // If you uncomment this line, you'll get an error saying + // If you uncomment this line, you'll get an error saying // "multiple `get` found". Because, after all, there are multiple methods // named `get`. // println!("{}", form.get()); diff --git a/src/doc/rust-by-example/src/trait/impl_trait.md b/src/doc/rust-by-example/src/trait/impl_trait.md index e738be4a35..34bc06bfd0 100644 --- a/src/doc/rust-by-example/src/trait/impl_trait.md +++ b/src/doc/rust-by-example/src/trait/impl_trait.md @@ -28,7 +28,7 @@ fn parse_csv_document(src: R) -> std::io::Result` or `[u8]`, -but it's not important what type `R` is, and `R` is only used to declare the type of `src`, so the function can also be written an +but it's not important what type `R` is, and `R` is only used to declare the type of `src`, so the function can also be written as: ```rust,editable fn parse_csv_document(src: impl std::io::BufRead) -> std::io::Result>> { @@ -46,7 +46,7 @@ fn parse_csv_document(src: impl std::io::BufRead) -> std::io::Result(std::io::empty())` will not work with the second example +Note that using `impl Trait` as an argument type means that you cannot explicitly state what form of the function you use, i.e. `parse_csv_document::(std::io::empty())` will not work with the second example. ## As a return type diff --git a/src/doc/rust-by-example/src/unsafe/asm.md b/src/doc/rust-by-example/src/unsafe/asm.md index 10d4a9b278..fa95fcad40 100644 --- a/src/doc/rust-by-example/src/unsafe/asm.md +++ b/src/doc/rust-by-example/src/unsafe/asm.md @@ -132,7 +132,7 @@ To achieve this Rust provides a `lateout` specifier. This can be used on any out written only after all inputs have been consumed. There is also a `inlateout` variant of this specifier. -Here is an example where `inlateout` *cannot* be used: +Here is an example where `inlateout` *cannot* be used in `release` mode or other optimized cases: ```rust use std::arch::asm; @@ -151,8 +151,9 @@ unsafe { } assert_eq!(a, 12); ``` +The above could work well in unoptimized cases (`Debug` mode), but if you want optimized performance (`release` mode or other optimized cases), it could not work. -Here the compiler is free to allocate the same register for inputs `b` and `c` since it knows they have the same value. However it must allocate a separate register for `a` since it uses `inout` and not `inlateout`. If `inlateout` was used, then `a` and `c` could be allocated to the same register, in which case the first instruction to overwrite the value of `c` and cause the assembly code to produce the wrong result. +That is because in optimized cases, the compiler is free to allocate the same register for inputs `b` and `c` since it knows they have the same value. However it must allocate a separate register for `a` since it uses `inout` and not `inlateout`. If `inlateout` was used, then `a` and `c` could be allocated to the same register, in which case the first instruction to overwrite the value of `c` and cause the assembly code to produce the wrong result. However the following example can use `inlateout` since the output is only modified after all input registers have been read: @@ -232,25 +233,24 @@ fn main() { // three entries of four bytes each let mut name_buf = [0_u8; 12]; // String is stored as ascii in ebx, edx, ecx in order - // Because ebx is reserved, we get a scratch register and move from - // ebx into it in the asm. The asm needs to preserve the value of - // that register though, so it is pushed and popped around the main asm + // Because ebx is reserved, the asm needs to preserve the value of it. + // So we push and pop it around the main asm. // (in 64 bit mode for 64 bit processors, 32 bit processors would use ebx) unsafe { asm!( "push rbx", "cpuid", - "mov [{0}], ebx", - "mov [{0} + 4], edx", - "mov [{0} + 8], ecx", + "mov [rdi], ebx", + "mov [rdi + 4], edx", + "mov [rdi + 8], ecx", "pop rbx", // We use a pointer to an array for storing the values to simplify // the Rust code at the cost of a couple more asm instructions // This is more explicit with how the asm works however, as opposed // to explicit register outputs such as `out("ecx") val` // The *pointer itself* is only an input even though it's written behind - in(reg) name_buf.as_mut_ptr(), + in("rdi") name_buf.as_mut_ptr(), // select cpuid 0, also specify eax as clobbered inout("eax") 0 => _, // cpuid clobbers these registers too @@ -269,9 +269,11 @@ This instruction writes to `eax` with the maximum supported `cpuid` argument and Even though `eax` is never read we still need to tell the compiler that the register has been modified so that the compiler can save any values that were in these registers before the asm. This is done by declaring it as an output but with `_` instead of a variable name, which indicates that the output value is to be discarded. -This code also works around the limitation that `ebx` is a reserved register by LLVM. That means that LLVM assumes that it has full control over the register and it must be restored to its original state before exiting the asm block, so it cannot be used as an output. To work around this we save the register via `push`, read from `ebx` inside the asm block into a temporary register allocated with `out(reg)` and then restoring `ebx` to its original state via `pop`. The `push` and `pop` use the full 64-bit `rbx` version of the register to ensure that the entire register is saved. On 32 bit targets the code would instead use `ebx` in the `push`/`pop`. +This code also works around the limitation that `ebx` is a reserved register by LLVM. That means that LLVM assumes that it has full control over the register and it must be restored to its original state before exiting the asm block, so it cannot be used as an input or output **except** if the compiler uses it to fulfill a general register class (e.g. `in(reg)`). This makes `reg` operands dangerous when using reserved registers as we could unknowingly corrupt out input or output because they share the same register. -This can also be used with a general register class (e.g. `reg`) to obtain a scratch register for use inside the asm code: +To work around this we use `rdi` to store the pointer to the output array, save `ebx` via `push`, read from `ebx` inside the asm block into the array and then restoring `ebx` to its original state via `pop`. The `push` and `pop` use the full 64-bit `rbx` version of the register to ensure that the entire register is saved. On 32 bit targets the code would instead use `ebx` in the `push`/`pop`. + +This can also be used with a general register class to obtain a scratch register for use inside the asm code: ```rust use std::arch::asm; diff --git a/src/doc/rustc-dev-guide/book.toml b/src/doc/rustc-dev-guide/book.toml index 336e5a3695..c4450cf0c3 100644 --- a/src/doc/rustc-dev-guide/book.toml +++ b/src/doc/rustc-dev-guide/book.toml @@ -21,9 +21,21 @@ level = 0 [output.linkcheck] command = "ci/linkcheck.sh" follow-web-links = true -exclude = [ "crates\\.io", "gcc\\.godbolt\\.org", "youtube\\.com", "youtu\\.be", "dl\\.acm\\.org", "cs\\.bgu\\.ac\\.il", "www\\.amazon\\.com", "www\\.rustaceans\\.org", "play\\.rust-lang\\.org" ] +exclude = [ + "crates\\.io", + "gcc\\.godbolt\\.org", + "youtube\\.com", + "youtu\\.be", + "dl\\.acm\\.org", + "cs\\.bgu\\.ac\\.il", + "www\\.amazon\\.com", + "www\\.rustaceans\\.org", + "play\\.rust-lang\\.org", + "tomlee\\.co" +] cache-timeout = 86400 warning-policy = "error" [output.html.redirect] "/compiletest.html" = "tests/compiletest.html" +"/diagnostics/sessiondiagnostic.html" = "diagnostics/diagnostic-structs.html" diff --git a/src/doc/rustc-dev-guide/ci/date-check/Cargo.lock b/src/doc/rustc-dev-guide/ci/date-check/Cargo.lock index 296a132d43..00fa3def81 100644 --- a/src/doc/rustc-dev-guide/ci/date-check/Cargo.lock +++ b/src/doc/rustc-dev-guide/ci/date-check/Cargo.lock @@ -1,10 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] @@ -43,12 +45,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.82" @@ -57,9 +53,9 @@ checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" [[package]] name = "memchr" -version = "2.3.4" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "num-integer" @@ -82,30 +78,20 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.3" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.22" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" - -[[package]] -name = "thread_local" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447" -dependencies = [ - "lazy_static", -] +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "time" diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs index 7177a28689..4203fe96a0 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-example.rs @@ -1,9 +1,9 @@ #![feature(rustc_private)] // NOTE: For the example to compile, you will need to first run the following: -// rustup component add rustc-dev +// rustup component add rustc-dev llvm-tools-preview -// version: 1.61.0-nightly (68369a041 2022-02-22) +// version: 1.62.0-nightly (7c4b47696 2022-04-30) extern crate rustc_error_codes; extern crate rustc_errors; @@ -13,13 +13,12 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; +use std::{path, process, str}; + use rustc_errors::registry; use rustc_hash::{FxHashMap, FxHashSet}; use rustc_session::config::{self, CheckCfg}; use rustc_span::source_map; -use std::path; -use std::process; -use std::str; fn main() { let out = process::Command::new("rustc") @@ -38,9 +37,14 @@ fn main() { crate_cfg: FxHashSet::default(), // FxHashSet<(String, Option)> crate_check_cfg: CheckCfg::default(), // CheckCfg input: config::Input::Str { - name: source_map::FileName::Custom("main.rs".to_string()), - input: "static HELLO: &str = \"Hello, world!\"; fn main() { println!(\"{}\", HELLO); }" - .to_string(), + name: source_map::FileName::Custom("main.rs".into()), + input: r#" +static HELLO: &str = "Hello, world!"; +fn main() { + println!("{HELLO}"); +} +"# + .into(), }, input_path: None, // Option output_dir: None, // Option @@ -69,15 +73,17 @@ fn main() { compiler.enter(|queries| { // Parse the program and print the syntax tree. let parse = queries.parse().unwrap().take(); - println!("{:#?}", parse); + println!("{parse:?}"); // Analyze the program and inspect the types of definitions. queries.global_ctxt().unwrap().take().enter(|tcx| { - for item in tcx.hir().items() { + for id in tcx.hir().items() { + let hir = tcx.hir(); + let item = hir.item(id); match item.kind { rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn(_, _, _) => { let name = item.ident; - let ty = tcx.type_of(tcx.hir().local_def_id(item.hir_id())); - println!("{:?}:\t{:?}", name, ty) + let ty = tcx.type_of(hir.local_def_id(item.hir_id())); + println!("{name:?}:\t{ty:?}") } _ => (), } diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs index c25695dd02..1d3a4034e4 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-getting-diagnostics.rs @@ -1,9 +1,9 @@ #![feature(rustc_private)] // NOTE: For the example to compile, you will need to first run the following: -// rustup component add rustc-dev +// rustup component add rustc-dev llvm-tools-preview -// version: 1.61.0-nightly (68369a041 2022-02-22) +// version: 1.62.0-nightly (7c4b47696 2022-04-30) extern crate rustc_error_codes; extern crate rustc_errors; @@ -57,8 +57,13 @@ fn main() { }, // This program contains a type error. input: config::Input::Str { - name: source_map::FileName::Custom("main.rs".to_string()), - input: "fn main() { let x: &str = 1; }".to_string(), + name: source_map::FileName::Custom("main.rs".into()), + input: " +fn main() { + let x: &str = 1; +} +" + .into(), }, // Redirect the diagnostic output of the compiler to a buffer. diagnostic_output: rustc_session::DiagnosticOutput::Raw(Box::from(DiagnosticSink( @@ -87,5 +92,5 @@ fn main() { }); // Read buffered diagnostics. let diagnostics = String::from_utf8(buffer.lock().unwrap().clone()).unwrap(); - println!("{}", diagnostics); + println!("{diagnostics}"); } diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs index c942ac3244..231994a97d 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs @@ -1,9 +1,9 @@ #![feature(rustc_private)] // NOTE: For the example to compile, you will need to first run the following: -// rustup component add rustc-dev llvm-tools-preview +// rustup component add rustc-dev llvm-tools-preview -// version: 1.61.0-nightly (68369a041 2022-02-22) +// version: 1.62.0-nightly (7c4b47696 2022-04-30) extern crate rustc_ast_pretty; extern crate rustc_error_codes; @@ -14,13 +14,12 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; +use std::{path, process, str}; + use rustc_ast_pretty::pprust::item_to_string; use rustc_errors::registry; use rustc_session::config::{self, CheckCfg}; use rustc_span::source_map; -use std::path; -use std::process; -use std::str; fn main() { let out = process::Command::new("rustc") @@ -36,8 +35,13 @@ fn main() { }, input: config::Input::Str { name: source_map::FileName::Custom("main.rs".to_string()), - input: "fn main() { let message = \"Hello, world!\"; println!(\"{}\", message); }" - .to_string(), + input: r#" +fn main() { + let message = "Hello, World!"; + println!("{message}"); +} +"# + .to_string(), }, diagnostic_output: rustc_session::DiagnosticOutput::Default, crate_cfg: rustc_hash::FxHashSet::default(), @@ -66,7 +70,8 @@ fn main() { // Every compilation contains a single crate. let hir_krate = tcx.hir(); // Iterate over the top-level items in the crate, looking for the main function. - for item in hir_krate.items() { + for id in hir_krate.items() { + let item = hir_krate.item(id); // Use pattern-matching to find a specific node inside the main function. if let rustc_hir::ItemKind::Fn(_, _, body_id) = item.kind { let expr = &tcx.hir().body(body_id).value; @@ -76,7 +81,7 @@ fn main() { let hir_id = expr.hir_id; // hir_id identifies the string "Hello, world!" let def_id = tcx.hir().local_def_id(item.hir_id()); // def_id identifies the main function let ty = tcx.typeck(def_id).node_type(hir_id); - println!("{:?}: {:?}", expr, ty); // prints expr(HirId { owner: DefIndex(3), local_id: 4 }: "Hello, world!"): &'static str + println!("{expr:#?}: {ty:?}"); } } } diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index e74ef5e4e9..e25eb284ea 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -76,8 +76,8 @@ - [Prologue](./part-3-intro.md) - [Command-line arguments](./cli.md) - [The Rustc Driver and Interface](./rustc-driver.md) - - [Ex: Type checking through `rustc_interface`](./rustc-driver-interacting-with-the-ast.md) - - [Ex: Getting diagnostics through `rustc_interface`](./rustc-driver-getting-diagnostics.md) + - [Example: Type checking](./rustc-driver-interacting-with-the-ast.md) + - [Example: Getting diagnostics](./rustc-driver-getting-diagnostics.md) - [Syntax and the AST](./syntax-intro.md) - [Lexing and Parsing](./the-parser.md) - [Macro expansion](./macro-expansion.md) @@ -138,10 +138,11 @@ - [Two-phase-borrows](./borrow_check/two_phase_borrows.md) - [Parameter Environments](./param_env.md) - [Errors and Lints](diagnostics.md) - - [Creating Errors With SessionDiagnostic](./diagnostics/sessiondiagnostic.md) + - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md) + - [Translation](./diagnostics/translation.md) - [`LintStore`](./diagnostics/lintstore.md) - - [Diagnostic Codes](./diagnostics/diagnostic-codes.md) - - [Diagnostic Items](./diagnostics/diagnostic-items.md) + - [Diagnostic codes](./diagnostics/diagnostic-codes.md) + - [Diagnostic items](./diagnostics/diagnostic-items.md) - [`ErrorGuaranteed`](./diagnostics/error-guaranteed.md) # MIR to Binaries diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md index cfb32bf07f..330c079b96 100644 --- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md +++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference.md @@ -78,13 +78,12 @@ The value of a region can be thought of as a **set**. This set contains all points in the MIR where the region is valid along with any regions that are outlived by this region (e.g. if `'a: 'b`, then `end('b)` is in the set for `'a`); we call the domain of this set a `RegionElement`. In the code, the value -for all regions is maintained in [the -`rustc_mir::borrow_check::nll::region_infer` module][ri]. For each region we -maintain a set storing what elements are present in its value (to make this +for all regions is maintained in [the `rustc_borrowck::region_infer` module][ri]. +For each region we maintain a set storing what elements are present in its value (to make this efficient, we give each kind of element an index, the `RegionElementIndex`, and use sparse bitsets). -[ri]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_mir/src/borrow_check/region_infer/ +[ri]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_borrowck/src/region_infer The kinds of region elements are as follows: diff --git a/src/doc/rustc-dev-guide/src/borrow_check/type_check.md b/src/doc/rustc-dev-guide/src/borrow_check/type_check.md index 1485f2ae87..69456d870e 100644 --- a/src/doc/rustc-dev-guide/src/borrow_check/type_check.md +++ b/src/doc/rustc-dev-guide/src/borrow_check/type_check.md @@ -8,3 +8,57 @@ this type-check, we also uncover the region constraints that apply to the program. TODO -- elaborate further? Maybe? :) + +## User types + +At the start of MIR type-check, we replace all regions in the body with new unconstrained regions. +However, this would cause us to accept the following program: +```rust +fn foo<'a>(x: &'a u32) { + let y: &'static u32 = x; +} +``` +By erasing the lifetimes in the type of `y` we no longer know that it is supposed to be `'static`, +ignoring the intentions of the user. + +To deal with this we remember all places where the user explicitly mentioned a type during +HIR type-check as [`CanonicalUserTypeAnnotations`][annot]. + +There are two different annotations we care about: +- explicit type ascriptions, e.g. `let y: &'static u32` results in `UserType::Ty(&'static u32)`. +- explicit generic arguments, e.g. `x.foo<&'a u32, Vec>` +results in `UserType::TypeOf(foo_def_id, [&'a u32, Vec])`. + +As we do not want the region inference from the HIR type-check to influence MIR typeck, +we store the user type right after lowering it from the HIR. +This means that it may still contain inference variables, +which is why we are using **canonical** user type annotations. +We replace all inference variables with existential bound variables instead. +Something like `let x: Vec<_>` would therefore result in `exists UserType::Ty(Vec)`. + +A pattern like `let Foo(x): Foo<&'a u32>` has a user type `Foo<&'a u32>` but +the actual type of `x` should only be `&'a u32`. For this, we use a [`UserTypeProjection`][proj]. + +In the MIR, we deal with user types in two slightly different ways. + +Given a MIR local corresponding to a variable in a pattern which has an explicit type annotation, +we require the type of that local to be equal to the type of the [`UserTypeProjection`][proj]. +This is directly stored in the [`LocalDecl`][decl]. + +We also constrain the type of scrutinee expressions, e.g. the type of `x` in `let _: &'a u32 = x;`. +Here `T_x` only has to be a subtype of the user type, so we instead use +[`StatementKind::AscribeUserType`][stmt] for that. + +Note that we do not directly use the user type as the MIR typechecker +doesn't really deal with type and const inference variables. We instead store the final +[`inferred_type`][inf] from the HIR type-checker. During MIR typeck, we then replace its regions +with new nll inference vars and relate it with the actual `UserType` to get the correct region +constraints again. + +After the MIR type-check, all user type annotations get discarded, as they aren't needed anymore. + +[annot]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.CanonicalUserTypeAnnotation.html +[proj]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.UserTypeProjection.html +[decl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.LocalDecl.html +[stmt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.StatementKind.html#variant.AscribeUserType +[inf]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.CanonicalUserTypeAnnotation.html#structfield.inferred_ty \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index dd997c8141..9ef43e341c 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -233,6 +233,12 @@ The rustup toolchain points to the specified toolchain compiled in your `build` so the rustup toolchain will be updated whenever `x.py build` or `x.py test` are run for that toolchain/stage. +**Note:** the toolchain we've built does not include `cargo`. In this case, `rustup` will +fall back to using `cargo` from the installed `nightly`, `beta`, or `stable` toolchain +(in that order). If you need to use unstable `cargo` flags, be sure to run +`rustup install nightly` if you haven't already. See the +[rustup documentation on custom toolchains](https://rust-lang.github.io/rustup/concepts/toolchains.html#custom-toolchains). + ## Other `x.py` commands Here are a few other useful `x.py` commands. We'll cover some of them in detail diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md index b5fc2cb0ad..f216ed0b76 100644 --- a/src/doc/rustc-dev-guide/src/building/new-target.md +++ b/src/doc/rustc-dev-guide/src/building/new-target.md @@ -104,6 +104,12 @@ index be15e50e2bc..4fb1248ba99 100644 After this, run `cargo update -p libc` to update the lockfiles. +Beware that if you patch to a local `path` dependency, this will enable +warnings for that dependency. Some dependencies are not warning-free, and due +to the `deny-warnings` setting in `config.toml`, the build may suddenly start +to fail. To work around the warnings, you may want to disable `deny-warnings` +in the config, or modify the dependency to remove the warnings. + [`libc`]: https://crates.io/crates/libc [`cc`]: https://crates.io/crates/cc [patch]: https://doc.rust-lang.org/stable/cargo/reference/overriding-dependencies.html#the-patch-section diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index a6ff65db3c..6c0b7135e9 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -3,16 +3,16 @@ The full bootstrapping process takes quite a while. Here are some suggestions to make your life easier. -## Installing a pre-commit hook +## Installing a pre-push hook CI will automatically fail your build if it doesn't pass `tidy`, our internal tool for ensuring code quality. If you'd like, you can install a [Git hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) -that will automatically run `./x.py test tidy --bless` on each commit, to ensure +that will automatically run `./x.py test tidy --bless` on each push, to ensure your code is up to par. If you decide later that this behavior is -undesirable, you can delete the `pre-commit` file in `.git/hooks`. +undesirable, you can delete the `pre-push` file in `.git/hooks`. -A prebuilt git hook lives at [`src/etc/pre-commit.sh`](https://github.com/rust-lang/rust/blob/master/src/etc/pre-commit.sh) which can be copied into your `.git/hooks` folder as `pre-commit` (without the `.sh` extension!). +A prebuilt git hook lives at [`src/etc/pre-push.sh`](https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh) which can be copied into your `.git/hooks` folder as `pre-push` (without the `.sh` extension!). You can also install the hook as a step of running `./x.py setup`! @@ -37,9 +37,16 @@ you can write: Now that we have [seen what the compiler does](./overview.md), let's take a -look at the structure of the contents of the rust-lang/rust repo. +look at the structure of the [`rust-lang/rust`] repository, where the rustc +source code lives. + +[`rust-lang/rust`]: https://github.com/rust-lang/rust + +> You may find it helpful to read the ["Overview of the compiler"](./overview.md) +> chapter, which introduces how the compiler works, before this one. ## Workspace structure @@ -16,29 +22,17 @@ The repository consists of three main directories: - `compiler/` contains the source code for `rustc`. It consists of many crates that together make up the compiler. - + - `library/` contains the standard libraries (`core`, `alloc`, `std`, `proc_macro`, `test`), as well as the Rust runtime (`backtrace`, `rtstartup`, `lang_start`). - + - `src/` contains the source code for rustdoc, clippy, cargo, the build system, - language docs, etc. - -## Standard library - -The standard library crates are all in `library/`. They have intuitive names -like `std`, `core`, `alloc`, etc. There is also `proc_macro`, `test`, and -other runtime libraries. - -This code is fairly similar to most other Rust crates except that it must be -built in a special way because it can use unstable features. + compiler tests, language docs, etc. ## Compiler -> You may find it helpful to read [The Overview Chapter](./overview.md) first, -> which gives an overview of how the compiler works. The crates mentioned in -> this section implement the compiler, and are underneath `compiler/` - +The compiler is implemented in the various `compiler/` crates. The `compiler/` crates all have names starting with `rustc_*`. These are a collection of around 50 interdependent crates ranging in size from tiny to huge. There is also the `rustc` crate which is the actual binary (i.e. the @@ -87,7 +81,7 @@ explanation of these crates here. ### Big picture -The dependency structure is influenced strongly by two main factors: +The dependency structure is influenced by two main factors: 1. Organization. The compiler is a _huge_ codebase; it would be an impossibly large crate. In part, the dependency structure reflects the code structure @@ -101,12 +95,11 @@ At the very bottom of the dependency tree are a handful of crates that are used by the whole compiler (e.g. [`rustc_span`]). The very early parts of the compilation process (e.g. parsing and the AST) depend on only these. -Pretty soon after the AST is constructed, the compiler's [query system][query] -gets set up. The query system is set up in a clever way using function +After the AST is constructed and other early analysis is done, the compiler's [query system][query] +gets set up. The query system is set up in a clever way using function pointers. This allows us to break dependencies between crates, allowing more parallel compilation. - -However, since the query system is defined in [`rustc_middle`], nearly all +The query system is defined in [`rustc_middle`], so nearly all subsequent parts of the compiler depend on this crate. It is a really large crate, leading to long compile times. Some efforts have been made to move stuff out of it with limited success. Another unfortunate side effect is that sometimes @@ -116,7 +109,7 @@ linting functionality is scattered across earlier parts of the crate, [`rustc_lint`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/index.html -More generally, in an ideal world, it seems like there would be fewer, more +Ideally there would be fewer, more cohesive crates, with incremental and parallel compilation making sure compile times stay reasonable. However, our incremental and parallel compilation haven't gotten good enough for that yet, so breaking things into separate crates has @@ -180,6 +173,15 @@ from `src/tools/`, such as [`tidy`] or [`compiletest`]. [bootstch]: ./building/bootstrapping.md +## Standard library + +The standard library crates are all in `library/`. They have intuitive names +like `std`, `core`, `alloc`, etc. There is also `proc_macro`, `test`, and +other runtime libraries. + +This code is fairly similar to most other Rust crates except that it must be +built in a special way because it can use unstable features. + ## Other There are a lot of other things in the `rust-lang/rust` repo that are related diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 3fe0948cc0..48d8b2d157 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -67,8 +67,8 @@ where contributors push changes to their personal fork and create pull requests bring those changes into the source repository. We have more info about how to use git when contributing to Rust under [the git section](./git.md). -[about-pull-requests]: https://help.github.com/articles/about-pull-requests/ -[development-models]: https://help.github.com/articles/about-collaborative-development-models/ +[about-pull-requests]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests +[development-models]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/getting-started/about-collaborative-development-models#fork-and-pull-model ### r? @@ -177,7 +177,7 @@ particularly during rebasing, citing the issue number in the commit can "spam" the issue in question. [labeling]: ./rustbot.md#issue-relabeling -[closing-keywords]: https://help.github.com/en/articles/closing-issues-using-keywords +[closing-keywords]: https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue ### External Dependencies (subtree) diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index b675204285..0f0bfd895a 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -139,10 +139,11 @@ use an error-level lint instead of a fixed error. flag. That said, don't make it so terse that it's hard to understand. - The word "illegal" is illegal. Prefer "invalid" or a more specific word instead. -- Errors should document the span of code where they occur – the - [`rustc_errors::diagnostic_builder::DiagnosticBuilder`][diagbuild] `span_*` - methods allow to easily do this. Also `note` other spans that have - contributed to the error if the span isn't too large. +- Errors should document the span of code where they occur (use + [`rustc_errors::diagnostic_builder::DiagnosticBuilder`][diagbuild]'s + `span_*` methods or a diagnostic struct's `#[primary_span]` to easily do + this). Also `note` other spans that have contributed to the error if the span + isn't too large. - When emitting a message with span, try to reduce the span to the smallest amount possible that still signifies the issue - Try not to emit multiple error messages for the same error. This may require @@ -272,19 +273,20 @@ There are two main ways to find where a given error is emitted: - `grep` for either a sub-part of the error message/label or error code. This usually works well and is straightforward, but there are some cases where - the error emitting code is removed from the code where the error is + the code emitting the error is removed from the code where the error is constructed behind a relatively deep call-stack. Even then, it is a good way to get your bearings. -- Invoking `rustc` with the nightly-only flag `-Z treat-err-as-bug=1`, which +- Invoking `rustc` with the nightly-only flag `-Z treat-err-as-bug=1` will treat the first error being emitted as an Internal Compiler Error, which - allows you to use the environment variable `RUST_BACKTRACE=full` to get a + allows you to get a stack trace at the point the error has been emitted. Change the `1` to - something else if you whish to trigger on a later error. Some limitations - with this approach is that some calls get elided from the stack trace because - they get inlined in the compiled `rustc`, and the same problem we faced with - the prior approach, where the _construction_ of the error is far away from - where it is _emitted_. In some cases we buffer multiple errors in order to - emit them in order. + something else if you wish to trigger on a later error. + + There are limitations with this approach: + - Some calls get elided from the stack trace because they get inlined in the compiled `rustc`. + - The _construction_ of the error is far away from where it is _emitted_, + a problem similar to the one we faced with the `grep` approach. + In some cases, we buffer multiple errors in order to emit them in order. The regular development practices apply: judicious use of `debug!()` statements and use of a debugger to trigger break points in order to figure out in what @@ -312,6 +314,15 @@ reporting errors. [errors]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html +Diagnostics can be implemented as types which implement the `SessionDiagnostic` +trait. This is preferred for new diagnostics as it enforces a separation +between diagnostic emitting logic and the main code paths. For less-complex +diagnostics, the `SessionDiagnostic` trait can be derived -- see [Diagnostic +structs][diagnostic-structs]. Within the trait implementation, the APIs +described below can be used as normal. + +[diagnostic-structs]: ./diagnostics/diagnostic-structs.md + [`Session`][session] and [`ParseSess`][parsesses] have methods (or fields with methods) that allow reporting errors. These methods usually have names like `span_err` or `struct_span_err` or `span_warn`, etc... @@ -327,6 +338,12 @@ directly and ones that allow finer control over what to emit. For example, [`struct_span_err`][strspanerr] instead returns a [`DiagnosticBuilder`][diagbuild]. +Most of these methods will accept strings, but it is recommended that typed +identifiers for translatable diagnostics be used for new diagnostics (see +[Translation][translation]). + +[translation]: ./diagnostics/translation.md + `DiagnosticBuilder` allows you to add related notes and suggestions to an error before emitting it by calling the [`emit`][emit] method. (Failing to either emit or [cancel][cancel] a `DiagnosticBuilder` will result in an ICE.) See the @@ -340,30 +357,30 @@ emit or [cancel][cancel] a `DiagnosticBuilder` will result in an ICE.) See the ```rust,ignore // Get a DiagnosticBuilder. This does _not_ emit an error yet. -let mut err = sess.struct_span_err(sp, "oh no! this is an error!"); +let mut err = sess.struct_span_err(sp, fluent::example::example_error); // In some cases, you might need to check if `sp` is generated by a macro to // avoid printing weird errors about macro-generated code. if let Ok(snippet) = sess.source_map().span_to_snippet(sp) { // Use the snippet to generate a suggested fix - err.span_suggestion(suggestion_sp, "try using a qux here", format!("qux {}", snippet)); + err.span_suggestion(suggestion_sp, fluent::example::try_qux_suggestion, format!("qux {}", snippet)); } else { // If we weren't able to generate a snippet, then emit a "help" message // instead of a concrete "suggestion". In practice this is unlikely to be // reached. - err.span_help(suggestion_sp, "you could use a qux here instead"); + err.span_help(suggestion_sp, fluent::example::qux_suggestion); } // emit the error err.emit(); ``` -Alternatively, for less-complex diagnostics, the `SessionDiagnostic` derive -macro can be used -- see [Creating Errors With SessionDiagnostic][sessiondiagnostic]. - -[sessiondiagnostic]: ./diagnostics/sessiondiagnostic.md - +```fluent +example-example-error = oh no! this is an error! + .try-qux-suggestion = try using a qux here + .qux-suggestion = you could use a qux here instead +``` ## Suggestions @@ -405,17 +422,17 @@ apply them) For example, to make our `qux` suggestion machine-applicable, we would do: ```rust,ignore -let mut err = sess.struct_span_err(sp, "oh no! this is an error!"); +let mut err = sess.struct_span_err(sp, fluent::example::message); if let Ok(snippet) = sess.source_map().span_to_snippet(sp) { err.span_suggestion( suggestion_sp, - "try using a qux here", + fluent::example::try_qux_suggestion, format!("qux {}", snippet), Applicability::MachineApplicable, ); } else { - err.span_help(suggestion_sp, "you could use a qux here instead"); + err.span_help(suggestion_sp, fluent::example::qux_suggestion); } err.emit(); @@ -504,9 +521,9 @@ much faster to work on. Every lint is implemented via a `struct` that implements the `LintPass` `trait` (you can also implement one of the more specific lint pass traits, either -`EarlyLintPass` or `LateLintPass` depending on when is best for your lint to run). -The trait implementation allows you to check certain syntactic constructs -as the linter walks the AST. You can then choose to emit lints in a +`EarlyLintPass` or `LateLintPass` depending on when is best for your lint to run). +The trait implementation allows you to check certain syntactic constructs +as the linter walks the AST. You can then choose to emit lints in a very similar way to compile errors. You also declare the metadata of a particular lint via the `declare_lint!` @@ -557,13 +574,12 @@ impl EarlyLintPass for WhileTrue { if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind { if let ast::LitKind::Bool(true) = lit.kind { if !lit.span.from_expansion() { - let msg = "denote infinite loops with `loop { ... }`"; let condition_span = cx.sess.source_map().guess_head_span(e.span); cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| { - lint.build(msg) + lint.build(fluent::example::use_loop) .span_suggestion_short( condition_span, - "use `loop`", + fluent::example::suggestion, "loop".to_owned(), Applicability::MachineApplicable, ) @@ -577,6 +593,11 @@ impl EarlyLintPass for WhileTrue { } ``` +```fluent +example-use-loop = denote infinite loops with `loop {"{"} ... {"}"}` + .suggestion = use `loop` +``` + ### Edition-gated lints Sometimes we want to change the behavior of a lint in a new edition. To do this, @@ -613,15 +634,15 @@ declare_lint! { The use of the term `future-incompatible` within the compiler has a slightly broader meaning than what rustc exposes to users of the compiler. -Inside rustc, future-incompatible lints are for signalling to the user that code they have +Inside rustc, future-incompatible lints are for signalling to the user that code they have written may not compile in the future. In general, future-incompatible code exists for two reasons: -* the user has written unsound code that the compiler mistakenly accepted. While -it is within Rust's backwards compatibility guarantees to fix the soundness hole -(breaking the user's code), the lint is there to warn the user that this will happen -in some upcoming version of rustc *regardless of which edition the code uses*. This is the +* the user has written unsound code that the compiler mistakenly accepted. While +it is within Rust's backwards compatibility guarantees to fix the soundness hole +(breaking the user's code), the lint is there to warn the user that this will happen +in some upcoming version of rustc *regardless of which edition the code uses*. This is the meaning that rustc exclusively exposes to users as "future incompatible". -* the user has written code that will either no longer compiler *or* will change +* the user has written code that will either no longer compiler *or* will change meaning in an upcoming *edition*. These are often called "edition lints" and can be typically seen in the various "edition compatibility" lint groups (e.g., `rust_2021_compatibility`) that are used to lint against code that will break if the user updates the crate's edition. @@ -644,11 +665,11 @@ declare_lint! { Notice the `reason` field which describes why the future incompatible change is happening. This will change the diagnostic message the user receives as well as determine which lint groups the lint is added to. In the example above, the lint is an "edition lint" -(since it's "reason" is `EditionError`) signifying to the user that the use of anonymous +(since it's "reason" is `EditionError`) signifying to the user that the use of anonymous parameters will no longer compile in Rust 2018 and beyond. -Inside [LintStore::register_lints][fi-lint-groupings], lints with `future_incompatible` -fields get placed into either edition-based lint groups (if their `reason` is tied to +Inside [LintStore::register_lints][fi-lint-groupings], lints with `future_incompatible` +fields get placed into either edition-based lint groups (if their `reason` is tied to an edition) or into the `future_incompatibility` lint group. [fi-lint-groupings]: https://github.com/rust-lang/rust/blob/51fd129ac12d5bfeca7d216c47b0e337bf13e0c2/compiler/rustc_lint/src/context.rs#L212-L237 @@ -659,7 +680,7 @@ to support this. ### Renaming or removing a lint -If it is determined that a lint is either improperly named or no longer needed, +If it is determined that a lint is either improperly named or no longer needed, the lint must be registered for renaming or removal, which will trigger a warning if a user tries to use the old lint name. To declare a rename/remove, add a line with [`store.register_renamed`] or [`store.register_removed`] to the code of the @@ -695,11 +716,11 @@ This defines the `nonstandard_style` group which turns on the listed lints. A user can turn on these lints with a `!#[warn(nonstandard_style)]` attribute in the source code, or by passing `-W nonstandard-style` on the command line. -Some lint groups are created automatically in `LintStore::register_lints`. For instance, -any lint declared with `FutureIncompatibleInfo` where the reason is -`FutureIncompatibilityReason::FutureReleaseError` (the default when +Some lint groups are created automatically in `LintStore::register_lints`. For instance, +any lint declared with `FutureIncompatibleInfo` where the reason is +`FutureIncompatibilityReason::FutureReleaseError` (the default when `@future_incompatible` is used in `declare_lint!`), will be added to -the `future_incompatible` lint group. Editions also have their own lint groups +the `future_incompatible` lint group. Editions also have their own lint groups (e.g., `rust_2021_compatibility`) automatically generated for any lints signaling future-incompatible code that will break in the specified edition. @@ -868,7 +889,7 @@ For example, the `Iterator` trait can be annotated in the following way: #[rustc_on_unimplemented( on( _Self="&str", - note="call `.chars()` or `.as_bytes()` on `{Self}" + note="call `.chars()` or `.as_bytes()` on `{Self}`" ), message="`{Self}` is not an iterator", label="`{Self}` is not an iterator", diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-codes.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-codes.md index 092c8a2f8d..3618b43cde 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-codes.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-codes.md @@ -1,4 +1,4 @@ -# Diagnostic Codes +# Diagnostic codes We generally try to assign each error message a unique code like `E0123`. These codes are defined in the compiler in the `diagnostics.rs` files found in each crate, which basically consist of macros. The codes come in two varieties: those @@ -60,7 +60,7 @@ To actually issue the error, you can use the `struct_span_err!` macro: struct_span_err!(self.tcx.sess, // some path to the session here span, // whatever span in the source you want E0592, // your new error code - &format!("text of the error")) + fluent::example::an_error_message) .emit() // actually issue the error ``` @@ -69,8 +69,8 @@ call `.emit()`: ```rust struct_span_err!(...) - .span_label(another_span, "something to label in the source") - .span_note(another_span, "some separate note, probably avoid these") + .span_label(another_span, fluent::example::example_label) + .span_note(another_span, fluent::example::separate_note) .emit_() ``` diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md index 61e3c3aec4..0031ba2840 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md @@ -1,19 +1,17 @@ # Diagnostic Items - -## Background - -While writing lints it's common to check for specific types, traits and functions. This raises -the question on how to check for these. Types can be checked by their complete type path. -However, this requires hard coding paths and can lead to misclassifications in some edge cases. -To counteract this, rustc has introduced diagnostic items that are used to identify types via +While writing lints it's common to check for specific types, traits and +functions. This raises the question on how to check for these. Types can be +checked by their complete type path. However, this requires hard coding paths +and can lead to misclassifications in some edge cases. To counteract this, +rustc has introduced diagnostic items that are used to identify types via [`Symbol`]s. -## How To Find Diagnostic Items - -Diagnostic items are added to items inside `rustc`/`std`/`core` with the `rustc_diagnostic_item` -attribute. The item for a specific type can be found by opening the source code in the -documentation and looking for this attribute. Note that it's often added with the `cfg_attr` -attribute to avoid compilation errors during tests. A definition often looks like this: +## Finding diagnostic items +Diagnostic items are added to items inside `rustc`/`std`/`core` with the +`rustc_diagnostic_item` attribute. The item for a specific type can be found by +opening the source code in the documentation and looking for this attribute. +Note that it's often added with the `cfg_attr` attribute to avoid compilation +errors during tests. A definition often looks like this: ```rs // This is the diagnostic item for this type vvvvvvv @@ -21,19 +19,20 @@ attribute to avoid compilation errors during tests. A definition often looks lik struct Penguin; ``` -Diagnostic items are usually only added to traits, types and standalone functions. If the goal -is to check for an associated type or method, please use the diagnostic item of the item and -reference [*How To Use Diagnostic Items*](#how-to-use-diagnostic-items). - -## How To Add Diagnostic Items +Diagnostic items are usually only added to traits, types and standalone +functions. If the goal is to check for an associated type or method, please use +the diagnostic item of the item and reference [*How To Use Diagnostic +Items*](#how-to-use-diagnostic-items). +## Adding diagnostic items A new diagnostic item can be added with these two steps: -1. Find the target item inside the Rust repo. Now add the diagnostic item as a string via the - `rustc_diagnostic_item` attribute. This can sometimes cause compilation errors while running - tests. These errors can be avoided by using the `cfg_attr` attribute with the `not(test)` - condition (it's fine adding then for all `rustc_diagnostic_item` attributes as a preventive - manner). At the end, it should look like this: +1. Find the target item inside the Rust repo. Now add the diagnostic item as a + string via the `rustc_diagnostic_item` attribute. This can sometimes cause + compilation errors while running tests. These errors can be avoided by using + the `cfg_attr` attribute with the `not(test)` condition (it's fine adding + then for all `rustc_diagnostic_item` attributes as a preventive manner). At + the end, it should look like this: ```rs // This will be the new diagnostic item vvv @@ -44,41 +43,45 @@ A new diagnostic item can be added with these two steps: For the naming conventions of diagnostic items, please refer to [*Naming Conventions*](#naming-conventions). -2. As of February 2022, diagnostic items in code are accessed via symbols in - [`rustc_span::symbol::sym`]. To add your newly created diagnostic item simply open the - module file and add the name (In this case `Cat`) at the correct point in the list. - -Now you can create a pull request with your changes. :tada: (Note that when using diagnostic -items in other projects like Clippy, it might take some time until the repos get synchronized.) - -## Naming Conventions - -Diagnostic items don't have a set in stone naming convention yet. These are some guidelines that -should be used for the future, but might differ from existing names: - -* Types, traits and enums are named using UpperCamelCase (Examples: `Iterator`, `HashMap`, ...) -* For type names that are used multiple times like `Writer` it's good to choose a more precise - name, maybe by adding the module to it. (Example: `IoWriter`) -* Associated items should not get their own diagnostic items, but instead be accessed indirectly - by the diagnostic item of the type they're originating from. -* Freestanding functions like `std::mem::swap()` should be named using `snake_case` with one - important (export) module as a prefix (Example: `mem_swap`, `cmp_max`) -* Modules should usually not have a diagnostic item attached to them. Diagnostic items were - added to avoid the usage of paths, using them on modules would therefore most likely to be - counterproductive. - -## How To Use Diagnostic Items - +2. As of February 2022, diagnostic items in code are + accessed via symbols in [`rustc_span::symbol::sym`]. To add your newly + created diagnostic item simply open the module file and add the name (In + this case `Cat`) at the correct point in the list. + +Now you can create a pull request with your changes. :tada: (Note that when +using diagnostic items in other projects like Clippy, it might take some time +until the repos get synchronized.) + +## Naming conventions +Diagnostic items don't have a set in stone naming convention yet. These are +some guidelines that should be used for the future, but might differ from +existing names: + +* Types, traits and enums are named using UpperCamelCase (Examples: `Iterator`, +* `HashMap`, ...) +* For type names that are used multiple times like `Writer` it's good to choose + a more precise name, maybe by adding the module to it. (Example: `IoWriter`) +* Associated items should not get their own diagnostic items, but instead be + accessed indirectly by the diagnostic item of the type they're originating + from. +* Freestanding functions like `std::mem::swap()` should be named using + `snake_case` with one important (export) module as a prefix (Example: + `mem_swap`, `cmp_max`) +* Modules should usually not have a diagnostic item attached to them. + Diagnostic items were added to avoid the usage of paths, using them on + modules would therefore most likely to be counterproductive. + +## Using diagnostic items In rustc, diagnostic items are looked up via [`Symbol`]s from inside the -[`rustc_span::symbol::sym`] module. These can then be mapped to [`DefId`]s using -[`TyCtxt::get_diagnostic_item()`] or checked if they match a [`DefId`] using -[`TyCtxt::is_diagnostic_item()`]. When mapping from a diagnostic item to a [`DefId`] the method -will return a `Option`. This can be `None` if either the symbol isn't a diagnostic item -or the type is not registered, for instance when compiling with `#[no_std]`. All following -examples are based on [`DefId`]s and their usage. - -### Check For A Type - +[`rustc_span::symbol::sym`] module. These can then be mapped to [`DefId`]s +using [`TyCtxt::get_diagnostic_item()`] or checked if they match a [`DefId`] +using [`TyCtxt::is_diagnostic_item()`]. When mapping from a diagnostic item to +a [`DefId`], the method will return a `Option`. This can be `None` if +either the symbol isn't a diagnostic item or the type is not registered, for +instance when compiling with `#[no_std]`. All following examples are based on +[`DefId`]s and their usage. + +### Example: Checking for a type ```rust use rustc_span::symbol::sym; @@ -92,8 +95,7 @@ fn example_1(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { } ``` -### Check For A Trait Implementation - +### Example: Checking for a trait implementation ```rust /// This example checks if a given [`DefId`] from a method is part of a trait /// implementation defined by a diagnostic item. @@ -110,24 +112,23 @@ fn is_diag_trait_item( ``` ### Associated Types - -Associated types of diagnostic items can be accessed indirectly by first getting the [`DefId`] -of the trait and then calling [`TyCtxt::associated_items()`]. This returns an [`AssocItems`] -object which can be used for further checks. Checkout +Associated types of diagnostic items can be accessed indirectly by first +getting the [`DefId`] of the trait and then calling +[`TyCtxt::associated_items()`]. This returns an [`AssocItems`] object which can +be used for further checks. Checkout [`clippy_utils::ty::get_iterator_item_ty()`] for an example usage of this. -### Usage In Clippy - -Clippy tries to use diagnostic items where possible and has developed some wrapper and utility -functions. Please also refer to its documentation when using diagnostic items in Clippy. (See -[*Common tools for writing lints*][clippy-Common-tools-for-writing-lints].) - -## Related Issues +### Usage in Clippy +Clippy tries to use diagnostic items where possible and has developed some +wrapper and utility functions. Please also refer to its documentation when +using diagnostic items in Clippy. (See [*Common tools for writing +lints*][clippy-Common-tools-for-writing-lints].) -This lists some related issues. These are probably only interesting to people who really want to -take a deep dive into the topic :) +## Related issues +This lists some related issues. These are probably only interesting to people +who really want to take a deep dive into the topic :) -* [rust#60966]: The Rust PR that introduced diagnostic items +* [rust#60966]: The Rust PR that introduced diagnostic items * [rust-clippy#5393]: Clippy's tracking issue for moving away from hard coded paths to diagnostic item diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md new file mode 100644 index 0000000000..cab9b0c2f9 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md @@ -0,0 +1,359 @@ +# Diagnostic and subdiagnostic structs +rustc has two diagnostic derives that can be used to create simple diagnostics, +which are recommended to be used when they are applicable: +`#[derive(SessionDiagnostic)]` and `#[derive(SessionSubdiagnostic)]`. + +Diagnostics created with the derive macros can be translated into different +languages and each has a slug that uniquely identifies the diagnostic. + +## `#[derive(SessionDiagnostic)]` +Instead of using the `DiagnosticBuilder` API to create and emit diagnostics, +the `SessionDiagnostic` derive can be used. `#[derive(SessionDiagnostic)]` is +only applicable for simple diagnostics that don't require much logic in +deciding whether or not to add additional subdiagnostics. + +Consider the [definition][defn] of the "field already declared" diagnostic +shown below: + +```rust,ignore +#[derive(SessionDiagnostic)] +#[error(code = "E0124", slug = "typeck-field-already-declared")] +pub struct FieldAlreadyDeclared { + pub field_name: Ident, + #[primary_span] + #[label] + pub span: Span, + #[label = "previous-decl-label"] + pub prev_span: Span, +} +``` + +`SessionDiagnostic` can only be applied to structs. Every `SessionDiagnostic` +has to have one attribute applied to the struct itself: either `#[error(..)]` +for defining errors, or `#[warning(..)]` for defining warnings. + +If an error has an error code (e.g. "E0624"), then that can be specified using +the `code` sub-attribute. Specifying a `code` isn't mandatory, but if you are +porting a diagnostic that uses `DiagnosticBuilder` to use `SessionDiagnostic` +then you should keep the code if there was one. + +Both `#[error(..)]` and `#[warning(..)]` must set a value for the `slug` +sub-attribute. `slug` uniquely identifies the diagnostic and is also how the +compiler knows what error message to emit (in the default locale of the +compiler, or in the locale requested by the user). See [translation +documentation](./translation.md) to learn more about how translatable error +messages are written. + +In our example, the Fluent message for the "field already declared" diagnostic +looks like this: + +```fluent +typeck-field-already-declared = + field `{$field_name}` is already declared + .label = field already declared + .previous-decl-label = `{$field_name}` first declared here +``` + +`typeck-field-already-declared` is the `slug` from our example and is followed +by the diagnostic message. + +Every field of the `SessionDiagnostic` which does not have an annotation is +available in Fluent messages as a variable, like `field_name` in the example +above. Fields can be annotated `#[skip_arg]` if this is undesired. + +Using the `#[primary_span]` attribute on a field (that has type `Span`) +indicates the primary span of the diagnostic which will have the main message +of the diagnostic. + +Diagnostics are more than just their primary message, they often include +labels, notes, help messages and suggestions, all of which can also be +specified on a `SessionDiagnostic`. + +`#[label]`, `#[help]` and `#[note]` can all be applied to fields which have the +type `Span`. Applying any of these attributes will create the corresponding +subdiagnostic with that `Span`. These attributes will look for their +diagnostic message in a Fluent attribute attached to the primary Fluent +message. In our example, `#[label]` will look for +`typeck-field-already-declared.label` (which has the message "field already +declared"). If there is more than one subdiagnostic of the same type, then +these attributes can also take a value that is the attribute name to look for +(e.g. `previous-decl-label` in our example). + +Other types have special behavior when used in a `SessionDiagnostic` derive: + +- Any attribute applied to an `Option` and will only emit a + subdiagnostic if the option is `Some(..)`. +- Any attribute applied to a `Vec` will be repeated for each element of the + vector. + +`#[help]` and `#[note]` can also be applied to the struct itself, in which case +they work exactly like when applied to fields except the subdiagnostic won't +have a `Span`. These attributes can also be applied to fields of type `()` for +the same effect, which when combined with the `Option` type can be used to +represent optional `#[note]`/`#[help]` subdiagnostics. + +Suggestions can be emitted using one of four field attributes: + +- `#[suggestion(message = "...", code = "...", applicability = "...")]` +- `#[suggestion_hidden(message = "...", code = "...", applicability = "...")]` +- `#[suggestion_short(message = "...", code = "...", applicability = "...")]` +- `#[suggestion_verbose(message = "...", code = "...", applicability = "...")]` + +Suggestions must be applied on either a `Span` field or a `(Span, +MachineApplicability)` field. Similarly to other field attributes, `message` +specifies the Fluent attribute with the message and defaults to `.suggestion`. +`code` specifies the code that should be suggested as a replacement and is a +format string (e.g. `{field_name}` would be replaced by the value of the +`field_name` field of the struct), not a Fluent identifier. `applicability` can +be used to specify the applicability in the attribute, it cannot be used when +the field's type contains an `Applicability`. + +In the end, the `SessionDiagnostic` derive will generate an implementation of +`SessionDiagnostic` that looks like the following: + +```rust,ignore +impl SessionDiagnostic for FieldAlreadyDeclared { + fn into_diagnostic(self, sess: &'_ rustc_session::Session) -> DiagnosticBuilder<'_> { + let mut diag = sess.struct_err_with_code( + rustc_errors::DiagnosticMessage::fluent("typeck-field-already-declared"), + rustc_errors::DiagnosticId::Error("E0124") + ); + diag.set_span(self.span); + diag.span_label( + self.span, + rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "label") + ); + diag.span_label( + self.prev_span, + rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "previous-decl-label") + ); + diag + } +} +``` + +Now that we've defined our diagnostic, how do we [use it][use]? It's quite +straightforward, just create an instance of the struct and pass it to +`emit_err` (or `emit_warning`): + +```rust,ignore +tcx.sess.emit_err(FieldAlreadyDeclared { + field_name: f.ident, + span: f.span, + prev_span, +}); +``` + +### Reference +`#[derive(SessionDiagnostic)]` supports the following attributes: + +- `#[error(code = "...", slug = "...")]` or `#[warning(code = "...", slug = "...")]` + - _Applied to struct._ + - _Mandatory_ + - Defines the struct to be representing an error or a warning. + - `code = "..."` (_Optional_) + - Specifies the error code. + - `slug = "..."` (_Mandatory_) + - Uniquely identifies the diagnostic and corresponds to its Fluent message, + mandatory. +- `#[note]` or `#[note = "..."]` (_Optional_) + - _Applied to struct or `Span`/`()` fields._ + - Adds a note subdiagnostic. + - Value is the Fluent attribute (relative to the Fluent message specified by + `slug`) for the note's message + - Defaults to `note`. + - If applied to a `Span` field, creates a spanned note. +- `#[help]` or `#[help = "..."]` (_Optional_) + - _Applied to struct or `Span`/`()` fields._ + - Adds a help subdiagnostic. + - Value is the Fluent attribute (relative to the Fluent message specified by + `slug`) for the help's message. + - Defaults to `help`. + - If applied to a `Span` field, creates a spanned help. +- `#[label]` or `#[label = "..."]` (_Optional_) + - _Applied to `Span` fields._ + - Adds a label subdiagnostic. + - Value is the Fluent attribute (relative to the Fluent message specified by + `slug`) for the label's message. + - Defaults to `label`. +- `#[suggestion{,_hidden,_short,_verbose}(message = "...", code = "...", applicability = "...")]` + (_Optional_) + - _Applied to `(Span, MachineApplicability)` or `Span` fields._ + - Adds a suggestion subdiagnostic. + - `message = "..."` (_Mandatory_) + - Value is the Fluent attribute (relative to the Fluent message specified + by `slug`) for the suggestion's message. + - Defaults to `suggestion`. + - `code = "..."` (_Mandatory_) + - Value is a format string indicating the code to be suggested as a + replacement. + - `applicability = "..."` (_Optional_) + - String which must be one of `machine-applicable`, `maybe-incorrect`, + `has-placeholders` or `unspecified`. +- `#[subdiagnostic]` + - _Applied to a type that implements `AddToDiagnostic` (from + `#[derive(SessionSubdiagnostic)]`)._ + - Adds the subdiagnostic represented by the subdiagnostic struct. +- `#[primary_span]` (_Optional_) + - _Applied to `Span` fields._ + - Indicates the primary span of the diagnostic. +- `#[skip_arg]` (_Optional_) + - _Applied to any field._ + - Prevents the field from being provided as a diagnostic argument. + +## `#[derive(SessionSubdiagnostic)]` +It is common in the compiler to write a function that conditionally adds a +specific subdiagnostic to an error if it is applicable. Oftentimes these +subdiagnostics could be represented using a diagnostic struct even if the +overall diagnostic could not. In this circumstance, the `SessionSubdiagnostic` +derive can be used to represent a partial diagnostic (e.g a note, label, help or +suggestion) as a struct. + +Consider the [definition][subdiag_defn] of the "expected return type" label +shown below: + +```rust +#[derive(SessionSubdiagnostic)] +pub enum ExpectedReturnTypeLabel<'tcx> { + #[label(slug = "typeck-expected-default-return-type")] + Unit { + #[primary_span] + span: Span, + }, + #[label(slug = "typeck-expected-return-type")] + Other { + #[primary_span] + span: Span, + expected: Ty<'tcx>, + }, +} +``` + +Unlike `SessionDiagnostic`, `SessionSubdiagnostic` can be applied to structs or +enums. Attributes that are placed on the type for structs are placed on each +variants for enums (or vice versa). Each `SessionSubdiagnostic` should have one +attribute applied to the struct or each variant, one of: + +- `#[label(..)]` for defining a label +- `#[note(..)]` for defining a note +- `#[help(..)]` for defining a help +- `#[suggestion{,_hidden,_short,_verbose}(..)]` for defining a suggestion + +All of the above must have a value set for the `slug` sub-attribute. `slug` +uniquely identifies the diagnostic and is also how the compiler knows what +error message to emit (in the default locale of the compiler, or in the locale +requested by the user). See [translation documentation](./translation.md) to +learn more about how translatable error messages are written. + +In our example, the Fluent message for the "expected return type" label +looks like this: + +```fluent +typeck-expected-default-return-type = expected `()` because of default return type + +typeck-expected-return-type = expected `{$expected}` because of return type +``` + +Using the `#[primary_span]` attribute on a field (with type `Span`) will denote +the primary span of the subdiagnostic. A primary span is only necessary for a +label or suggestion, which can not be spanless. + +Every field of the type/variant which does not have an annotation is available +in Fluent messages as a variable. Fields can be annotated `#[skip_arg]` if this +is undesired. + +Like `SessionDiagnostic`, `SessionSubdiagnostic` supports `Option` and +`Vec` fields. + +Suggestions can be emitted using one of four attributes on the type/variant: + +- `#[suggestion(message = "...", code = "...", applicability = "...")]` +- `#[suggestion_hidden(message = "...", code = "...", applicability = "...")]` +- `#[suggestion_short(message = "...", code = "...", applicability = "...")]` +- `#[suggestion_verbose(message = "...", code = "...", applicability = "...")]` + +Suggestions require `#[primary_span]` be set on a field and can have the +following sub-attributes: + +- `message` specifies the Fluent attribute with the message and defaults to + `.suggestion`. +- `code` specifies the code that should be suggested as a replacement and is a + format string (e.g. `{field_name}` would be replaced by the value of the + `field_name` field of the struct), not a Fluent identifier. +- `applicability` can be used to specify the applicability in the attribute, it + cannot be used when the field's type contains an `Applicability`. + +Applicabilities can also be specified as a field (of type `Applicability`) +using the `#[applicability]` attribute. + +In the end, the `SessionSubdiagnostic` derive will generate an implementation +of `SessionSubdiagnostic` that looks like the following: + +```rust +impl<'tcx> AddToDiagnostic for ExpectedReturnTypeLabel<'tcx> { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + use rustc_errors::{Applicability, IntoDiagnosticArg}; + match self { + ExpectedReturnTypeLabel::Unit { span } => { + diag.span_label(span, DiagnosticMessage::fluent("typeck-expected-default-return-type")) + } + ExpectedReturnTypeLabel::Other { span, expected } => { + diag.set_arg("expected", expected); + diag.span_label(span, DiagnosticMessage::fluent("typeck-expected-return-type")) + } + + } + } +} +``` + +Once defined, a subdiagnostic can be used by passing it to the `subdiagnostic` +function ([example][subdiag_use_1] and [example][subdiag_use_2]) on a +diagnostic or by assigning it to a `#[subdiagnostic]`-annotated field of a +diagnostic struct. + +### Reference +`#[derive(SessionSubdiagnostic)]` supports the following attributes: + +- `#[label(slug = "...")]`, `#[help(slug = "...")]` or `#[note(slug = "...")]` + - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ + - _Mandatory_ + - Defines the type to be representing a label, help or note. + - `slug = "..."` (_Mandatory_) + - Uniquely identifies the diagnostic and corresponds to its Fluent message, + mandatory. +- `#[suggestion{,_hidden,_short,_verbose}(message = "...", code = "...", applicability = "...")]` + - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ + - _Mandatory_ + - Defines the type to be representing a suggestion. + - `message = "..."` (_Mandatory_) + - Value is the Fluent attribute (relative to the Fluent message specified + by `slug`) for the suggestion's message. + - Defaults to `suggestion`. + - `code = "..."` (_Mandatory_) + - Value is a format string indicating the code to be suggested as a + replacement. + - `applicability = "..."` (_Optional_) + - _Mutually exclusive with `#[applicability]` on a field._ + - Value is the applicability of the suggestion. + - String which must be one of: + - `machine-applicable` + - `maybe-incorrect` + - `has-placeholders` + - `unspecified` +- `#[primary_span]` (_Mandatory_ for labels and suggestions; _optional_ otherwise) + - _Applied to `Span` fields._ + - Indicates the primary span of the subdiagnostic. +- `#[applicability]` (_Optional_; only applicable to suggestions) + - _Applied to `Applicability` fields._ + - Indicates the applicability of the suggestion. +- `#[skip_arg]` (_Optional_) + - _Applied to any field._ + - Prevents the field from being provided as a diagnostic argument. + +[defn]: https://github.com/rust-lang/rust/blob/bbe9d27b8ff36da56638aa43d6d0cdfdf89a4e57/compiler/rustc_typeck/src/errors.rs#L65-L74 +[use]: https://github.com/rust-lang/rust/blob/eb82facb1626166188d49599a3313fc95201f556/compiler/rustc_typeck/src/collect.rs#L981-L985 + +[subdiag_defn]: https://github.com/rust-lang/rust/blob/e70c60d34b9783a2fd3171d88d248c2e0ec8ecdd/compiler/rustc_typeck/src/errors.rs#L220-L233 +[subdiag_use_1]: https://github.com/rust-lang/rust/blob/e70c60d34b9783a2fd3171d88d248c2e0ec8ecdd/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs#L556-L560 +[subdiag_use_2]: https://github.com/rust-lang/rust/blob/e70c60d34b9783a2fd3171d88d248c2e0ec8ecdd/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs#L575-L579 diff --git a/src/doc/rustc-dev-guide/src/diagnostics/error-guaranteed.md b/src/doc/rustc-dev-guide/src/diagnostics/error-guaranteed.md index 5a9b7f3354..d92ba62abb 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/error-guaranteed.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/error-guaranteed.md @@ -1,5 +1,4 @@ # `ErrorGuaranteed` - The previous sections have been about the error message that a user of the compiler sees. But emitting an error can also have a second important side effect within the compiler source code: it generates an @@ -19,7 +18,6 @@ There are some important considerations about the usage of `ErrorGuaranteed`: Thus, you should not rely on `ErrorGuaranteed` when deciding whether to emit an error, or what kind of error to emit. - * `ErrorGuaranteed` should not be used to indicate that a compilation _will emit_ an error in the future. It should be used to indicate that an error _has already been_ emitted -- that is, the [`emit()`][emit] function has @@ -30,7 +28,6 @@ There are some important considerations about the usage of `ErrorGuaranteed`: Thankfully, in most cases, it should be statically impossible to abuse `ErrorGuaranteed`. - [errorguar]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.ErrorGuaranteed.html [rerrors]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html [dsp]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Handler.html#method.delay_span_bug diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md index 489771dac4..39007f8d1d 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md @@ -1,104 +1,110 @@ # Lints - This page documents some of the machinery around lint registration and how we run lints in the compiler. -The [`LintStore`] is the central piece of infrastructure, around which everything -rotates. It's not available during the early parts of compilation (i.e., before -TyCtxt) in most code, as we need to fill it in with all of the lints, which can only happen after -plugin registration. +The [`LintStore`] is the central piece of infrastructure, around which +everything rotates. It's not available during the early parts of compilation +(i.e., before TyCtxt) in most code, as we need to fill it in with all of the +lints, which can only happen after plugin registration. ## Lints vs. lint passes +There are two parts to the linting mechanism within the compiler: lints and +lint passes. Unfortunately, a lot of the documentation we have refers to both +of these as just "lints." -There are two parts to the linting mechanism within the compiler: lints and lint passes. -Unfortunately, a lot of the documentation we have refers to both of these as just "lints." - -First, we have the lint declarations themselves: this is where the name and default lint level and -other metadata come from. These are normally defined by way of the [`declare_lint!`] macro, which -boils down to a static with type `&rustc_session::lint::Lint`. +First, we have the lint declarations themselves: this is where the name and +default lint level and other metadata come from. These are normally defined by +way of the [`declare_lint!`] macro, which boils down to a static with type +`&rustc_session::lint::Lint`. As of February 2022, we lint against direct declarations without the use of the macro today (although this may change in the future, as the macro is somewhat unwieldy to add new fields to, like all macros). -Lint declarations don't carry any "state" - they are merely global identifiers and descriptions of -lints. We assert at runtime that they are not registered twice (by lint name). +Lint declarations don't carry any "state" - they are merely global identifiers +and descriptions of lints. We assert at runtime that they are not registered +twice (by lint name). -Lint passes are the meat of any lint. Notably, there is not a one-to-one relationship between -lints and lint passes; a lint might not have any lint pass that emits it, it could have many, or -just one -- the compiler doesn't track whether a pass is in any way associated with a particular -lint, and frequently lints are emitted as part of other work (e.g., type checking, etc.). +Lint passes are the meat of any lint. Notably, there is not a one-to-one +relationship between lints and lint passes; a lint might not have any lint pass +that emits it, it could have many, or just one -- the compiler doesn't track +whether a pass is in any way associated with a particular lint, and frequently +lints are emitted as part of other work (e.g., type checking, etc.). ## Registration ### High-level overview +In [`rustc_interface::register_plugins`] the [`LintStore`] is created and all +lints are registered. + +There are four 'sources' of lints: -In [`rustc_interface::register_plugins`] the [`LintStore`] is created and all lints are registered. -There are four 'sources' of lints: * internal lints: lints only used by the rustc codebase -* builtin lints: lints built into the compiler and not provided by some outside source +* builtin lints: lints built into the compiler and not provided by some outside + source * plugin lints: lints created by plugins through the plugin system. -* `rustc_interface::Config`[`register_lints`]: lints passed into the compiler during construction +* `rustc_interface::Config`[`register_lints`]: lints passed into the compiler + during construction Lints are registered via the [`LintStore::register_lint`] function. This should happen just once for any lint, or an ICE will occur. -Once the registration is complete, we "freeze" the lint store by placing it in an `Lrc`. Later in -the driver, it's passed into the `GlobalCtxt` constructor where it lives in an immutable form from -then on. +Once the registration is complete, we "freeze" the lint store by placing it in +an `Lrc`. Later in the driver, it's passed into the `GlobalCtxt` constructor +where it lives in an immutable form from then on. -Lint passes are registered separately into one of the categories (pre-expansion, -early, late, late module). Passes are registered as a closure -- i.e., `impl -Fn() -> Box`, where `dyn X` is either an early or late lint pass trait -object. When we run the lint passes, we run the closure and then invoke the lint -pass methods. The lint pass methods take `&mut self` so they can keep track of state -internally. +Lint passes are registered separately into one of the categories +(pre-expansion, early, late, late module). Passes are registered as a closure +-- i.e., `impl Fn() -> Box`, where `dyn X` is either an early or late +lint pass trait object. When we run the lint passes, we run the closure and +then invoke the lint pass methods. The lint pass methods take `&mut self` so +they can keep track of state internally. #### Internal lints +These are lints used just by the compiler or plugins like `clippy`. They can be +found in `rustc_lint::internal`. -These are lints used just by the compiler or plugins like `clippy`. They can be found in -`rustc_lint::internal`. - -An example of such a lint is the check that lint passes are implemented using the -`declare_lint_pass!` macro and not by hand. This is accomplished with the +An example of such a lint is the check that lint passes are implemented using +the `declare_lint_pass!` macro and not by hand. This is accomplished with the `LINT_PASS_IMPL_WITHOUT_MACRO` lint. -Registration of these lints happens in the [`rustc_lint::register_internals`] function which is -called when constructing a new lint store inside [`rustc_lint::new_lint_store`]. +Registration of these lints happens in the [`rustc_lint::register_internals`] +function which is called when constructing a new lint store inside +[`rustc_lint::new_lint_store`]. ### Builtin Lints - These are primarily described in two places: `rustc_session::lint::builtin` and -`rustc_lint::builtin`. Often the first provides the definitions for the lints themselves, -and the latter provides the lint pass definitions (and implementations), but this is not always -true. +`rustc_lint::builtin`. Often the first provides the definitions for the lints +themselves, and the latter provides the lint pass definitions (and +implementations), but this is not always true. -The builtin lint registration happens in the [`rustc_lint::register_builtins`] function. Just like -with internal lints, this happens inside of [`rustc_lint::new_lint_store`]. +The builtin lint registration happens in the [`rustc_lint::register_builtins`] +function. Just like with internal lints, this happens inside of +[`rustc_lint::new_lint_store`]. #### Plugin lints +This is one of the primary use cases remaining for plugins/drivers. Plugins are +given access to the mutable `LintStore` during registration (which happens +inside of [`rustc_interface::register_plugins`]) and they can call any +functions they need on the `LintStore`, just like rustc code. -This is one of the primary use cases remaining for plugins/drivers. Plugins are given access -to the mutable `LintStore` during registration (which happens inside of -[`rustc_interface::register_plugins`]) and they can call any functions they need on -the `LintStore`, just like rustc code. - -Plugins are intended to declare lints with the `plugin` field set to true (e.g., by -way of the [`declare_tool_lint!`] macro), but this is purely for diagnostics and help text; -otherwise plugin lints are mostly just as first class as rustc builtin lints. +Plugins are intended to declare lints with the `plugin` field set to true +(e.g., by way of the [`declare_tool_lint!`] macro), but this is purely for +diagnostics and help text; otherwise plugin lints are mostly just as first +class as rustc builtin lints. #### Driver lints - -These are the lints provided by drivers via the `rustc_interface::Config` [`register_lints`] field, -which is a callback. Drivers should, if finding it already set, call the function currently set -within the callback they add. The best way for drivers to get access to this is by overriding the -`Callbacks::config` function which gives them direct access to the `Config` structure. +These are the lints provided by drivers via the `rustc_interface::Config` +[`register_lints`] field, which is a callback. Drivers should, if finding it +already set, call the function currently set within the callback they add. The +best way for drivers to get access to this is by overriding the +`Callbacks::config` function which gives them direct access to the `Config` +structure. ## Compiler lint passes are combined into one pass - Within the compiler, for performance reasons, we usually do not register dozens -of lint passes. Instead, we have a single lint pass of each variety -(e.g., `BuiltinCombinedModuleLateLintPass`) which will internally call all of the +of lint passes. Instead, we have a single lint pass of each variety (e.g., +`BuiltinCombinedModuleLateLintPass`) which will internally call all of the individual lint passes; this is because then we get the benefits of static over dynamic dispatch for each of the (often empty) trait methods. diff --git a/src/doc/rustc-dev-guide/src/diagnostics/sessiondiagnostic.md b/src/doc/rustc-dev-guide/src/diagnostics/sessiondiagnostic.md deleted file mode 100644 index e82d5629d5..0000000000 --- a/src/doc/rustc-dev-guide/src/diagnostics/sessiondiagnostic.md +++ /dev/null @@ -1,207 +0,0 @@ -# Creating translatable errors using `SessionDiagnostic` -The `SessionDiagnostic` derive macro is the recommended way to create -diagnostics. Diagnostics created with the derive macro can be translated into -different languages and each have a slug that uniquely identifies the -diagnostic. - -Instead of using the `DiagnosticBuilder` API to create and emit diagnostics, -the `SessionDiagnostic` derive macro is applied to structs. - -The [definition][defn] of the "field already declared" diagnostic is shown -below. - -```rust,ignore -#[derive(SessionDiagnostic)] -#[error(code = "E0124", slug = "typeck-field-already-declared")] -pub struct FieldAlreadyDeclared { - pub field_name: Ident, - #[primary_span] - #[label] - pub span: Span, - #[label = "previous-decl-label"] - pub prev_span: Span, -} -``` - -Every `SessionDiagnostic` has to have one attribute applied to the struct -itself: either `#[error(..)]` for defining errors, or `#[warning(..)]` for -defining warnings. - -If an error has an error code (e.g. "E0624"), then that can be specified using -the `code` sub-attribute. Specifying a `code` isn't mandatory, but if you are -porting a diagnostic that uses `DiagnosticBuilder` to use `SessionDiagnostic` -then you should keep the code if there was one. - -Both `#[error(..)]` and `#[warning(..)]` must set a value for the `slug` -sub-attribute. `slug` uniquely identifies the diagnostic and is also how the -compiler knows what error message to emit (in the default locale of the -compiler, or in the locale requested by the user). - -rustc uses [Fluent](https://projectfluent.org) to handle the intricacies of -translation. Each diagnostic's `slug` is actually an identifier for a *Fluent -message*. Let's take a look at what the Fluent message for the "field already -declared" diagnostic looks like: - -```fluent -typeck-field-already-declared = - field `{$field_name}` is already declared - .label = field already declared - .previous-decl-label = `{$field_name}` first declared here -``` - -`typeck-field-already-declared` is the `slug` from our example and is followed -by the diagnostic message. - -Fluent is built around the idea of "asymmetric localization", which aims to -decouple the expressiveness of translations from the grammar of the source -language (English in rustc's case). Prior to translation, rustc's diagnostics -relied heavily on interpolation to build the messages shown to the users. -Interpolated strings are hard to translate because writing a natural-sounding -translation might require more, less, or just different interpolation than the -English string, all of which would require changes to the compiler's source -code to support. - -As the compiler team gain more experience creating `SessionDiagnostic` structs -that have all of the information necessary to be translated into different -languages, this page will be updated with more guidance. For now, the [Project -Fluent](https://projectfluent.org) documentation has excellent examples of -translating messages into different locales and the information that needs to -be provided by the code to do so. - -When adding or changing a diagnostic, you don't need to worry about the -translations, only updating the original English message. All of rustc's -English Fluent messages can be found in -`/compiler/rustc_error_messages/locales/en-US/diagnostics.ftl`. - -Every field of the `SessionDiagnostic` which does not have an annotation is -available in Fluent messages as a variable, like `field_name` in the example -above. - -Using the `#[primary_span]` attribute on a field (that has type `Span`) -indicates the primary span of the diagnostic which will have the main message -of the diagnostic. - -Diagnostics are more than just their primary message, they often include -labels, notes, help messages and suggestions, all of which can also be -specified on a `SessionDiagnostic`. - -`#[label]`, `#[help]` and `#[note]` can all be applied to fields which have the -type `Span`. Applying any of these attributes will create the corresponding -sub-diagnostic with that `Span`. These attributes will look for their -diagnostic message in a Fluent attribute attached to the primary Fluent -message. In our example, `#[label]` will look for -`typeck-field-already-declared.label` (which has the message "field already -declared"). If there is more than one sub-diagnostic of the same type, then -these attributes can also take a value that is the attribute name to look for -(e.g. `previous-decl-label` in our example). - -`#[help]` and `#[note]` can also be applied to the struct itself, in which case -they work exactly like when applied to fields except the sub-diagnostic won't -have a `Span`. - -Any attribute can also be applied to an `Option` and will only emit a -sub-diagnostic if the option is `Some(..)`. - -Suggestions can be emitted using one of four field attributes: - -- `#[suggestion(message = "...", code = "...")]` -- `#[suggestion_hidden(message = "...", code = "...")]` -- `#[suggestion_short(message = "...", code = "...")]` -- `#[suggestion_verbose(message = "...", code = "...")]` - -Suggestions must be applied on either a `Span` field or a -`(Span, MachineApplicability)` field. Similarly to other field attributes, -`message` specifies the Fluent attribute with the message and defaults to -`.suggestion`. `code` specifies the code that should be suggested as a -replacement and is a format string (e.g. `{field_name}` would be replaced by -the value of the `field_name` field of the struct), not a Fluent identifier. - -In the end, the `SessionDiagnostic` derive will generate an implementation of -`SessionDiagnostic` that looks like the following: - -```rust,ignore -impl SessionDiagnostic for FieldAlreadyDeclared { - fn into_diagnostic(self, sess: &'_ rustc_session::Session) -> DiagnosticBuilder<'_> { - let mut diag = sess.struct_err_with_code( - rustc_errors::DiagnosticMessage::fluent("typeck-field-already-declared"), - rustc_errors::DiagnosticId::Error("E0124") - ); - diag.set_span(self.span); - diag.span_label( - self.span, - rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "label") - ); - diag.span_label( - self.prev_span, - rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "previous-decl-label") - ); - diag - } -} -``` - -Now that we've defined our diagnostic, how do we [use it][use]? It's quite -straightforward, just create an instance of the struct and pass it to -`emit_err` (or `emit_warning`): - -```rust,ignore -tcx.sess.emit_err(FieldAlreadyDeclared { - field_name: f.ident, - span: f.span, - prev_span, -}); -``` - -## Reference -`#[derive(SessionDiagnostic)]` supports the following attributes: - -- `#[error(code = "...", slug = "...")]` or `#[warning(code = "...", slug = "...")]` - - _Applied to struct._ - - _Mandatory_ - - Defines the struct to be representing an error or a warning. - - `code = "..."` - - _Optional_ - - Specifies the error code. - - `slug = "..."` - - _Mandatory_ - - Uniquely identifies the diagnostic and corresponds to its Fluent message, - mandatory. -- `#[note]` or `#[note = "..."]` - - _Applied to struct or `Span` fields._ - - _Optional_ - - Adds a note sub-diagnostic. - - Value is the Fluent attribute (relative to the Fluent message specified by - `slug`) for the note's message - - Defaults to `note`. - - If applied to a `Span` field, creates a spanned note. -- `#[help]` or `#[help = "..."]` - - _Applied to struct or `Span` fields._ - - _Optional_ - - Adds a help sub-diagnostic. - - Value is the Fluent attribute (relative to the Fluent message specified by - `slug`) for the help's message - - Defaults to `help`. - - If applied to a `Span` field, creates a spanned help. -- `#[label]` or `#[label = "..."]` - - _Applied to `Span` fields._ - - _Optional_ - - Adds a label sub-diagnostic. - - Value is the Fluent attribute (relative to the Fluent message specified by - `slug`) for the label's message - - Defaults to `label`. -- `#[suggestion{,_hidden,_short,_verbose}(message = "...", code = "...")]` - - _Applied to `(Span, MachineApplicability)` or `Span` fields._ - - _Optional_ - - Adds a suggestion sub-diagnostic. - - `message = "..."` - - _Mandatory_ - - Value is the Fluent attribute (relative to the Fluent message specified - by `slug`) for the suggestion's message - - Defaults to `suggestion`. - - `code = "..."` - - _Optional_ - - Value is a format string indicating the code to be suggested as a - replacement. - -[defn]: https://github.com/rust-lang/rust/blob/bbe9d27b8ff36da56638aa43d6d0cdfdf89a4e57/compiler/rustc_typeck/src/errors.rs#L65-L74 -[use]: https://github.com/rust-lang/rust/blob/eb82facb1626166188d49599a3313fc95201f556/compiler/rustc_typeck/src/collect.rs#L981-L985 diff --git a/src/doc/rustc-dev-guide/src/diagnostics/translation.md b/src/doc/rustc-dev-guide/src/diagnostics/translation.md new file mode 100644 index 0000000000..5c078ffb32 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/diagnostics/translation.md @@ -0,0 +1,239 @@ +# Translation +rustc's diagnostic infrastructure supports translatable diagnostics using +[Fluent]. + +## Writing translatable diagnostics +There are two ways of writing translatable diagnostics: + +1. For simple diagnostics, using a diagnostic (or subdiagnostic) derive + ("simple" diagnostics being those that don't require a lot of logic in + deciding to emit subdiagnostics and can therefore be represented as + diagnostic structs). See [the diagnostic and subdiagnostic structs + documentation](./diagnostic-structs.md). +2. Using typed identifiers with `DiagnosticBuilder` APIs (in + `SessionDiagnostic` implementations). + +When adding or changing a translatable diagnostic, you don't need to worry +about the translations, only updating the original English message. Currently, +each crate which defines translatable diagnostics has its own Fluent resource, +such as `parser.ftl` or `typeck.ftl`. + +## Fluent +Fluent is built around the idea of "asymmetric localization", which aims to +decouple the expressiveness of translations from the grammar of the source +language (English in rustc's case). Prior to translation, rustc's diagnostics +relied heavily on interpolation to build the messages shown to the users. +Interpolated strings are hard to translate because writing a natural-sounding +translation might require more, less, or just different interpolation than the +English string, all of which would require changes to the compiler's source +code to support. + +Diagnostic messages are defined in Fluent resources. A combined set of Fluent +resources for a given locale (e.g. `en-US`) is known as Fluent bundle. + +```fluent +typeck-address-of-temporary-taken = cannot take address of a temporary +``` + +In the above example, `typeck-address-of-temporary-taken` is the identifier for +a Fluent message and corresponds to the diagnostic message in English. Other +Fluent resources can be written which would correspond to a message in another +language. Each diagnostic therefore has at least one Fluent message. + +```fluent +typeck-address-of-temporary-taken = cannot take address of a temporary + .label = temporary value +``` + +By convention, diagnostic messages for subdiagnostics are specified as +"attributes" on Fluent messages (additional related messages, denoted by the +`.` syntax). In the above example, `label` is an attribute of +`typeck-address-of-temporary-taken` which corresponds to the message for the +label added to this diagnostic. + +Diagnostic messages often interpolate additional context into the message shown +to the user, such as the name of a type or of a variable. Additional context to +Fluent messages is provided as an "argument" to the diagnostic. + +```fluent +typeck-struct-expr-non-exhaustive = + cannot create non-exhaustive {$what} using struct expression +``` + +In the above example, the Fluent message refers to an argument named `what` +which is expected to exist (how arguments are provided to diagnostics is +discussed in detail later). + +You can consult the [Fluent] documentation for other usage examples of Fluent +and its syntax. + +### Guidelines for writing translatable messages +For a message to be translatable into different languages, all of the +information required by any language must be provided to the diagnostic as an +argument (not just the information required in the English message). + +As the compiler team gain more experience writing diagnostics that have all of +the information necessary to be translated into different languages, this page +will be updated with more guidance. For now, the [Fluent] documentation has +excellent examples of translating messages into different locales and the +information that needs to be provided by the code to do so. + +### Compile-time validation and typed identifiers +rustc's Fluent resources for the default locale (`en-US`) are in the +[`compiler/rustc_error_messages/locales/en-US`] directory. Currently, each crate +which defines translatable diagnostics has its own Fluent resource, such as +`parser.ftl` or `typeck.ftl`. + +rustc's `fluent_messages` macro performs compile-time validation of Fluent +resources and generates code to make it easier to refer to Fluent messages in +diagnostics. + +Compile-time validation of Fluent resources will emit any parsing errors +from Fluent resources while building the compiler, preventing invalid Fluent +resources from causing panics in the compiler. Compile-time validation also +emits an error if multiple Fluent messages have the same identifier. + +In `rustc_error_messages`, `fluent_messages` also generates a constant for each +Fluent message which can be used to refer to messages when emitting +diagnostics and guarantee that the message exists. + +```rust +fluent_messages! { + typeck => "../locales/en-US/typeck.ftl", +} +``` + +For example, given the following Fluent... + +```fluent +typeck-field-multiply-specified-in-initializer = + field `{$ident}` specified more than once + .label = used more than once + .label-previous-use = first use of `{$ident}` +``` + +...then the `fluent_messages` macro will generate: + +```rust +pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[ + include_str!("../locales/en-US/typeck.ftl"), +]; + +mod fluent_generated { + mod typeck { + pub const field_multiply_specified_in_initializer: DiagnosticMessage = + DiagnosticMessage::new("typeck-field-multiply-specified-in-initializer"); + pub const label: SubdiagnosticMessage = + SubdiagnosticMessage::attr("label"); + pub const label_previous_use: SubdiagnosticMessage = + SubdiagnosticMessage::attr("previous-use-label"); + } +} +``` + +`rustc_error_messages::fluent_generated` is re-exported and primarily used as +`rustc_errors::fluent`. + +```rust +use rustc_errors::fluent; +let mut err = sess.struct_span_err(span, fluent::typeck::field_multiply_specified_in_initializer); +err.span_label(span, fluent::typeck::label); +err.span_label(previous_use_span, fluent::typeck::previous_use_label); +err.emit(); +``` + +When emitting a diagnostic, these constants can be used like shown above. + +## Internals +Various parts of rustc's diagnostic internals are modified in order to support +translation. + +### Messages +All of rustc's traditional diagnostic APIs (e.g. `struct_span_err` or `note`) +take any message that can be converted into a `DiagnosticMessage` (or +`SubdiagnosticMessage`). + +[`rustc_error_messages::DiagnosticMessage`] can represent legacy non-translatable +diagnostic messages and translatable messages. Non-translatable messages are +just `String`s. Translatable messages are just a `&'static str` with the +identifier of the Fluent message (sometimes with an additional `&'static str` +with an attribute). + +`DiagnosticMessage` never needs to be interacted with directly: +`DiagnosticMessage` constants are created for each diagnostic message in a +Fluent resource (described in more detail below), or `DiagnosticMessage`s will +either be created in the macro-generated code of a diagnostic derive. + +`rustc_error_messages::SubdiagnosticMessage` is similar, it can correspond to a +legacy non-translatable diagnostic message or the name of an attribute to a +Fluent message. Translatable `SubdiagnosticMessage`s must be combined with a +`DiagnosticMessage` (using `DiagnosticMessage::with_subdiagnostic_message`) to +be emitted (an attribute name on its own is meaningless without a corresponding +message identifier, which is what `DiagnosticMessage` provides). + +Both `DiagnosticMessage` and `SubdiagnosticMessage` implement `Into` for any +type that can be converted into a string, and converts these into +non-translatable diagnostics - this keeps all existing diagnostic calls +working. + +### Arguments +Additional context for Fluent messages which are interpolated into message +contents needs to be provided to translatable diagnostics. + +Diagnostics have a `set_arg` function that can be used to provide this +additional context to a diagnostic. + +Arguments have both a name (e.g. "what" in the earlier example) and a value. +Argument values are represented using the `DiagnosticArgValue` type, which is +just a string or a number. rustc types can implement `IntoDiagnosticArg` with +conversion into a string or a number, common types like `Ty<'tcx>` already +have such implementations. + +`set_arg` calls are handled transparently by diagnostic derives but need to be +added manually when using diagnostic builder APIs. + +### Loading +rustc makes a distinction between the "fallback bundle" for `en-US` that is used +by default and when another locale is missing a message; and the primary fluent +bundle which is requested by the user. + +Diagnostic emitters implement the `Emitter` trait which has two functions for +accessing the fallback and primary fluent bundles (`fallback_fluent_bundle` and +`fluent_bundle` respectively). + +`Emitter` also has member functions with default implementations for performing +translation of a `DiagnosticMessage` using the results of +`fallback_fluent_bundle` and `fluent_bundle`. + +All of the emitters in rustc load the fallback Fluent bundle lazily, only +reading Fluent resources and parsing them when an error message is first being +translated (for performance reasons - it doesn't make sense to do this if no +error is being emitted). `rustc_error_messages::fallback_fluent_bundle` returns +a `std::lazy::Lazy` which is provided to emitters and evaluated +in the first call to `Emitter::fallback_fluent_bundle`. + +The primary Fluent bundle (for the user's desired locale) is expected to be +returned by `Emitter::fluent_bundle`. This bundle is used preferentially when +translating messages, the fallback bundle is only used if the primary bundle is +missing a message or not provided. + +As of June 2022, there are no locale bundles +distributed with the compiler, but mechanisms are implemented for loading +bundles. + +- `-Ztranslate-additional-ftl` can be used to load a specific resource as the + primary bundle for testing purposes. +- `-Ztranslate-lang` can be provided a language identifier (something like + `en-US`) and will load any Fluent resources found in + `$sysroot/share/locale/$locale/` directory (both the user provided + sysroot and any sysroot candidates). + +Primary bundles are not currently loaded lazily and if requested will be loaded +at the start of compilation regardless of whether an error occurs. Lazily +loading primary bundles is possible if it can be assumed that loading a bundle +won't fail. Bundle loading can fail if a requested locale is missing, Fluent +files are malformed, or a message is duplicated in multiple resources. + +[Fluent]: https://projectfluent.org +[`compiler/rustc_error_messages/locales/en-US`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_error_messages/locales/en-US +[`rustc_error_messages::DiagnosticMessage`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_error_messages/enum.DiagnosticMessage.html diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md index d5c37f82df..e55dbf858e 100644 --- a/src/doc/rustc-dev-guide/src/git.md +++ b/src/doc/rustc-dev-guide/src/git.md @@ -18,7 +18,7 @@ more in depth [book from Git]. [book from Git]: https://git-scm.com/book/en/v2/ [atlassian-git]: https://www.atlassian.com/git/tutorials/what-is-version-control -[documentation]: https://docs.github.com/en/github/getting-started-with-github/set-up-git +[documentation]: https://docs.github.com/en/get-started/quickstart/set-up-git [guides]: https://guides.github.com/introduction/git-handbook/ ## Prerequisites diff --git a/src/doc/rustc-dev-guide/src/macro-expansion.md b/src/doc/rustc-dev-guide/src/macro-expansion.md index e3b5a27e6b..840bfabe83 100644 --- a/src/doc/rustc-dev-guide/src/macro-expansion.md +++ b/src/doc/rustc-dev-guide/src/macro-expansion.md @@ -227,7 +227,7 @@ only within the macro (i.e. it should not be visible outside the macro). [code_dir]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_expand/src/mbe [code_mp]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/mbe/macro_parser [code_mr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/mbe/macro_rules -[code_parse_int]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/mbe/macro_parser/fn.parse_tt.html +[code_parse_int]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/mbe/macro_parser/struct.TtParser.html#method.parse_tt [parsing]: ./the-parser.html The context is attached to AST nodes. All AST nodes generated by macros have @@ -503,9 +503,10 @@ The interface of the macro parser is as follows (this is slightly simplified): ```rust,ignore fn parse_tt( - parser: &mut Cow, - ms: &[TokenTree], -) -> NamedParseResult + &mut self, + parser: &mut Cow<'_, Parser<'_>>, + matcher: &[MatcherLoc] +) -> ParseResult ``` We use these items in macro parser: @@ -515,20 +516,20 @@ We use these items in macro parser: ask the MBE parser to parse. We will consume the raw stream of tokens and output a binding of metavariables to corresponding token trees. The parsing session can be used to report parser errors. -- `ms` a _matcher_. This is a sequence of token trees that we want to match - the token stream against. +- `matcher` is a sequence of `MatcherLoc`s that we want to match + the token stream against. They're converted from token trees before matching. In the analogy of a regex parser, the token stream is the input and we are matching it -against the pattern `ms`. Using our examples, the token stream could be the stream of -tokens containing the inside of the example invocation `print foo`, while `ms` +against the pattern `matcher`. Using our examples, the token stream could be the stream of +tokens containing the inside of the example invocation `print foo`, while `matcher` might be the sequence of token (trees) `print $mvar:ident`. -The output of the parser is a `NamedParseResult`, which indicates which of +The output of the parser is a [`ParseResult`], which indicates which of three cases has occurred: -- Success: the token stream matches the given matcher `ms`, and we have produced a binding +- Success: the token stream matches the given `matcher`, and we have produced a binding from metavariables to the corresponding token trees. -- Failure: the token stream does not match `ms`. This results in an error message such as +- Failure: the token stream does not match `matcher`. This results in an error message such as "No rule expected token _blah_". - Error: some fatal error has occurred _in the parser_. For example, this happens if there are more than one pattern match, since that indicates @@ -607,6 +608,7 @@ Because the Rust ABI is unstable, we use the C ABI for this conversion. [stablets]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html [pm]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/proc_macro/index.html [pms]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/proc_macro_server/index.html +[`ParseResult`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/mbe/macro_parser/enum.ParseResult.html TODO: more here. [#1160](https://github.com/rust-lang/rustc-dev-guide/issues/1160) diff --git a/src/doc/rustc-dev-guide/src/mir/dataflow.md b/src/doc/rustc-dev-guide/src/mir/dataflow.md index 6fe8d6aa5a..ce4a86a239 100644 --- a/src/doc/rustc-dev-guide/src/mir/dataflow.md +++ b/src/doc/rustc-dev-guide/src/mir/dataflow.md @@ -17,8 +17,10 @@ some basic terminology, such as "transfer function", "fixpoint" and "lattice". If you're unfamiliar with these terms, or if you want a quick refresher, [*Static Program Analysis*] by Anders Møller and Michael I. Schwartzbach is an excellent, freely available textbook. For those who prefer audiovisual -learning, the Goethe University Frankfurt has published a series of short -[lectures on YouTube][goethe] in English that are very approachable. +learning, we previously recommended a series of short lectures +by the Goethe University Frankfurt on YouTube, but it has since been deleted. +See [this PR][pr-1295] for the context and [this comment][pr-1295-comment] +for the alternative lectures. ## Defining a Dataflow Analysis @@ -229,6 +231,7 @@ the example below: [`apply_call_return_effect`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/trait.Analysis.html#tymethod.apply_call_return_effect [`into_engine`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/trait.Analysis.html#method.into_engine [`lattice`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/lattice/index.html -[goethe]: https://www.youtube.com/watch?v=NVBQSR_HdL0&list=PL_sGR8T76Y58l3Gck3ZwIIHLWEmXrOLV_&index=2 +[pr-1295]: https://github.com/rust-lang/rustc-dev-guide/pull/1295 +[pr-1295-comment]: https://github.com/rust-lang/rustc-dev-guide/pull/1295#issuecomment-1118131294 [lattice]: https://en.wikipedia.org/wiki/Lattice_(order) [wiki]: https://en.wikipedia.org/wiki/Data-flow_analysis#Basic_principles diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md index a3c2258e88..ea4b3ca046 100644 --- a/src/doc/rustc-dev-guide/src/overview.md +++ b/src/doc/rustc-dev-guide/src/overview.md @@ -83,9 +83,9 @@ try to recover, parsing a superset of Rust's grammar, while also emitting an err ### HIR lowering -We next take the AST and convert it to [High-Level Intermediate +Next, we take the AST and convert it to [High-Level Intermediate Representation (HIR)][hir], a more compiler-friendly representation of the -AST. This process called "lowering". It involves a lot of desugaring of things +AST. This process is called "lowering". It involves a lot of desugaring of things like loops and `async fn`. We then use the HIR to do [*type inference*] (the process of automatic diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md index f81e02d28f..dc196e490f 100644 --- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md @@ -58,7 +58,7 @@ The story is a bit different for `type_check_item(foo)`: We again walk the edges and already know that `type_of(foo)` is fine. Then we get to `type_of(bar)` which we have not checked yet, so we walk the edges of `type_of(bar)` and encounter `Hir(bar)` which *has* changed. Consequently -the result of `type_of(bar)` might yield a different same result than what we +the result of `type_of(bar)` might yield a different result than what we have in the cache and, transitively, the result of `type_check_item(foo)` might have changed too. We thus re-run `type_check_item(foo)`, which in turn will re-run `type_of(bar)`, which will yield an up-to-date result @@ -329,7 +329,7 @@ up its dependencies (i.e. also dep-nodes in the previous graph) and continue wit the rest of the try-mark-green algorithm. The next interesting thing happens when we successfully marked the node as green. At that point we copy the node and the edges to its dependencies from the old graph into the new graph. We -have to do this because the new dep-graph cannot not acquire the +have to do this because the new dep-graph cannot acquire the node and edges via the regular dependency tracking. The tracking system can only record edges while actually running a query -- but running the query, although we have the result already cached, is exactly what we want to avoid. diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 6e02bfc7bf..95e570dfc7 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -37,7 +37,7 @@ will in turn demand information about that crate, starting from the actual parsing. Although this vision is not fully realized, large sections of the -compiler (for example, generating [MIR](./mir/)) currently work exactly like this. +compiler (for example, generating [MIR](./mir/index.md)) currently work exactly like this. [^incr-comp-detail]: The ["Incremental Compilation in Detail](queries/incremental-compilation-in-detail.md) chapter gives a more in-depth description of what queries are and how they work. diff --git a/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md b/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md index fa5ce0750e..327415e5aa 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md @@ -6,8 +6,8 @@ To get diagnostics from the compiler, configure `rustc_interface::Config` to output diagnostic to a buffer, -and run `TyCtxt.analysis`. The following should be compiled -with `nightly-2021-03-28` (See [here][example] +and run `TyCtxt.analysis`. The following was tested +with `nightly-2022-06-05` (See [here][example] for the complete example): [example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-driver-getting-diagnostics.rs @@ -35,7 +35,7 @@ rustc_interface::run_compiler(config, |compiler| { compiler.enter(|queries| { queries.global_ctxt().unwrap().take().enter(|tcx| { // Run the analysis phase on the local crate to trigger the type error. - tcx.analysis(rustc_hir::def_id::LOCAL_CRATE); + let _ = tcx.analysis(()); }); }); }); diff --git a/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md b/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md index 7cb53187b2..d70264fe4f 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md @@ -5,7 +5,7 @@ ## Getting the type of an expression To get the type of an expression, use the `global_ctxt` to get a `TyCtxt`. -The following should be compiled with `nightly-2021-03-28` +The following was tested with `nightly-2022-06-05` (see [here][example] for the complete example): [example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-driver-interacting-with-the-ast.rs @@ -24,9 +24,10 @@ rustc_interface::run_compiler(config, |compiler| { // Analyze the crate and inspect the types under the cursor. queries.global_ctxt().unwrap().take().enter(|tcx| { // Every compilation contains a single crate. - let hir_krate = tcx.hir().krate(); + let hir_krate = tcx.hir(); // Iterate over the top-level items in the crate, looking for the main function. - for (_, item) in &hir_krate.items { + for id in hir_krate.items() { + let item = hir_krate.item(id); // Use pattern-matching to find a specific node inside the main function. if let rustc_hir::ItemKind::Fn(_, _, body_id) = item.kind { let expr = &tcx.hir().body(body_id).value; @@ -36,7 +37,7 @@ rustc_interface::run_compiler(config, |compiler| { let hir_id = expr.hir_id; // hir_id identifies the string "Hello, world!" let def_id = tcx.hir().local_def_id(item.hir_id()); // def_id identifies the main function let ty = tcx.typeck(def_id).node_type(hir_id); - println!("{:?}: {:?}", expr, ty); // prints expr(HirId { owner: DefIndex(3), local_id: 4 }: "Hello, world!"): &'static str + println!("{:?}: {:?}", expr, ty); } } } diff --git a/src/doc/rustc-dev-guide/src/rustc-driver.md b/src/doc/rustc-dev-guide/src/rustc-driver.md index 2cffba42c8..7250c852c5 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver.md @@ -7,7 +7,7 @@ using the interface defined in the [`rustc_interface`] crate. The `rustc_interface` crate provides external users with an (unstable) API for running code at particular times during the compilation process, allowing third parties to effectively use `rustc`'s internals as a library for -analysing a crate or emulating the compiler in-process (e.g. the RLS or rustdoc). +analyzing a crate or emulating the compiler in-process (e.g. the RLS or rustdoc). For those using `rustc` as a library, the [`rustc_interface::run_compiler()`][i_rc] function is the main entrypoint to the compiler. It takes a configuration for the compiler diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md index ccf0fcc5fe..1050c259b1 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md @@ -32,7 +32,7 @@ is the `impl Clean for visit_ast::RustdocVisitor`, which is called by `run_core` above. You see, I actually lied a little earlier: There's another AST transformation -that happens before the events in `clean/mod.rs`. In `visit_ast.rs` is the +that happens before the events in `clean/mod.rs`. In `visit_ast.rs` is the type `RustdocVisitor`, which *actually* crawls a `rustc_hir::Crate` to get the first intermediate representation, defined in `doctree.rs`. This pass is mainly to get a few intermediate wrappers around the HIR types and to process visibility @@ -52,10 +52,10 @@ which describe the publicly-documentable items in the target crate. Before moving on to the next major step, a few important "passes" occur over the documentation. These do things like combine the separate "attributes" into -a single string and strip leading whitespace to make the document easier on the -markdown parser, or drop items that are not public or deliberately hidden with -`#[doc(hidden)]`. These are all implemented in the `passes/` directory, one -file per pass. By default, all of these passes are run on a crate, but the ones +a single string to make the document easier on the markdown parser, +or drop items that are not public or deliberately hidden with `#[doc(hidden)]`. +These are all implemented in the `passes/` directory, one file per pass. +By default, all of these passes are run on a crate, but the ones regarding dropping private/hidden items can be bypassed by passing `--document-private-items` to rustdoc. Note that unlike the previous set of AST transformations, the passes are run on the _cleaned_ crate. @@ -66,7 +66,7 @@ these passes, please let us know!) [44136]: https://github.com/rust-lang/rust/issues/44136 -Here is the list of passes as of October 2021: +Here is the list of passes as of May 2022: - `calculate-doc-coverage` calculates information used for the `--show-coverage` flag. @@ -74,7 +74,7 @@ Here is the list of passes as of October 2021: - `check-bare-urls` detects links that are not linkified, e.g., in Markdown such as `Go to https://example.com/.` It suggests wrapping the link with angle brackets: `Go to .` to linkify it. This is the code behind the `rustdoc::bare_urls` lint. + date: 2022-05 --> `rustdoc::bare_urls` lint. - `check-code-block-syntax` validates syntax inside Rust code blocks (```rust) @@ -84,7 +84,7 @@ Here is the list of passes as of October 2021: - `check-invalid-html-tags` detects invalid HTML (like an unclosed ``) in doc comments. -- `collect-intra-doc-links` resolves [intra-doc links](https://doc.rust-lang.org/rustdoc/linking-to-items-by-name.html). +- `collect-intra-doc-links` resolves [intra-doc links](https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html). - `collect-trait-impls` collects trait impls for each item in the crate. For example, if we define a struct that implements a trait, this pass will note @@ -102,23 +102,6 @@ Here is the list of passes as of October 2021: from the output. `strip-private` implies `strip-priv-imports`. Basically, the goal is to remove items that are not relevant for public documentation. -- `unindent-comments` removes excess indentation on comments in order for the - Markdown to be parsed correctly. This is necessary because the convention for - writing documentation is to provide a space between the `///` or `//!` marker - and the doc text, but Markdown is whitespace-sensitive. For example, a block - of text with four-space indentation is parsed as a code block, so if we didn't - unindent comments, these list items - - ```rust,ignore - /// A list: - /// - /// - Foo - /// - Bar - ``` - - would be parsed as if they were in a code block, which is likely not what the - user intended. - There is also a `stripper` module in `passes/`, but it is a collection of utility functions for the `strip-*` passes and is not a pass itself. diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md index 51d849200c..3469ce2baa 100644 --- a/src/doc/rustc-dev-guide/src/stability.md +++ b/src/doc/rustc-dev-guide/src/stability.md @@ -121,24 +121,21 @@ Always ping @rust-lang/wg-const-eval if you are adding more ## staged_api -Any crate that uses the `stable`, `unstable`, or `rustc_deprecated` attributes -must include the `#![feature(staged_api)]` attribute on the crate. +Any crate that uses the `stable` or `unstable` attributes must include the +`#![feature(staged_api)]` attribute on the crate. -## rustc_deprecated +## deprecated -The deprecation system shares the same infrastructure as the stable/unstable -attributes. The `rustc_deprecated` attribute is similar to the [`deprecated` -attribute]. It was previously called `deprecated`, but was split off when -`deprecated` was stabilized. The `deprecated` attribute cannot be used in a -`staged_api` crate, `rustc_deprecated` must be used instead. The deprecated -item must also have a `stable` or `unstable` attribute. +Deprecations in the standard library are nearly identical to deprecations in +user code. When `#[deprecated]` is used on an item, it must also have a `stable` +or `unstable `attribute. -`rustc_deprecated` has the following form: +`deprecated` has the following form: ```rust,ignore -#[rustc_deprecated( +#[deprecated( since = "1.38.0", - reason = "explanation for deprecation", + note = "explanation for deprecation", suggestion = "other_function" )] ``` @@ -146,13 +143,13 @@ item must also have a `stable` or `unstable` attribute. The `suggestion` field is optional. If given, it should be a string that can be used as a machine-applicable suggestion to correct the warning. This is typically used when the identifier is renamed, but no other significant changes -are necessary. +are necessary. When the `suggestion` field is used, you need to have +`#![feature(deprecated_suggestion)]` at the crate root. -Another difference from the `deprecated` attribute is that the `since` field is -actually checked against the current version of `rustc`. If `since` is in a -future version, then the `deprecated_in_future` lint is triggered which is -default `allow`, but most of the standard library raises it to a warning with +Another difference from user code is that the `since` field is actually checked +against the current version of `rustc`. If `since` is in a future version, then +the `deprecated_in_future` lint is triggered which is default `allow`, but most +of the standard library raises it to a warning with `#![warn(deprecated_in_future)]`. -[`deprecated` attribute]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute [blog]: https://www.ralfj.de/blog/2018/07/19/const.html diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index 7e147c9ceb..a3d37a37c5 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -501,23 +501,22 @@ To run the tests in a different mode, you need to pass the `--compare-mode` CLI flag: ```bash -./x.py test src/test/ui --compare-mode=nll +./x.py test src/test/ui --compare-mode=chalk ``` The possible compare modes are: -* `nll` — Runs in the "true" NLL mode with `-Zborrowck=mir`. - See [UI compare modes](ui.md#compare-modes) for more. -* `polonius` — Runs with Polonius with `-Zpolonius -Zborrowck=mir`, and reuses - the `nll` stderr files. +* `polonius` — Runs with Polonius with `-Zpolonius`. * `chalk` — Runs with Chalk with `-Zchalk`. * `split-dwarf` — Runs with unpacked split-DWARF with `-Csplit-debuginfo=unpacked`. * `split-dwarf-single` — Runs with packed split-DWARF with `-Csplit-debuginfo=packed`. +See [UI compare modes](ui.md#compare-modes) for more information about how UI +tests support different output for different modes. + In CI, compare modes are only used in one Linux builder, and only with the following settings: -* `src/test/ui`: Uses `nll` mode. * `src/test/debuginfo`: Uses `split-dwarf` mode. This helps ensure that none of the debuginfo tests are affected when enabling split-DWARF. diff --git a/src/doc/rustc-dev-guide/src/tests/docker.md b/src/doc/rustc-dev-guide/src/tests/docker.md index 29837dfea4..feb614c519 100644 --- a/src/doc/rustc-dev-guide/src/tests/docker.md +++ b/src/doc/rustc-dev-guide/src/tests/docker.md @@ -8,7 +8,7 @@ build Rust within the image, and run the tests. You can run these images on your local development machine. This can be helpful to test environments different from your local system. First you will need to install Docker on a Linux, Windows, or macOS system (typically Linux -will be much faster than Windows or macOS because the later use virtual +will be much faster than Windows or macOS because the latter use virtual machines to emulate a Linux environment). To enter interactive mode which will start a bash shell in the container, run `src/ci/docker/run.sh --dev ` where `` is one of the directory names in `src/ci/docker` (for example diff --git a/src/doc/rustc-dev-guide/src/tests/headers.md b/src/doc/rustc-dev-guide/src/tests/headers.md index bdbe0a14ea..bfa637f348 100644 --- a/src/doc/rustc-dev-guide/src/tests/headers.md +++ b/src/doc/rustc-dev-guide/src/tests/headers.md @@ -125,7 +125,7 @@ Some examples of `X` in `ignore-X` or `only-X`: * When [remote testing] is used: `remote` * When debug-assertions are enabled: `debug` * When particular debuggers are being tested: `cdb`, `gdb`, `lldb` -* Specific [compare modes]: `compare-mode-nll`, `compare-mode-polonius`, +* Specific [compare modes]: `compare-mode-polonius`, `compare-mode-chalk`, `compare-mode-split-dwarf`, `compare-mode-split-dwarf-single` diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md index 2e823c0edd..5d8417188d 100644 --- a/src/doc/rustc-dev-guide/src/tests/running.md +++ b/src/doc/rustc-dev-guide/src/tests/running.md @@ -196,13 +196,13 @@ of the `build` directory from time to time. ## Running tests with different "compare modes" UI tests may have different output depending on certain "modes" that -the compiler is in. For example, when in "non-lexical lifetimes" (NLL) -mode a test `foo.rs` will first look for expected output in -`foo.nll.stderr`, falling back to the usual `foo.stderr` if not found. -To run the UI test suite in NLL mode, one would use the following: +the compiler is in. For example, when using the Polonius +mode, a test `foo.rs` will first look for expected output in +`foo.polonius.stderr`, falling back to the usual `foo.stderr` if not found. +The following will run the UI test suite in Polonius mode: ```bash -./x.py test src/test/ui --compare-mode=nll +./x.py test src/test/ui --compare-mode=polonius ``` See [Compare modes](compiletest.md#compare-modes) for more details. @@ -211,7 +211,7 @@ See [Compare modes](compiletest.md#compare-modes) for more details. Sometimes it's easier and faster to just run the test by hand. Most tests are just `rs` files, so after -[creating a rustup toolchain](/building/how-to-build-and-run.html#creating-a-rustup-toolchain), +[creating a rustup toolchain](../building/how-to-build-and-run.md#creating-a-rustup-toolchain), you can do something like: ```bash diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index c1c1051418..1baa447a0c 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -74,7 +74,7 @@ The general form is: * `32bit.stderr` — compiler stderr with `stderr-per-bitwidth` header on a 32-bit target A simple example would be `foo.stderr` next to a `foo.rs` test. -A more complex example would be `foo.my-revision.nll.stderr`. +A more complex example would be `foo.my-revision.polonius.stderr`. There are several [headers](headers.md) which will change how compiletest will check for output files: @@ -496,12 +496,11 @@ In some cases, this might result in different output from the compiler. To support this, different output files can be saved which contain the output based on the compare mode. -For example, when in "non-lexical lifetimes" (NLL) mode a test `foo.rs` will -first look for expected output in `foo.nll.stderr`, falling back to the usual +For example, when using the Polonius mode, a test `foo.rs` will +first look for expected output in `foo.polonius.stderr`, falling back to the usual `foo.stderr` if not found. -This is useful as "true" NLL mode can sometimes result in different -diagnostics and behavior compared to the "migrate mode" NLL (which is the -current default). +This is useful as different modes can sometimes result in different +diagnostics and behavior. This can help track which tests have differences between the modes, and to visually inspect those diagnostic differences. @@ -509,7 +508,7 @@ If in the rare case you encounter a test that has different behavior, you can run something like the following to generate the alternate stderr file: ```sh -./x.py test src/test/ui --compare-mode=nll --bless +./x.py test src/test/ui --compare-mode=polonius --bless ``` -Currently, only `nll` mode is checked in CI for UI tests. +Currently none of the compare modes are checked in CI for UI tests. diff --git a/src/doc/rustc-dev-guide/src/tracing.md b/src/doc/rustc-dev-guide/src/tracing.md index 63d68e5412..0bba73f743 100644 --- a/src/doc/rustc-dev-guide/src/tracing.md +++ b/src/doc/rustc-dev-guide/src/tracing.md @@ -60,6 +60,30 @@ still get a short message per ignored `do_mir_borrowck`, but none of the things calls. This helps you in looking through the calls that are happening and helps you adjust your regex if you mistyped it. +## Query level filters + +Every [query](query.md) is automatically tagged with a logging span so that +you can display all log messages during the execution of the query. For +example, if you want to log everything during type checking: + +``` +RUSTC_LOG=[typeck] +``` + +The query arguments are included as a tracing field which means that you can +filter on the debug display of the arguments. For example, the `typeck` query +has an argument `key: LocalDefId` of what is being checked. You can use a +regex to match on that `LocalDefId` to log type checking for a specific +function: + +``` +RUSTC_LOG=[typeck{key=.*name_of_item.*}] +``` + +Different queries have different arguments. You can find a list of queries and +their arguments in +[`rustc_middle/src/query/mod.rs`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/query/mod.rs#L18). + ## Broad module level filters You can also use filters similar to the `log` crate's filters, which will enable diff --git a/src/doc/rustc-dev-guide/src/traits/chalk.md b/src/doc/rustc-dev-guide/src/traits/chalk.md index db3c19a386..d4045c460c 100644 --- a/src/doc/rustc-dev-guide/src/traits/chalk.md +++ b/src/doc/rustc-dev-guide/src/traits/chalk.md @@ -1,13 +1,14 @@ # Chalk-based trait solving [Chalk][chalk] is an experimental trait solver for Rust that is (as of January 2021) under development by the [Traits Working -Group][wg]. Its goal is to enable a lot of trait system features and bug fixes +date: 2022-05 --> May 2022) under development by the [Types team]. +Its goal is to enable a lot of trait system features and bug fixes that are hard to implement (e.g. GATs or specialization). If you would like to -help in hacking on the new solver, you will find instructions for getting -involved in the [Traits Working Group tracking issue][wg]. +help in hacking on the new solver, drop by on the rust-lang Zulip in the [`#t-types`] +stream and say hello! -[wg]: https://github.com/rust-lang/rust/issues/48416 +[Types team]: https://github.com/rust-lang/types-team +[`#t-types`]: https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types The new-style trait solver is based on the work done in [chalk][chalk]. Chalk recasts Rust's trait system explicitly in terms of logic programming. It does diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md index 70b53e9105..c22ee6de61 100644 --- a/src/doc/rustc-dev-guide/src/traits/resolution.md +++ b/src/doc/rustc-dev-guide/src/traits/resolution.md @@ -120,7 +120,7 @@ the obligation contains unbound inference variables. The subroutines that decide whether a particular impl/where-clause/etc applies to a particular obligation are collectively referred to as the process of -_matching_. As of January 2021, this amounts to unifying +_matching_. As of May 2022, this amounts to unifying the `Self` types, but in the future we may also recursively consider some of the nested obligations, in the case of an impl. diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index c2d44ac0e4..87dc513853 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -1,37 +1,40 @@ # The Rustc Book - [What is rustc?](what-is-rustc.md) -- [Command-line arguments](command-line-arguments.md) +- [Command-line Arguments](command-line-arguments.md) + - [Codegen Options](codegen-options/index.md) - [Lints](lints/index.md) - - [Lint levels](lints/levels.md) + - [Lint Levels](lints/levels.md) - [Lint Groups](lints/groups.md) - - [Lint listing](lints/listing/index.md) - - [Allowed-by-default lints](lints/listing/allowed-by-default.md) - - [Warn-by-default lints](lints/listing/warn-by-default.md) - - [Deny-by-default lints](lints/listing/deny-by-default.md) -- [Codegen options](codegen-options/index.md) + - [Lint Listing](lints/listing/index.md) + - [Allowed-by-default Lints](lints/listing/allowed-by-default.md) + - [Warn-by-default Lints](lints/listing/warn-by-default.md) + - [Deny-by-default Lints](lints/listing/deny-by-default.md) - [JSON Output](json.md) - [Tests](tests/index.md) - [Platform Support](platform-support.md) - - [Template for target-specific documentation](platform-support/TEMPLATE.md) + - [Target Tier Policy](target-tier-policy.md) + - [Template for Target-specific Documentation](platform-support/TEMPLATE.md) - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md) + - [\*-apple-watchos\*](platform-support/apple-watchos.md) + - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md) - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md) + - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) - [*-unknown-openbsd](platform-support/openbsd.md) - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) -- [Target Tier Policy](target-tier-policy.md) - [Targets](targets/index.md) - [Built-in Targets](targets/built-in.md) - [Custom Targets](targets/custom.md) - [Known Issues](targets/known-issues.md) - [Profile-guided Optimization](profile-guided-optimization.md) - [Instrumentation-based Code Coverage](instrument-coverage.md) -- [Linker-plugin based LTO](linker-plugin-lto.md) +- [Linker-plugin-based LTO](linker-plugin-lto.md) - [Exploit Mitigations](exploit-mitigations.md) - [Contributing to `rustc`](contributing.md) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 02011325d6..b1c3b618ce 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -1,4 +1,4 @@ -# Codegen options +# Codegen Options All of these options are passed to `rustc` via the `-C` flag, short for "codegen." You can see a version of this list for your exact compiler by running `rustc -C help`. diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 0d02fa7bd6..f05ff3f1b6 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -1,4 +1,4 @@ -# Command-line arguments +# Command-line Arguments Here's a list of command-line arguments to `rustc` and what they do. @@ -52,7 +52,8 @@ where `KIND` may be one of: If the kind is specified, then linking modifiers can be attached to it. Modifiers are specified as a comma-delimited string with each modifier prefixed with either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively. -The last boolean value specified for a given modifier wins. \ +Specifying multiple `modifiers` arguments in a single `link` attribute, +or multiple identical modifiers in the same `modifiers` argument is not currently supported. \ Example: `-l static:+whole-archive=mylib`. The kind of library and the modifiers can also be specified in a [`#[link]` @@ -83,6 +84,26 @@ The default for this modifier is `-whole-archive`. \ NOTE: The default may currently be different in some cases for backward compatibility, but it is not guaranteed. If you need whole archive semantics use `+whole-archive` explicitly. +### Linking modifiers: `bundle` + +This modifier is only compatible with the `static` linking kind. +Using any other kind will result in a compiler error. + +When building a rlib or staticlib `+bundle` means that the native static library +will be packed into the rlib or staticlib archive, and then retrieved from there +during linking of the final binary. + +When building a rlib `-bundle` means that the native static library is registered as a dependency +of that rlib "by name", and object files from it are included only during linking of the final +binary, the file search by that name is also performed during final linking. \ +When building a staticlib `-bundle` means that the native static library is simply not included +into the archive and some higher level build system will need to add it later during linking of +the final binary. + +This modifier has no effect when building other targets like executables or dynamic libraries. + +The default for this modifier is `+bundle`. + ## `--crate-type`: a list of types of crates for the compiler to emit diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index 108b0ffe99..0ae9e53af3 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -1,4 +1,4 @@ -# `instrument-coverage` +# Instrumentation-based Code Coverage ## Introduction diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md index e7bf8d9a36..9c644dd404 100644 --- a/src/doc/rustc/src/linker-plugin-lto.md +++ b/src/doc/rustc/src/linker-plugin-lto.md @@ -1,4 +1,4 @@ -# Linker-plugin-LTO +# Linker-plugin-based LTO The `-C linker-plugin-lto` flag allows for deferring the LTO optimization to the actual linking step, which in turn allows for performing diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index fbec3cd9ba..93892d6ade 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -1,4 +1,4 @@ -# Lint levels +# Lint Levels In `rustc`, lints are divided into five *levels*: diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md index 95dd60bebf..8c4c0b9c55 100644 --- a/src/doc/rustc/src/lints/listing/allowed-by-default.md +++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md @@ -1,3 +1,3 @@ -# Allowed-by-default lints +# Allowed-by-default Lints This file is auto-generated by the lint-docs script. diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index 3c1452d646..12f511423b 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -1,3 +1,3 @@ -# Deny-by-default lints +# Deny-by-default Lints This file is auto-generated by the lint-docs script. diff --git a/src/doc/rustc/src/lints/listing/index.md b/src/doc/rustc/src/lints/listing/index.md index 97aa2caf91..791a80274e 100644 --- a/src/doc/rustc/src/lints/listing/index.md +++ b/src/doc/rustc/src/lints/listing/index.md @@ -1,4 +1,4 @@ -# Lint listing +# Lint Listing This section lists out all of the lints, grouped by their default lint levels. diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md index eebc022a82..84d67764f7 100644 --- a/src/doc/rustc/src/lints/listing/warn-by-default.md +++ b/src/doc/rustc/src/lints/listing/warn-by-default.md @@ -1,3 +1,3 @@ -# Warn-by-default lints +# Warn-by-default Lints This file is auto-generated by the lint-docs script. diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ab98651a1e..eb98580326 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -207,6 +207,7 @@ target | std | host | notes -------|:---:|:----:|------- `aarch64-apple-ios-macabi` | ? | | Apple Catalyst on ARM64 `aarch64-apple-tvos` | * | | ARM64 tvOS +[`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD @@ -220,11 +221,12 @@ target | std | host | notes `aarch64-wrs-vxworks` | ? | | `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) +[`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM Apple WatchOS 64-bit with 32-bit pointers `armv4t-unknown-linux-gnueabi` | ? | | `armv5te-unknown-linux-uclibceabi` | ? | | ARMv5TE Linux with uClibc `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD `armv6-unknown-netbsd-eabihf` | ? | | -`armv6k-nintendo-3ds` | * | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain) +[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain) `armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8 [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7 Linux with uClibc, softfloat [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux with uClibc, hardfloat @@ -234,6 +236,7 @@ target | std | host | notes [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3, hardfloat `armv7a-none-eabihf` | * | | ARM Cortex-A, hardfloat +[`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM Apple WatchOS `armv7s-apple-ios` | ✓ | | `avr-unknown-gnu-atmega328` | * | | AVR. Requires `-Z build-std=core` `bpfeb-unknown-none` | * | | BPF (big endian) @@ -275,6 +278,7 @@ target | std | host | notes `riscv32gc-unknown-linux-gnu` | | | RISC-V Linux (kernel 5.4, glibc 2.33) `riscv32gc-unknown-linux-musl` | | | RISC-V Linux (kernel 5.4, musl + RISCV32 support patches) `riscv32im-unknown-none-elf` | * | | Bare RISC-V (RV32IM ISA) +[`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) `riscv32imc-esp-espidf` | ✓ | | RISC-V ESP-IDF `riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD `riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.0) @@ -289,6 +293,7 @@ target | std | host | notes [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly `x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64 `x86_64-apple-tvos` | * | | x86 64-bit tvOS +[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `x86_64-pc-windows-msvc` | * | | 64-bit Windows XP support `x86_64-sun-solaris` | ? | | Deprecated target for 64-bit Solaris 10/11, illumos diff --git a/src/doc/rustc/src/platform-support/apple-watchos.md b/src/doc/rustc/src/platform-support/apple-watchos.md new file mode 100644 index 0000000000..fe4c7c0c88 --- /dev/null +++ b/src/doc/rustc/src/platform-support/apple-watchos.md @@ -0,0 +1,55 @@ +# *-apple-watchos +- arm64_32-apple-watchos +- armv7k-apple-watchos +- aarch64-apple-watchos-sim +- x86_64-apple-watchos-sim + +**Tier: 3** + +Apple WatchOS targets: +- Apple WatchOS on Arm 64_32 +- Apple WatchOS on Arm v7k +- Apple WatchOS Simulator on arm64 +- Apple WatchOS Simulator on x86_64 + +## Target maintainers + +* [@deg4uss3r](https://github.com/deg4uss3r) +* [@vladimir-ea](https://github.com/vladimir-ea) + +## Requirements + +These targets are cross-compiled. +To build these targets Xcode 12 or higher on macOS is required. + +## Building the target + +The targets can be built by enabling them for a `rustc` build, for example: + +```toml +[build] +build-stage = 1 +target = ["aarch64-apple-watchos-sim"] +``` + +## Building Rust programs + +*Note: Building for this target requires the corresponding WatchOS SDK, as provided by Xcode 12+.* + +Rust programs can be built for these targets, if `rustc` has been built with support for them, for example: + +```text +rustc --target aarch64-apple-watchos-sim your-code.rs +``` + +## Testing + +There is no support for running the Rust testsuite on WatchOS or the simulators. + +There is no easy way to run simple programs on WatchOS or the WatchOS simulators. Static library builds can be embedded into WatchOS applications. + +## Cross-compilation toolchains and C code + +This target can be cross-compiled from x86_64 or aarch64 macOS hosts. + +Other hosts are not supported for cross-compilation, but might work when also providing the required Xcode SDK. diff --git a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md new file mode 100644 index 0000000000..215290e389 --- /dev/null +++ b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md @@ -0,0 +1,130 @@ +# `armv6k-nintendo-3ds` + +**Tier: 3** + +The Nintendo 3DS platform, which has an ARMv6K processor, and its associated +operating system (`horizon`). + +Rust support for this target is not affiliated with Nintendo, and is not derived +from nor used with any official Nintendo SDK. + +## Target maintainers + +- [@Meziu](https://github.com/Meziu) +- [@AzureMarker](https://github.com/AzureMarker) +- [@ian-h-chamberlain](https://github.com/ian-h-chamberlain) + +## Requirements + +This target is cross-compiled. Dynamic linking is not supported. + +`#![no_std]` crates can be built using `build-std` to build `core` and optionally +`alloc`, and either `panic_abort` or `panic_unwind`. + +`std` is partially supported, but mostly works. Some APIs are unimplemented +and will simply return an error, such as `std::process`. An allocator is provided +by default. + +In order to support some APIs, binaries must be linked against `libc` written +for the target, using a linker for the target. These are provided by the +devkitARM toolchain. See +[Cross-compilation toolchains and C code](#cross-compilation-toolchains-and-c-code) +for more details. + +Additionally, some helper crates provide implementations of some `libc` functions +use by `std` that may otherwise be missing. These, or an alternate implementation +of the relevant functions, are required to use `std`: + +- [`pthread-3ds`](https://github.com/Meziu/pthread-3ds) provides pthread APIs for `std::thread`. +- [`linker-fix-3ds`](https://github.com/Meziu/rust-linker-fix-3ds) fulfills some other missing libc APIs. + +Binaries built for this target should be compatible with all variants of the +3DS (and 2DS) hardware and firmware, but testing is limited and some versions may +not work correctly. + +This target generates binaries in the ELF format. + +## Building the target + +You can build Rust with support for the target by adding it to the `target` +list in `config.toml` and providing paths to the devkitARM toolchain. + +```toml +[build] +build-stage = 1 +target = ["armv6k-nintendo-3ds"] + +[target.armv6k-nintendo-3ds] +cc = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-gcc" +cxx = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-g++" +ar = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-ar" +ranlib = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-ranlib" +linker = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-gcc" +``` + +Also, to build `compiler_builtins` for the target, export these flags before +building the Rust toolchain: + +```sh +export CFLAGS_armv6k_nintendo_3ds="-mfloat-abi=hard -mtune=mpcore -mtp=soft -march=armv6k" +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. + +The recommended way to build binaries is by using the +[cargo-3ds](https://github.com/Meziu/cargo-3ds) tool, which uses `build-std` +and provides commands that work like the usual `cargo run`, `cargo build`, etc. + +You can also build Rust with the target enabled (see +[Building the target](#building-the-target) above). + +As mentioned in [Requirements](#requirements), programs that use `std` must link +against both the devkitARM toolchain and libraries providing the `libc` APIs used +in `std`. There is a general-purpose utility crate for working with nonstandard +APIs provided by the OS: [`ctru-rs`](https://github.com/Meziu/ctru-rs). +Add it to Cargo.toml to use it in your program: + +```toml +[dependencies] +ctru-rs = { git = "https://github.com/Meziu/ctru-rs.git" } +``` + +Using this library's `init()` function ensures the symbols needed to link +against `std` are present (as mentioned in [Requirements](#requirements) +above), as well as providing a runtime suitable for `std`: + +```rust,ignore (requires-3rd-party-library) +fn main() { + ctru::init(); +} +``` + +## Testing + +Binaries built for this target can be run in an emulator (most commonly +[Citra](https://citra-emu.org/)), or sent to a device through +the use of a tool like devkitARM's `3dslink`. They may also simply be copied +to an SD card to be inserted in the device. + +The `cargo-3ds` tool mentioned in [Building Rust programs](#building-rust-programs) +supports the use of `3dslink` with `cargo 3ds run`. The default Rust test runner +is not supported, but +[custom test frameworks](https://doc.rust-lang.org/beta/unstable-book/language-features/custom-test-frameworks.html) +can be used with `cargo 3ds test` to run unit tests on a device. + +The Rust test suite for `library/std` is not yet supported. + +## Cross-compilation toolchains and C code + +C code can be built for this target using the +[devkitARM toolchain](https://devkitpro.org/wiki/Getting_Started). +This toolchain provides `arm-none-eabi-gcc` as the linker used to link Rust +programs as well. + +The toolchain also provides a `libc` implementation, which is required by `std` +for many of its APIs, and a helper library `libctru` which is used by several +of the helper crates listed in [Requirements](#requirements). +This toolchain does not, however, include all of the APIs expected by `std`, +and the remaining APIs are implemented by `pthread-3ds` and `linker-fix-3ds`. diff --git a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md b/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md index 96ae065b31..721c234c6e 100644 --- a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md +++ b/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md @@ -4,7 +4,7 @@ Windows targets similar to `*-pc-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of GCC/Binutils. -Target triples avaiable so far: +Target triples available so far: - `aarch64-pc-windows-gnullvm` - `x86_64-pc-windows-gnullvm` @@ -26,7 +26,7 @@ Like with any other Windows target created binaries are in PE format. ## Building the target For cross-compilation I recommend using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain, one change that seems necessary beside configuring corss compilers is disabling experimental `m86k` target. Otherwise LLVM build fails with `multiple definition ...` errors. -Native bootstrapping builds require rather fragile hacks until host artifacts are avaiable so I won't describe them here. +Native bootstrapping builds require rather fragile hacks until host artifacts are available so I won't describe them here. ## Building Rust programs diff --git a/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md b/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md new file mode 100644 index 0000000000..f024cd25bf --- /dev/null +++ b/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md @@ -0,0 +1,50 @@ +# riscv32imac-unknown-xous-elf + +**Tier: 3** + +Xous microkernel, message-based operating system that powers devices such as Precursor and Betrusted. The operating system is written entirely in Rust, so no additional software is required to compile programs for Xous. + +## Target maintainers + +- [@xobs](https://github.com/xobs) + +## Requirements + + +Building the target itself requires a RISC-V compiler that is supported by `cc-rs`. For example, you can use the prebuilt [xPack](https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/latest) toolchain. + +Cross-compiling programs does not require any additional software beyond the toolchain. Prebuilt versions of the toolchain are available [from Betrusted](https://github.com/betrusted-io/rust/releases). + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["riscv32imac-unknown-xous-elf"] +``` + +Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`: + +```toml +[target.riscv32imac-unknown-xous-elf] +cc = "riscv-none-elf-gcc" +ar = "riscv-none-elf-ar" +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will need to do one of the following: + +* Build Rust with the target enabled (see "Building the target" above) +* Build your own copy of `core` by using `build-std` or similar +* Download a prebuilt toolchain [from Betrusted](https://github.com/betrusted-io/rust/releases) + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +Currently there is no support to run the rustc test suite for this target. diff --git a/src/doc/rustc/src/profile-guided-optimization.md b/src/doc/rustc/src/profile-guided-optimization.md index d066f4a9cf..d9cf7ce30f 100644 --- a/src/doc/rustc/src/profile-guided-optimization.md +++ b/src/doc/rustc/src/profile-guided-optimization.md @@ -1,4 +1,4 @@ -# Profile Guided Optimization +# Profile-guided Optimization `rustc` supports doing profile-guided optimization (PGO). This chapter describes what PGO is, what it is good for, and how it can be used. diff --git a/src/doc/rustdoc/src/how-to-read-rustdoc.md b/src/doc/rustdoc/src/how-to-read-rustdoc.md index 098bc1879b..d666d54b31 100644 --- a/src/doc/rustdoc/src/how-to-read-rustdoc.md +++ b/src/doc/rustdoc/src/how-to-read-rustdoc.md @@ -59,15 +59,8 @@ or the current item whose documentation is being displayed. ## The Theme Picker and Search Interface When viewing `rustdoc`'s output in a browser with JavaScript enabled, -a dynamic interface appears at the top of the page. -To the left is the theme picker, denoted with a paint-brush icon, -and the search interface, help screen, and options appear to the right of that. - -### The Theme Picker - -Clicking on the theme picker provides a list of themes - -by default `ayu`, `light`, and `dark` - -which are available for viewing. +a dynamic interface appears at the top of the page composed of the search +interface, help screen, and options. ### The Search Interface @@ -91,12 +84,16 @@ When typing in the search bar, you can prefix your search term with a type followed by a colon (such as `mod:`) to restrict the results to just that kind of item. (The available items are listed in the help popup.) +### Changing displayed theme + +You can change the displayed theme by opening the settings menu (the gear +icon in the upper right) and then pick a new one from there. + ### Shortcuts Pressing `S` while focused elsewhere on the page will move focus to the search bar, and pressing `?` shows the help screen, which includes all these shortcuts and more. -Pressing `T` focuses the theme picker. When the search results are focused, the left and right arrows move between tabs and the up and down arrows move diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md index 25ef8b5bb9..e3b0864899 100644 --- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md +++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md @@ -87,7 +87,9 @@ on your documentation examples make requests to. #![doc(html_playground_url = "https://playground.example.com/")] ``` -Now, when you press "run", the button will make a request to this domain. +Now, when you press "run", the button will make a request to this domain. The request +URL will contain 2 query parameters: `code` and `edition` for the code in the documentation +and the Rust edition respectively. If you don't use this attribute, there will be no run buttons. diff --git a/src/doc/rustdoc/src/write-documentation/what-to-include.md b/src/doc/rustdoc/src/write-documentation/what-to-include.md index 35e6ccbc38..e1e09aa4a8 100644 --- a/src/doc/rustdoc/src/write-documentation/what-to-include.md +++ b/src/doc/rustdoc/src/write-documentation/what-to-include.md @@ -109,8 +109,9 @@ rustdoc --extend-css custom.css src/lib.rs A good example of using this feature to create a dark theme is documented [on this blog]. Just remember, dark theme is already included in the rustdoc output -by clicking on the paintbrush. Adding additional options to the themes are -as easy as creating a custom theme `.css` file and using the following syntax: +by clicking on the gear icon in the upper right. Adding additional options to the +themes are as easy as creating a custom theme `.css` file and using the following +syntax: ```bash rustdoc --theme awesome.css src/lib.rs diff --git a/src/doc/unstable-book/src/compiler-flags/extern-options.md b/src/doc/unstable-book/src/compiler-flags/extern-options.md new file mode 100644 index 0000000000..858eee5d2c --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/extern-options.md @@ -0,0 +1,22 @@ +# `--extern` Options + +The behavior of the `--extern` flag can be modified with `noprelude`, `priv` or `nounused` options. + +This is unstable feature, so you have to provide `-Zunstable-options` to enable it. + +## Examples + +Use your own build of the `core` crate. + +`rustc main.rs -Z unstable-options --extern noprelude:core=libcore.rlib` + +To use multiple options, separate them with a comma: + +`rustc main.rs -Z unstable-options --extern noprelude,priv,nounused:mydep=mydep.rlib` + +## Options + +* `noprelude`: Do not add the crate to the external prelude. If used, it will need to be imported using `extern crate`. + This is used by the [build-std project](https://github.com/rust-lang/wg-cargo-std-aware/) to simulate compatibility with sysroot-only crates. +* `priv`: Mark the crate as a private dependency for the [`exported_private_dependencies`](../../rustc/lints/listing/warn-by-default.html#exported-private-dependencies) lint. +* `nounused`: Suppress [`unused-crate-dependencies`](../../rustc/lints/listing/allowed-by-default.html#unused-crate-dependencies) warnings for the crate. diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 3f60caffef..e83c4d98cc 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -22,7 +22,10 @@ This feature allows for use of one of following sanitizers: To enable a sanitizer compile with `-Zsanitizer=address`,`-Zsanitizer=cfi`, `-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, `-Zsanitizer=memory`, -`-Zsanitizer=memtag`, or `-Zsanitizer=thread`. +`-Zsanitizer=memtag`, or `-Zsanitizer=thread`. You might also need the `--target` and `build-std` flags. Example: +```shell +$ RUSTFLAGS=-Zsanitizer=address cargo build -Zbuild-std --target x86_64-unknown-linux-gnu +``` # AddressSanitizer diff --git a/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md b/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md new file mode 100644 index 0000000000..c6516d838d --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/virtual-function-elimination.md @@ -0,0 +1,39 @@ +# `virtual-function-elimination` + +This option controls whether LLVM runs the Virtual Function Elimination (VFE) +optimization. This optimization in only available with LTO, so this flag can +only be passed if [`-Clto`][Clto] is also passed. + +VFE makes it possible to remove functions from vtables that are never +dynamically called by the rest of the code. Without this flag, LLVM makes the +really conservative assumption, that if any function in a vtable is called, no +function that is referenced by this vtable can be removed. With this flag +additional information are given to LLVM, so that it can determine which +functions are actually called and remove the unused functions. + +## Limitations + +At the time of writing this flag may remove vtable functions too eagerly. One +such example is in this code: + +```rust +trait Foo { fn foo(&self) { println!("foo") } } + +impl Foo for usize {} + +pub struct FooBox(Box); + +pub fn make_foo() -> FooBox { FooBox(Box::new(0)) } + +#[inline] +pub fn f(a: FooBox) { a.0.foo() } +``` + +In the above code the `Foo` trait is private, so an assumption is made that its +functions can only be seen/called from the current crate and can therefore get +optimized out, if unused. However, with `make_foo` you can produce a wrapped +`dyn Foo` type outside of the current crate, which can then be used in `f`. Due +to inlining of `f`, `Foo::foo` can then be called from a foreign crate. This can +lead to miscompilations. + +[Clto]: https://doc.rust-lang.org/rustc/codegen-options/index.html#lto diff --git a/src/doc/unstable-book/src/language-features/crate-visibility-modifier.md b/src/doc/unstable-book/src/language-features/crate-visibility-modifier.md deleted file mode 100644 index b59859dd34..0000000000 --- a/src/doc/unstable-book/src/language-features/crate-visibility-modifier.md +++ /dev/null @@ -1,20 +0,0 @@ -# `crate_visibility_modifier` - -The tracking issue for this feature is: [#53120] - -[#53120]: https://github.com/rust-lang/rust/issues/53120 - ------ - -The `crate_visibility_modifier` feature allows the `crate` keyword to be used -as a visibility modifier synonymous to `pub(crate)`, indicating that a type -(function, _&c._) is to be visible to the entire enclosing crate, but not to -other crates. - -```rust -#![feature(crate_visibility_modifier)] - -crate struct Foo { - bar: usize, -} -``` diff --git a/src/doc/unstable-book/src/language-features/debugger-visualizer.md b/src/doc/unstable-book/src/language-features/debugger-visualizer.md index 4ab482fffb..c7a0414b67 100644 --- a/src/doc/unstable-book/src/language-features/debugger-visualizer.md +++ b/src/doc/unstable-book/src/language-features/debugger-visualizer.md @@ -14,6 +14,7 @@ to embed a debugger visualizer file into the PDB/ELF generated by `rustc`. ``` rust,ignore (partial-example) #![feature(debugger_visualizer)] #![debugger_visualizer(natvis_file = "foo.natvis")] +#![debugger_visualizer(gdb_script_file = "foo.py")] struct Foo { } @@ -22,4 +23,5 @@ struct Foo { ## Limitations Currently, this feature only supports embedding Natvis files on `-windows-msvc` -targets when using the MSVC linker via the `natvis_file` meta item. +targets via the `natvis_file` meta item. `-windows-gnu` targets are not currently +supported. diff --git a/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md b/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md deleted file mode 100644 index 479571d85f..0000000000 --- a/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md +++ /dev/null @@ -1,53 +0,0 @@ -# `explicit_generic_args_with_impl_trait` - -The tracking issue for this feature is: [#83701] - -[#83701]: https://github.com/rust-lang/rust/issues/83701 - ------------------------- - -The `explicit_generic_args_with_impl_trait` feature gate lets you specify generic arguments even -when `impl Trait` is used in argument position. - -A simple example is: - -```rust -#![feature(explicit_generic_args_with_impl_trait)] - -fn foo(_f: impl AsRef) {} - -fn main() { - foo::("".to_string()); -} -``` - -This is currently rejected: - -```text -error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position - --> src/main.rs:6:11 - | -6 | foo::("".to_string()); - | ^^^ explicit generic argument not allowed - -``` - -However it would compile if `explicit_generic_args_with_impl_trait` is enabled. - -Note that the synthetic type parameters from `impl Trait` are still implicit and you -cannot explicitly specify these: - -```rust,compile_fail -#![feature(explicit_generic_args_with_impl_trait)] - -fn foo(_f: impl AsRef) {} -fn bar>(_f: F) {} - -fn main() { - bar::("".to_string()); // Okay - bar::("".to_string()); // Okay - - foo::("".to_string()); // Okay - foo::("".to_string()); // Error, you cannot specify `impl Trait` explicitly -} -``` diff --git a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md deleted file mode 100644 index 5f3f1b4dd8..0000000000 --- a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md +++ /dev/null @@ -1,44 +0,0 @@ -# `infer_static_outlives_requirements` - -The tracking issue for this feature is: [#54185] - -[#54185]: https://github.com/rust-lang/rust/issues/54185 - ------------------------- -The `infer_static_outlives_requirements` feature indicates that certain -`'static` outlives requirements can be inferred by the compiler rather than -stating them explicitly. - -Note: It is an accompanying feature to `infer_outlives_requirements`, -which must be enabled to infer outlives requirements. - -For example, currently generic struct definitions that contain -references, require where-clauses of the form T: 'static. By using -this feature the outlives predicates will be inferred, although -they may still be written explicitly. - -```rust,ignore (pseudo-Rust) -struct Foo where U: 'static { // <-- currently required - bar: Bar -} -struct Bar { - x: T, -} -``` - - -## Examples: - -```rust,ignore (pseudo-Rust) -#![feature(infer_outlives_requirements)] -#![feature(infer_static_outlives_requirements)] - -#[rustc_outlives] -// Implicitly infer U: 'static -struct Foo { - bar: Bar -} -struct Bar { - x: T, -} -``` diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md index 86bedb5153..39238dffa1 100644 --- a/src/doc/unstable-book/src/language-features/lang-items.md +++ b/src/doc/unstable-book/src/language-features/lang-items.md @@ -23,8 +23,10 @@ use core::panic::PanicInfo; extern crate libc; +struct Unique(*mut T); + #[lang = "owned_box"] -pub struct Box(*mut T); +pub struct Box(Unique); #[lang = "exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { diff --git a/src/doc/unstable-book/src/language-features/native-link-modifiers-bundle.md b/src/doc/unstable-book/src/language-features/native-link-modifiers-bundle.md deleted file mode 100644 index ac192cff13..0000000000 --- a/src/doc/unstable-book/src/language-features/native-link-modifiers-bundle.md +++ /dev/null @@ -1,19 +0,0 @@ -# `native_link_modifiers_bundle` - -The tracking issue for this feature is: [#81490] - -[#81490]: https://github.com/rust-lang/rust/issues/81490 - ------------------------- - -The `native_link_modifiers_bundle` feature allows you to use the `bundle` modifier. - -Only compatible with the `static` linking kind. Using any other kind will result in a compiler error. - -`+bundle` means objects from the static library are bundled into the produced crate (a rlib, for example) and are used from this crate later during linking of the final binary. - -`-bundle` means the static library is included into the produced rlib "by name" and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking. - -This modifier is supposed to supersede the `static-nobundle` linking kind defined by [RFC 1717](https://github.com/rust-lang/rfcs/pull/1717). - -The default for this modifier is currently `+bundle`, but it could be changed later on some future edition boundary. diff --git a/src/etc/cpu-usage-over-time-plot.sh b/src/etc/cpu-usage-over-time-plot.sh index 0905789079..1c34255919 100755 --- a/src/etc/cpu-usage-over-time-plot.sh +++ b/src/etc/cpu-usage-over-time-plot.sh @@ -7,13 +7,21 @@ # commit SHA of the build you're interested in, and the second is the name of # the builder. For example: # -# ./src/etc/cpu-usage-over-time-plot.sh e699ea096fcc2fc9ce8e8bcf884e11496a31cc9f i686-mingw-1 +# ./src/etc/cpu-usage-over-time-plot.sh 7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c x86_64-gnu # # That will generate `$builder.png` in the current directory which you can open # up to see a hopefully pretty graph. # # Improvements to this script are greatly appreciated! +if [[ $# != 2 ]]; then + echo "expected 2 arguments, recieved $#" + echo "example usage: './src/etc/cpu-usage-over-time-plot.sh \ +7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c \ +x86_64-gnu'" + exit 1 +fi + set -ex bucket=rust-lang-ci2 @@ -30,7 +38,7 @@ set ylabel "CPU Usage %" set xlabel "Time" set datafile sep ',' set term png size 3000,1000 -set output "$builder.png" +set output "$builder-$commit-cpu-usage-plot.png" set grid f(x) = mean_y @@ -43,7 +51,9 @@ set ytics 10 set boxwidth 0.5 plot \\ - mean_y with lines linetype 1 linecolor rgb "#ff0000" title "average", \\ - "cpu-$builder.csv" using 1:(100-\$2) with points pointtype 7 pointsize 0.4 title "$builder", \\ - "" using 1:(100-\$2) smooth bezier linewidth 3 title "bezier" + mean_y with lines linetype 1 linecolor rgb "#ff0000" title "average", "cpu-$builder.csv" \\ + using 1:(100-\$2) with points pointtype 7 pointsize 0.4 title "$builder", "" \\ + using 1:(100-\$2) smooth bezier linewidth 3 title "bezier" EOF + +rm "cpu-$builder.csv" diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py index 269b6868e2..70b6af717c 100644 --- a/src/etc/htmldocck.py +++ b/src/etc/htmldocck.py @@ -94,6 +94,10 @@ There are a number of supported commands: in the specified file. The number of occurrences must match the given count. +* `@count PATH XPATH TEXT COUNT` checks for the occurrence of the given XPath + with the given text in the specified file. The number of occurrences must + match the given count. + * `@snapshot NAME PATH XPATH` creates a snapshot test named NAME. A snapshot test captures a subtree of the DOM, at the location determined by the XPath, and compares it to a pre-recorded value @@ -382,9 +386,10 @@ def check_tree_attr(tree, path, attr, pat, regexp): return ret -def check_tree_text(tree, path, pat, regexp): +# Returns the number of occurences matching the regex (`regexp`) and the text (`pat`). +def check_tree_text(tree, path, pat, regexp, stop_at_first): path = normalize_xpath(path) - ret = False + match_count = 0 try: for e in tree.findall(path): try: @@ -392,13 +397,14 @@ def check_tree_text(tree, path, pat, regexp): except KeyError: continue else: - ret = check_string(value, pat, regexp) - if ret: - break + if check_string(value, pat, regexp): + match_count += 1 + if stop_at_first: + break except Exception: print('Failed to get path "{}"'.format(path)) raise - return ret + return match_count def get_tree_count(tree, path): @@ -411,7 +417,7 @@ def check_snapshot(snapshot_name, actual_tree, normalize_to_text): snapshot_path = '{}.{}.{}'.format(rust_test_path[:-3], snapshot_name, 'html') try: with open(snapshot_path, 'r') as snapshot_file: - expected_str = snapshot_file.read() + expected_str = snapshot_file.read().replace("{{channel}}", channel) except FileNotFoundError: if bless: expected_str = None @@ -516,6 +522,19 @@ def print_err(lineno, context, err, message=None): stderr("\t{}".format(context)) +def get_nb_matching_elements(cache, c, regexp, stop_at_first): + tree = cache.get_tree(c.args[0]) + pat, sep, attr = c.args[1].partition('/@') + if sep: # attribute + tree = cache.get_tree(c.args[0]) + return check_tree_attr(tree, pat, attr, c.args[2], False) + else: # normalized text + pat = c.args[1] + if pat.endswith('/text()'): + pat = pat[:-7] + return check_tree_text(cache.get_tree(c.args[0]), pat, c.args[2], regexp, stop_at_first) + + ERR_COUNT = 0 @@ -536,16 +555,7 @@ def check_command(c, cache): ret = check_string(cache.get_file(c.args[0]), c.args[1], regexp) elif len(c.args) == 3: # @has/matches = XML tree test cerr = "`XPATH PATTERN` did not match" - tree = cache.get_tree(c.args[0]) - pat, sep, attr = c.args[1].partition('/@') - if sep: # attribute - tree = cache.get_tree(c.args[0]) - ret = check_tree_attr(tree, pat, attr, c.args[2], regexp) - else: # normalized text - pat = c.args[1] - if pat.endswith('/text()'): - pat = pat[:-7] - ret = check_tree_text(cache.get_tree(c.args[0]), pat, c.args[2], regexp) + ret = get_nb_matching_elements(cache, c, regexp, True) != 0 else: raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd)) @@ -555,6 +565,11 @@ def check_command(c, cache): found = get_tree_count(cache.get_tree(c.args[0]), c.args[1]) cerr = "Expected {} occurrences but found {}".format(expected, found) ret = expected == found + elif len(c.args) == 4: # @count = count test + expected = int(c.args[3]) + found = get_nb_matching_elements(cache, c, False, False) + cerr = "Expected {} occurrences but found {}".format(expected, found) + ret = found == expected else: raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd)) diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index 643590fc97..a4e8a57e4b 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -7,15 +7,15 @@ - {value} + {value.pointer} - value + value.pointer - {value} + {value.pointer} - value + value.pointer diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 21efd04066..78470e8deb 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -11,8 +11,7 @@ arrayvec = { version = "0.7", default-features = false } askama = { version = "0.11", default-features = false, features = ["config"] } atty = "0.2" pulldown-cmark = { version = "0.9", default-features = false } -minifier = "0.0.43" -rayon = "1.5.1" +minifier = "0.2.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" smallvec = "1.6.1" @@ -29,6 +28,9 @@ version = "0.3.3" default-features = false features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] +[target.'cfg(windows)'.dependencies] +rayon = "1.5.1" + [dev-dependencies] expect-test = "1.0" diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index fffd949920..5e9f3346af 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; -use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable}; +use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable}; use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult}; use std::fmt::Debug; @@ -20,12 +20,12 @@ struct RegionDeps<'tcx> { smaller: FxHashSet>, } -crate struct AutoTraitFinder<'a, 'tcx> { - crate cx: &'a mut core::DocContext<'tcx>, +pub(crate) struct AutoTraitFinder<'a, 'tcx> { + pub(crate) cx: &'a mut core::DocContext<'tcx>, } impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { - crate fn new(cx: &'a mut core::DocContext<'tcx>) -> Self { + pub(crate) fn new(cx: &'a mut core::DocContext<'tcx>) -> Self { AutoTraitFinder { cx } } @@ -130,7 +130,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { }) } - crate fn get_auto_trait_impls(&mut self, item_def_id: DefId) -> Vec { + pub(crate) fn get_auto_trait_impls(&mut self, item_def_id: DefId) -> Vec { let tcx = self.cx.tcx; let param_env = tcx.param_env(item_def_id); let ty = tcx.type_of(item_def_id); @@ -345,15 +345,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { fn make_final_bounds( &self, ty_to_bounds: FxHashMap>, - ty_to_fn: FxHashMap, Option)>, + ty_to_fn: FxHashMap)>, lifetime_to_bounds: FxHashMap>, ) -> Vec { ty_to_bounds .into_iter() .flat_map(|(ty, mut bounds)| { - if let Some(data) = ty_to_fn.get(&ty) { - let (poly_trait, output) = - (data.0.as_ref().unwrap().clone(), data.1.as_ref().cloned().map(Box::new)); + if let Some((ref poly_trait, ref output)) = ty_to_fn.get(&ty) { let mut new_path = poly_trait.trait_.clone(); let last_segment = new_path.segments.pop().expect("segments were empty"); @@ -371,8 +369,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { GenericArgs::Parenthesized { inputs, output } => (inputs, output), }; + let output = output.as_ref().cloned().map(Box::new); if old_output.is_some() && old_output != output { - panic!("Output mismatch for {:?} {:?} {:?}", ty, old_output, data.1); + panic!("Output mismatch for {:?} {:?} {:?}", ty, old_output, output); } let new_params = GenericArgs::Parenthesized { inputs: old_input, output }; @@ -382,7 +381,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { .push(PathSegment { name: last_segment.name, args: new_params }); bounds.insert(GenericBound::TraitBound( - PolyTrait { trait_: new_path, generic_params: poly_trait.generic_params }, + PolyTrait { + trait_: new_path, + generic_params: poly_trait.generic_params.clone(), + }, hir::TraitBoundModifier::None, )); } @@ -468,7 +470,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { let mut lifetime_to_bounds: FxHashMap<_, FxHashSet<_>> = Default::default(); let mut ty_to_traits: FxHashMap> = Default::default(); - let mut ty_to_fn: FxHashMap, Option)> = Default::default(); + let mut ty_to_fn: FxHashMap)> = Default::default(); for p in clean_where_predicates { let (orig_p, p) = (p, p.clean(self.cx)); @@ -532,8 +534,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { if is_fn { ty_to_fn .entry(ty.clone()) - .and_modify(|e| *e = (Some(poly_trait.clone()), e.1.clone())) - .or_insert(((Some(poly_trait.clone())), None)); + .and_modify(|e| *e = (poly_trait.clone(), e.1.clone())) + .or_insert(((poly_trait.clone()), None)); ty_to_bounds.entry(ty.clone()).or_default(); } else { @@ -556,7 +558,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { .and_modify(|e| { *e = (e.0.clone(), Some(rhs.ty().unwrap().clone())) }) - .or_insert((None, Some(rhs.ty().unwrap().clone()))); + .or_insert(( + PolyTrait { + trait_: trait_.clone(), + generic_params: Vec::new(), + }, + Some(rhs.ty().unwrap().clone()), + )); continue; } @@ -643,11 +651,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { /// both for visual consistency between 'rustdoc' runs, and to /// make writing tests much easier #[inline] - fn sort_where_predicates(&self, mut predicates: &mut Vec) { + fn sort_where_predicates(&self, predicates: &mut Vec) { // We should never have identical bounds - and if we do, // they're visually identical as well. Therefore, using // an unstable sort is fine. - self.unstable_debug_sort(&mut predicates); + self.unstable_debug_sort(predicates); } /// Ensure that the bounds are in a consistent order. The precise @@ -656,11 +664,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { /// both for visual consistency between 'rustdoc' runs, and to /// make writing tests much easier #[inline] - fn sort_where_bounds(&self, mut bounds: &mut Vec) { + fn sort_where_bounds(&self, bounds: &mut Vec) { // We should never have identical bounds - and if we do, // they're visually identical as well. Therefore, using // an unstable sort is fine. - self.unstable_debug_sort(&mut bounds); + self.unstable_debug_sort(bounds); } /// This might look horrendously hacky, but it's actually not that bad. diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 805cc5c71d..c591c59133 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -8,12 +8,12 @@ use rustc_span::DUMMY_SP; use super::*; -crate struct BlanketImplFinder<'a, 'tcx> { - crate cx: &'a mut core::DocContext<'tcx>, +pub(crate) struct BlanketImplFinder<'a, 'tcx> { + pub(crate) cx: &'a mut core::DocContext<'tcx>, } impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { - crate fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec { + pub(crate) fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec { let param_env = self.cx.tcx.param_env(item_def_id); let ty = self.cx.tcx.bound_type_of(item_def_id); diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 9e9c4dfb50..f33f5d27d1 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -21,7 +21,7 @@ use crate::html::escape::Escape; mod tests; #[derive(Clone, Debug, PartialEq, Eq, Hash)] -crate enum Cfg { +pub(crate) enum Cfg { /// Accepts all configurations. True, /// Denies all configurations. @@ -37,9 +37,9 @@ crate enum Cfg { } #[derive(PartialEq, Debug)] -crate struct InvalidCfgError { - crate msg: &'static str, - crate span: Span, +pub(crate) struct InvalidCfgError { + pub(crate) msg: &'static str, + pub(crate) span: Span, } impl Cfg { @@ -56,7 +56,7 @@ impl Cfg { } } - crate fn parse_without( + pub(crate) fn parse_without( cfg: &MetaItem, exclude: &FxHashSet, ) -> Result, InvalidCfgError> { @@ -87,15 +87,20 @@ impl Cfg { }), }, MetaItemKind::List(ref items) => { + let orig_len = items.len(); let sub_cfgs = items.iter().filter_map(|i| Cfg::parse_nested(i, exclude).transpose()); let ret = match name { sym::all => sub_cfgs.fold(Ok(Cfg::True), |x, y| Ok(x? & y?)), sym::any => sub_cfgs.fold(Ok(Cfg::False), |x, y| Ok(x? | y?)), sym::not => { - let mut sub_cfgs = sub_cfgs.collect::>(); - if sub_cfgs.len() == 1 { - Ok(!sub_cfgs.pop().unwrap()?) + if orig_len == 1 { + let mut sub_cfgs = sub_cfgs.collect::>(); + if sub_cfgs.len() == 1 { + Ok(!sub_cfgs.pop().unwrap()?) + } else { + return Ok(None); + } } else { Err(InvalidCfgError { msg: "expected 1 cfg-pattern", span: cfg.span }) } @@ -117,7 +122,7 @@ impl Cfg { /// /// If the content is not properly formatted, it will return an error indicating what and where /// the error is. - crate fn parse(cfg: &MetaItem) -> Result { + pub(crate) fn parse(cfg: &MetaItem) -> Result { Self::parse_without(cfg, &FxHashSet::default()).map(|ret| ret.unwrap()) } @@ -125,7 +130,7 @@ impl Cfg { /// /// Equivalent to `attr::cfg_matches`. // FIXME: Actually make use of `features`. - crate fn matches(&self, parse_sess: &ParseSess, features: Option<&Features>) -> bool { + pub(crate) fn matches(&self, parse_sess: &ParseSess, features: Option<&Features>) -> bool { match *self { Cfg::False => false, Cfg::True => true, @@ -304,8 +309,7 @@ impl ops::BitAnd for Cfg { impl ops::BitOrAssign for Cfg { fn bitor_assign(&mut self, other: Cfg) { match (self, other) { - (&mut Cfg::True, _) | (_, Cfg::False) => {} - (s, Cfg::True) => *s = Cfg::True, + (Cfg::True, _) | (_, Cfg::False) | (_, Cfg::True) => {} (s @ &mut Cfg::False, b) => *s = b, (&mut Cfg::Any(ref mut a), Cfg::Any(ref mut b)) => { for c in b.drain(..) { diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index ece3fcb18b..7f72d5d39a 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -161,7 +161,7 @@ fn test_cfg_or() { x = word_cfg("test"); x |= Cfg::True; - assert_eq!(x, Cfg::True); + assert_eq!(x, word_cfg("test")); x = word_cfg("test2"); x |= Cfg::False; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 9a579cb531..5a3a8086f1 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -38,7 +38,7 @@ type Attrs<'hir> = &'hir [ast::Attribute]; /// and `Some` of a vector of items if it was successfully expanded. /// /// `parent_module` refers to the parent of the *re-export*, not the original item. -crate fn try_inline( +pub(crate) fn try_inline( cx: &mut DocContext<'_>, parent_module: DefId, import_def_id: Option, @@ -134,10 +134,11 @@ crate fn try_inline( Some(ret) } -crate fn try_inline_glob( +pub(crate) fn try_inline_glob( cx: &mut DocContext<'_>, res: Res, visited: &mut FxHashSet, + inlined_names: &mut FxHashSet<(ItemType, Symbol)>, ) -> Option> { let did = res.opt_def_id()?; if did.is_local() { @@ -146,15 +147,24 @@ crate fn try_inline_glob( match res { Res::Def(DefKind::Mod, did) => { - let m = build_module(cx, did, visited); - Some(m.items) + let mut items = build_module_items(cx, did, visited, inlined_names); + items.drain_filter(|item| { + if let Some(name) = item.name { + // If an item with the same type and name already exists, + // it takes priority over the inlined stuff. + !inlined_names.insert((item.type_(), name)) + } else { + false + } + }); + Some(items) } // glob imports on things like enums aren't inlined even for local exports, so just bail _ => None, } } -crate fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> { +pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> { cx.tcx.get_attrs_unchecked(did) } @@ -162,7 +172,7 @@ crate fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> { /// /// These names are used later on by HTML rendering to generate things like /// source links back to the original item. -crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) { +pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) { let crate_name = cx.tcx.crate_name(did.krate); let relative = @@ -190,7 +200,7 @@ crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) } } -crate fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait { +pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait { let trait_items = cx .tcx .associated_items(did) @@ -218,7 +228,7 @@ crate fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Tra } } -fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Function { +fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> clean::Function { let sig = cx.tcx.fn_sig(did); let predicates = cx.tcx.predicates_of(did); @@ -236,7 +246,6 @@ fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum { clean::Enum { generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), - variants_stripped: false, variants: cx.tcx.adt_def(did).variants().iter().map(|v| v.clean(cx)).collect(), } } @@ -249,7 +258,6 @@ fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct { struct_type: variant.ctor_kind, generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), fields: variant.fields.iter().map(|x| x.clean(cx)).collect(), - fields_stripped: false, } } @@ -259,7 +267,7 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union { let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); let fields = variant.fields.iter().map(|x| x.clean(cx)).collect(); - clean::Union { generics, fields, fields_stripped: false } + clean::Union { generics, fields } } fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef { @@ -274,7 +282,7 @@ fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef { } /// Builds all inherent implementations of an ADT (struct/union/enum) or Trait item/path/reexport. -crate fn build_impls( +pub(crate) fn build_impls( cx: &mut DocContext<'_>, parent_module: Option, did: DefId, @@ -318,7 +326,7 @@ fn merge_attrs( } /// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl`. -crate fn build_impl( +pub(crate) fn build_impl( cx: &mut DocContext<'_>, parent_module: Option, did: DefId, @@ -344,7 +352,7 @@ crate fn build_impl( } if let Some(stab) = tcx.lookup_stability(did) { - if stab.level.is_unstable() && stab.feature == sym::rustc_private { + if stab.is_unstable() && stab.feature == sym::rustc_private { return; } } @@ -373,7 +381,7 @@ crate fn build_impl( } if let Some(stab) = tcx.lookup_stability(did) { - if stab.level.is_unstable() && stab.feature == sym::rustc_private { + if stab.is_unstable() && stab.feature == sym::rustc_private { return; } } @@ -502,7 +510,11 @@ crate fn build_impl( for_, items: trait_items, polarity, - kind: ImplKind::Normal, + kind: if utils::has_doc_flag(tcx, did, sym::tuple_variadic) { + ImplKind::TupleVaradic + } else { + ImplKind::Normal + }, }), box merged_attrs, cx, @@ -515,6 +527,18 @@ fn build_module( did: DefId, visited: &mut FxHashSet, ) -> clean::Module { + let items = build_module_items(cx, did, visited, &mut FxHashSet::default()); + + let span = clean::Span::new(cx.tcx.def_span(did)); + clean::Module { items, span } +} + +fn build_module_items( + cx: &mut DocContext<'_>, + did: DefId, + visited: &mut FxHashSet, + inlined_names: &mut FxHashSet<(ItemType, Symbol)>, +) -> Vec { let mut items = Vec::new(); // If we're re-exporting a re-export it may actually re-export something in @@ -524,7 +548,13 @@ fn build_module( if item.vis.is_public() { let res = item.res.expect_non_local(); if let Some(def_id) = res.mod_def_id() { - if did == def_id || !visited.insert(def_id) { + // If we're inlining a glob import, it's possible to have + // two distinct modules with the same name. We don't want to + // inline it, or mark any of its contents as visited. + if did == def_id + || inlined_names.contains(&(ItemType::Module, item.ident.name)) + || !visited.insert(def_id) + { continue; } } @@ -544,7 +574,7 @@ fn build_module( segments: vec![clean::PathSegment { name: prim_ty.as_sym(), args: clean::GenericArgs::AngleBracketed { - args: Vec::new(), + args: Default::default(), bindings: ThinVec::new(), }, }], @@ -561,11 +591,10 @@ fn build_module( } } - let span = clean::Span::new(cx.tcx.def_span(did)); - clean::Module { items, span } + items } -crate fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { +pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { if let Some(did) = did.as_local() { let hir_id = tcx.hir().local_def_id_to_hir_id(did); rustc_hir_pretty::id_to_string(&tcx.hir(), hir_id) @@ -670,7 +699,7 @@ fn separate_supertrait_bounds( (g, ty_bounds) } -crate fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) { +pub(crate) fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) { if did.is_local() { return; } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6e18f381c5..4fd05c7bab 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3,12 +3,12 @@ mod auto_trait; mod blanket_impl; -crate mod cfg; -crate mod inline; +pub(crate) mod cfg; +pub(crate) mod inline; mod render_macro_matchers; mod simplify; -crate mod types; -crate mod utils; +pub(crate) mod types; +pub(crate) mod utils; use rustc_ast as ast; use rustc_attr as attr; @@ -41,27 +41,57 @@ use crate::visit_ast::Module as DocModule; use utils::*; -crate use self::types::*; -crate use self::utils::{get_auto_trait_and_blanket_impls, krate, register_res}; +pub(crate) use self::types::*; +pub(crate) use self::utils::{get_auto_trait_and_blanket_impls, krate, register_res}; -crate trait Clean { - fn clean(&self, cx: &mut DocContext<'_>) -> T; +pub(crate) trait Clean<'tcx, T> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> T; } -impl Clean for DocModule<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let mut items: Vec = vec![]; - items.extend( - self.foreigns - .iter() - .map(|(item, renamed)| clean_maybe_renamed_foreign_item(cx, item, *renamed)), - ); - items.extend(self.mods.iter().map(|x| x.clean(cx))); - items.extend( - self.items - .iter() - .flat_map(|(item, renamed)| clean_maybe_renamed_item(cx, item, *renamed)), - ); + let mut inserted = FxHashSet::default(); + items.extend(self.foreigns.iter().map(|(item, renamed)| { + let item = clean_maybe_renamed_foreign_item(cx, item, *renamed); + if let Some(name) = item.name { + inserted.insert((item.type_(), name)); + } + item + })); + items.extend(self.mods.iter().map(|x| { + inserted.insert((ItemType::Module, x.name)); + x.clean(cx) + })); + + // Split up imports from all other items. + // + // This covers the case where somebody does an import which should pull in an item, + // but there's already an item with the same namespace and same name. Rust gives + // priority to the not-imported one, so we should, too. + items.extend(self.items.iter().flat_map(|(item, renamed)| { + // First, lower everything other than imports. + if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { + return Vec::new(); + } + let v = clean_maybe_renamed_item(cx, item, *renamed); + for item in &v { + if let Some(name) = item.name { + inserted.insert((item.type_(), name)); + } + } + v + })); + items.extend(self.items.iter().flat_map(|(item, renamed)| { + // Now we actually lower the imports, skipping everything else. + if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { + let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); + clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted) + } else { + // skip everything else + Vec::new() + } + })); // determine if we should display the inner contents or // the outer `mod` item for the source code. @@ -89,14 +119,14 @@ impl Clean for DocModule<'_> { } } -impl Clean for [ast::Attribute] { +impl<'tcx> Clean<'tcx, Attributes> for [ast::Attribute] { fn clean(&self, _cx: &mut DocContext<'_>) -> Attributes { Attributes::from_ast(self, None) } } -impl Clean> for hir::GenericBound<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { +impl<'tcx> Clean<'tcx, Option> for hir::GenericBound<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { Some(match *self { hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)), hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => { @@ -131,9 +161,9 @@ impl Clean> for hir::GenericBound<'_> { } } -fn clean_trait_ref_with_bindings( - cx: &mut DocContext<'_>, - trait_ref: ty::TraitRef<'_>, +fn clean_trait_ref_with_bindings<'tcx>( + cx: &mut DocContext<'tcx>, + trait_ref: ty::TraitRef<'tcx>, bindings: &[TypeBinding], ) -> Path { let kind = cx.tcx.def_kind(trait_ref.def_id).into(); @@ -148,15 +178,15 @@ fn clean_trait_ref_with_bindings( path } -impl Clean for ty::TraitRef<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Path { +impl<'tcx> Clean<'tcx, Path> for ty::TraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Path { clean_trait_ref_with_bindings(cx, *self, &[]) } } -fn clean_poly_trait_ref_with_bindings( - cx: &mut DocContext<'_>, - poly_trait_ref: ty::PolyTraitRef<'_>, +fn clean_poly_trait_ref_with_bindings<'tcx>( + cx: &mut DocContext<'tcx>, + poly_trait_ref: ty::PolyTraitRef<'tcx>, bindings: &[TypeBinding], ) -> GenericBound { let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap(); @@ -167,7 +197,7 @@ fn clean_poly_trait_ref_with_bindings( .collect_referenced_late_bound_regions(&poly_trait_ref) .into_iter() .filter_map(|br| match br { - ty::BrNamed(_, name) => Some(GenericParamDef { + ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => Some(GenericParamDef { name, kind: GenericParamDefKind::Lifetime { outlives: vec![] }, }), @@ -182,14 +212,14 @@ fn clean_poly_trait_ref_with_bindings( ) } -impl<'tcx> Clean for ty::PolyTraitRef<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { +impl<'tcx> Clean<'tcx, GenericBound> for ty::PolyTraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericBound { clean_poly_trait_ref_with_bindings(cx, *self, &[]) } } -impl Clean for hir::Lifetime { - fn clean(&self, cx: &mut DocContext<'_>) -> Lifetime { +impl<'tcx> Clean<'tcx, Lifetime> for hir::Lifetime { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Lifetime { let def = cx.tcx.named_region(self.hir_id); if let Some( rl::Region::EarlyBound(_, node_id) @@ -205,8 +235,8 @@ impl Clean for hir::Lifetime { } } -impl Clean for hir::ConstArg { - fn clean(&self, cx: &mut DocContext<'_>) -> Constant { +impl<'tcx> Clean<'tcx, Constant> for hir::ConstArg { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Constant { Constant { type_: cx .tcx @@ -217,15 +247,20 @@ impl Clean for hir::ConstArg { } } -impl Clean> for ty::Region<'_> { +impl<'tcx> Clean<'tcx, Option> for ty::Region<'tcx> { fn clean(&self, _cx: &mut DocContext<'_>) -> Option { match **self { ty::ReStatic => Some(Lifetime::statik()), ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) => { - Some(Lifetime(name)) + if name != kw::UnderscoreLifetime { Some(Lifetime(name)) } else { None } + } + ty::ReEarlyBound(ref data) => { + if data.name != kw::UnderscoreLifetime { + Some(Lifetime(data.name)) + } else { + None + } } - ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)), - ty::ReLateBound(..) | ty::ReFree(..) | ty::ReVar(..) @@ -239,8 +274,8 @@ impl Clean> for ty::Region<'_> { } } -impl Clean> for hir::WherePredicate<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { +impl<'tcx> Clean<'tcx, Option> for hir::WherePredicate<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { if !self.in_where_clause() { return None; } @@ -248,7 +283,7 @@ impl Clean> for hir::WherePredicate<'_> { hir::WherePredicate::BoundPredicate(ref wbp) => { let bound_params = wbp .bound_generic_params - .into_iter() + .iter() .map(|param| { // Higher-ranked params must be lifetimes. // Higher-ranked lifetimes can't have bounds. @@ -279,8 +314,8 @@ impl Clean> for hir::WherePredicate<'_> { } } -impl<'a> Clean> for ty::Predicate<'a> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { +impl<'tcx> Clean<'tcx, Option> for ty::Predicate<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { let bound_predicate = self.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Trait(pred) => bound_predicate.rebind(pred).clean(cx), @@ -300,8 +335,8 @@ impl<'a> Clean> for ty::Predicate<'a> { } } -impl<'a> Clean> for ty::PolyTraitPredicate<'a> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { +impl<'tcx> Clean<'tcx, Option> for ty::PolyTraitPredicate<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op. if self.skip_binder().constness == ty::BoundConstness::ConstIfConst && Some(self.skip_binder().def_id()) == cx.tcx.lang_items().destruct_trait() @@ -318,10 +353,10 @@ impl<'a> Clean> for ty::PolyTraitPredicate<'a> { } } -impl<'tcx> Clean> +impl<'tcx> Clean<'tcx, Option> for ty::OutlivesPredicate, ty::Region<'tcx>> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { let ty::OutlivesPredicate(a, b) = self; if a.is_empty() && b.is_empty() { @@ -335,8 +370,10 @@ impl<'tcx> Clean> } } -impl<'tcx> Clean> for ty::OutlivesPredicate, ty::Region<'tcx>> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { +impl<'tcx> Clean<'tcx, Option> + for ty::OutlivesPredicate, ty::Region<'tcx>> +{ + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { let ty::OutlivesPredicate(ty, lt) = self; if lt.is_empty() { @@ -351,8 +388,8 @@ impl<'tcx> Clean> for ty::OutlivesPredicate, ty: } } -impl<'tcx> Clean for ty::Term<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> Term { +impl<'tcx> Clean<'tcx, Term> for ty::Term<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Term { match self { ty::Term::Ty(ty) => Term::Type(ty.clean(cx)), ty::Term::Const(c) => Term::Constant(c.clean(cx)), @@ -360,8 +397,8 @@ impl<'tcx> Clean for ty::Term<'tcx> { } } -impl<'tcx> Clean for hir::Term<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> Term { +impl<'tcx> Clean<'tcx, Term> for hir::Term<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Term { match self { hir::Term::Ty(ty) => Term::Type(ty.clean(cx)), hir::Term::Const(c) => { @@ -372,60 +409,72 @@ impl<'tcx> Clean for hir::Term<'tcx> { } } -impl<'tcx> Clean for ty::ProjectionPredicate<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { +impl<'tcx> Clean<'tcx, WherePredicate> for ty::ProjectionPredicate<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> WherePredicate { let ty::ProjectionPredicate { projection_ty, term } = self; WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: term.clean(cx) } } } -impl<'tcx> Clean for ty::ProjectionTy<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> Type { - let lifted = self.lift_to_tcx(cx.tcx).unwrap(); - let trait_ = lifted.trait_ref(cx.tcx).clean(cx); - let self_type = self.self_ty().clean(cx); - Type::QPath { - assoc: Box::new(projection_to_path_segment(*self, cx)), - self_def_id: self_type.def_id(&cx.cache), - self_type: box self_type, - trait_, - } +fn clean_projection<'tcx>( + ty: ty::ProjectionTy<'tcx>, + cx: &mut DocContext<'tcx>, + def_id: Option, +) -> Type { + let lifted = ty.lift_to_tcx(cx.tcx).unwrap(); + let trait_ = lifted.trait_ref(cx.tcx).clean(cx); + let self_type = ty.self_ty().clean(cx); + let self_def_id = if let Some(def_id) = def_id { + cx.tcx.opt_parent(def_id).or(Some(def_id)) + } else { + self_type.def_id(&cx.cache) + }; + let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); + Type::QPath { + assoc: Box::new(projection_to_path_segment(ty, cx)), + should_show_cast, + self_type: box self_type, + trait_, } } -fn projection_to_path_segment(ty: ty::ProjectionTy<'_>, cx: &mut DocContext<'_>) -> PathSegment { +impl<'tcx> Clean<'tcx, Type> for ty::ProjectionTy<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { + clean_projection(*self, cx, None) + } +} + +fn compute_should_show_cast(self_def_id: Option, trait_: &Path, self_type: &Type) -> bool { + !trait_.segments.is_empty() + && self_def_id + .zip(Some(trait_.def_id())) + .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_) +} + +fn projection_to_path_segment<'tcx>( + ty: ty::ProjectionTy<'tcx>, + cx: &mut DocContext<'tcx>, +) -> PathSegment { let item = cx.tcx.associated_item(ty.item_def_id); let generics = cx.tcx.generics_of(ty.item_def_id); PathSegment { name: item.name, args: GenericArgs::AngleBracketed { - args: substs_to_args(cx, &ty.substs[generics.parent_count..], false), + args: substs_to_args(cx, &ty.substs[generics.parent_count..], false).into(), bindings: Default::default(), }, } } -impl Clean for ty::GenericParamDef { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { +impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef { let (name, kind) = match self.kind { ty::GenericParamDefKind::Lifetime => { (self.name, GenericParamDefKind::Lifetime { outlives: vec![] }) } ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { let default = if has_default { - let mut default = cx.tcx.type_of(self.def_id).clean(cx); - - // We need to reassign the `self_def_id`, if there's a parent (which is the - // `Self` type), so we can properly render `` casts, because the - // information about which type `Self` is, is only present here, but not in - // the cleaning process of the type itself. To resolve this and have the - // `self_def_id` set, we override it here. - // See https://github.com/rust-lang/rust/issues/85454 - if let QPath { ref mut self_def_id, .. } = default { - *self_def_id = Some(cx.tcx.parent(self.def_id)); - } - - Some(default) + Some(clean_ty(cx.tcx.type_of(self.def_id), cx, Some(self.def_id))) } else { None }; @@ -456,29 +505,19 @@ impl Clean for ty::GenericParamDef { } } -fn clean_generic_param( - cx: &mut DocContext<'_>, - generics: Option<&hir::Generics<'_>>, - param: &hir::GenericParam<'_>, +fn clean_generic_param<'tcx>( + cx: &mut DocContext<'tcx>, + generics: Option<&hir::Generics<'tcx>>, + param: &hir::GenericParam<'tcx>, ) -> GenericParamDef { + let did = cx.tcx.hir().local_def_id(param.hir_id); let (name, kind) = match param.kind { hir::GenericParamKind::Lifetime { .. } => { let outlives = if let Some(generics) = generics { generics - .predicates - .iter() - .flat_map(|pred| { - match pred { - hir::WherePredicate::RegionPredicate(rp) - if rp.lifetime.name == hir::LifetimeName::Param(param.name) - && !rp.in_where_clause => - { - rp.bounds - } - _ => &[], - } - .iter() - }) + .outlives_for_param(did) + .filter(|bp| !bp.in_where_clause) + .flat_map(|bp| bp.bounds) .map(|bound| match bound { hir::GenericBound::Outlives(lt) => lt.clean(cx), _ => panic!(), @@ -490,7 +529,6 @@ fn clean_generic_param( (param.name.ident().name, GenericParamDefKind::Lifetime { outlives }) } hir::GenericParamKind::Type { ref default, synthetic } => { - let did = cx.tcx.hir().local_def_id(param.hir_id); let bounds = if let Some(generics) = generics { generics .bounds_for_param(did) @@ -511,10 +549,10 @@ fn clean_generic_param( }, ) } - hir::GenericParamKind::Const { ref ty, default } => ( + hir::GenericParamKind::Const { ty, default } => ( param.name.ident().name, GenericParamDefKind::Const { - did: cx.tcx.hir().local_def_id(param.hir_id).to_def_id(), + did: did.to_def_id(), ty: Box::new(ty.clean(cx)), default: default.map(|ct| { let def_id = cx.tcx.hir().local_def_id(ct.hir_id); @@ -527,29 +565,25 @@ fn clean_generic_param( GenericParamDef { name, kind } } -impl Clean for hir::Generics<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Generics { - // Synthetic type-parameters are inserted after normal ones. - // In order for normal parameters to be able to refer to synthetic ones, - // scans them first. - fn is_impl_trait(param: &hir::GenericParam<'_>) -> bool { - match param.kind { - hir::GenericParamKind::Type { synthetic, .. } => synthetic, - _ => false, - } - } - /// This can happen for `async fn`, e.g. `async fn f<'_>(&'_ self)`. - /// - /// See [`lifetime_to_generic_param`] in [`rustc_ast_lowering`] for more information. - /// - /// [`lifetime_to_generic_param`]: rustc_ast_lowering::LoweringContext::lifetime_to_generic_param - fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool { - matches!( - param.kind, - hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided } - ) - } +/// Synthetic type-parameters are inserted after normal ones. +/// In order for normal parameters to be able to refer to synthetic ones, +/// scans them first. +fn is_impl_trait(param: &hir::GenericParam<'_>) -> bool { + match param.kind { + hir::GenericParamKind::Type { synthetic, .. } => synthetic, + _ => false, + } +} +/// This can happen for `async fn`, e.g. `async fn f<'_>(&'_ self)`. +/// +/// See `lifetime_to_generic_param` in `rustc_ast_lowering` for more information. +fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool { + matches!(param.kind, hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided }) +} + +impl<'tcx> Clean<'tcx, Generics> for hir::Generics<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Generics { let impl_trait_params = self .params .iter() @@ -609,10 +643,10 @@ impl Clean for hir::Generics<'_> { } } -fn clean_ty_generics( - cx: &mut DocContext<'_>, +fn clean_ty_generics<'tcx>( + cx: &mut DocContext<'tcx>, gens: &ty::Generics, - preds: ty::GenericPredicates<'_>, + preds: ty::GenericPredicates<'tcx>, ) -> Generics { // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses, // since `Clean for ty::Predicate` would consume them. @@ -775,13 +809,13 @@ fn clean_ty_generics( } } -fn clean_fn_or_proc_macro( - item: &hir::Item<'_>, - sig: &hir::FnSig<'_>, - generics: &hir::Generics<'_>, +fn clean_fn_or_proc_macro<'tcx>( + item: &hir::Item<'tcx>, + sig: &hir::FnSig<'tcx>, + generics: &hir::Generics<'tcx>, body_id: hir::BodyId, name: &mut Symbol, - cx: &mut DocContext<'_>, + cx: &mut DocContext<'tcx>, ) -> ItemKind { let attrs = cx.tcx.hir().attrs(item.hir_id()); let macro_kind = attrs.iter().find_map(|a| { @@ -859,10 +893,10 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib } } -fn clean_function( - cx: &mut DocContext<'_>, - sig: &hir::FnSig<'_>, - generics: &hir::Generics<'_>, +fn clean_function<'tcx>( + cx: &mut DocContext<'tcx>, + sig: &hir::FnSig<'tcx>, + generics: &hir::Generics<'tcx>, body_id: hir::BodyId, ) -> Function { let (generics, decl) = enter_impl_trait(cx, |cx| { @@ -875,9 +909,9 @@ fn clean_function( Function { decl, generics } } -fn clean_args_from_types_and_names( - cx: &mut DocContext<'_>, - types: &[hir::Ty<'_>], +fn clean_args_from_types_and_names<'tcx>( + cx: &mut DocContext<'tcx>, + types: &[hir::Ty<'tcx>], names: &[Ident], ) -> Arguments { Arguments { @@ -895,9 +929,9 @@ fn clean_args_from_types_and_names( } } -fn clean_args_from_types_and_body_id( - cx: &mut DocContext<'_>, - types: &[hir::Ty<'_>], +fn clean_args_from_types_and_body_id<'tcx>( + cx: &mut DocContext<'tcx>, + types: &[hir::Ty<'tcx>], body_id: hir::BodyId, ) -> Arguments { let body = cx.tcx.hir().body(body_id); @@ -915,25 +949,25 @@ fn clean_args_from_types_and_body_id( } } -fn clean_fn_decl_with_args( - cx: &mut DocContext<'_>, - decl: &hir::FnDecl<'_>, +fn clean_fn_decl_with_args<'tcx>( + cx: &mut DocContext<'tcx>, + decl: &hir::FnDecl<'tcx>, args: Arguments, ) -> FnDecl { FnDecl { inputs: args, output: decl.output.clean(cx), c_variadic: decl.c_variadic } } -fn clean_fn_decl_from_did_and_sig( - cx: &mut DocContext<'_>, +fn clean_fn_decl_from_did_and_sig<'tcx>( + cx: &mut DocContext<'tcx>, did: Option, - sig: ty::PolyFnSig<'_>, + sig: ty::PolyFnSig<'tcx>, ) -> FnDecl { let mut names = did.map_or(&[] as &[_], |did| cx.tcx.fn_arg_names(did)).iter(); // We assume all empty tuples are default return type. This theoretically can discard `-> ()`, // but shouldn't change any code meaning. let output = match sig.skip_binder().output().clean(cx) { - Type::Tuple(inner) if inner.len() == 0 => DefaultReturn, + Type::Tuple(inner) if inner.is_empty() => DefaultReturn, ty => Return(ty), }; @@ -955,17 +989,17 @@ fn clean_fn_decl_from_did_and_sig( } } -impl Clean for hir::FnRetTy<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> FnRetTy { +impl<'tcx> Clean<'tcx, FnRetTy> for hir::FnRetTy<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> FnRetTy { match *self { - Self::Return(ref typ) => Return(typ.clean(cx)), + Self::Return(typ) => Return(typ.clean(cx)), Self::DefaultReturn(..) => DefaultReturn, } } } -impl Clean for hir::IsAuto { - fn clean(&self, _: &mut DocContext<'_>) -> bool { +impl<'tcx> Clean<'tcx, bool> for hir::IsAuto { + fn clean(&self, _: &mut DocContext<'tcx>) -> bool { match *self { hir::IsAuto::Yes => true, hir::IsAuto::No => false, @@ -973,39 +1007,40 @@ impl Clean for hir::IsAuto { } } -impl Clean for hir::TraitRef<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Path { +impl<'tcx> Clean<'tcx, Path> for hir::TraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Path { let path = self.path.clean(cx); register_res(cx, path.res); path } } -impl Clean for hir::PolyTraitRef<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> PolyTrait { +impl<'tcx> Clean<'tcx, PolyTrait> for hir::PolyTraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> PolyTrait { PolyTrait { trait_: self.trait_ref.clean(cx), generic_params: self .bound_generic_params .iter() + .filter(|p| !is_elided_lifetime(p)) .map(|x| clean_generic_param(cx, None, x)) .collect(), } } } -impl Clean for hir::TraitItem<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for hir::TraitItem<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let local_did = self.def_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match self.kind { - hir::TraitItemKind::Const(ref ty, Some(default)) => AssocConstItem( + hir::TraitItemKind::Const(ty, Some(default)) => AssocConstItem( ty.clean(cx), ConstantKind::Local { def_id: local_did, body: default }, ), - hir::TraitItemKind::Const(ref ty, None) => TyAssocConstItem(ty.clean(cx)), + hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(ty.clean(cx)), hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { - let m = clean_function(cx, sig, &self.generics, body); + let m = clean_function(cx, sig, self.generics, body); MethodItem(m, None) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => { @@ -1041,21 +1076,21 @@ impl Clean for hir::TraitItem<'_> { } } -impl Clean for hir::ImplItem<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let local_did = self.def_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match self.kind { - hir::ImplItemKind::Const(ref ty, expr) => { + hir::ImplItemKind::Const(ty, expr) => { let default = ConstantKind::Local { def_id: local_did, body: expr }; AssocConstItem(ty.clean(cx), default) } hir::ImplItemKind::Fn(ref sig, body) => { - let m = clean_function(cx, sig, &self.generics, body); + let m = clean_function(cx, sig, self.generics, body); let defaultness = cx.tcx.associated_item(self.def_id).defaultness; MethodItem(m, Some(defaultness)) } - hir::ImplItemKind::TyAlias(ref hir_ty) => { + hir::ImplItemKind::TyAlias(hir_ty) => { let type_ = hir_ty.clean(cx); let generics = self.generics.clean(cx); let item_type = hir_ty_to_ty(cx.tcx, hir_ty).clean(cx); @@ -1082,8 +1117,8 @@ impl Clean for hir::ImplItem<'_> { } } -impl Clean for ty::AssocItem { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let tcx = cx.tcx; let kind = match self.kind { ty::AssocKind::Const => { @@ -1196,7 +1231,7 @@ impl Clean for ty::AssocItem { || generics .params .iter() - .zip(args) + .zip(args.iter()) .any(|(param, arg)| !param_eq_arg(param, arg)) { return false; @@ -1273,12 +1308,12 @@ impl Clean for ty::AssocItem { } } -fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { +fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type { let hir::Ty { hir_id: _, span, ref kind } = *hir_ty; let hir::TyKind::Path(qpath) = kind else { unreachable!() }; match qpath { - hir::QPath::Resolved(None, ref path) => { + hir::QPath::Resolved(None, path) => { if let Res::Def(DefKind::TyParam, did) = path.res { if let Some(new_ty) = cx.substs.get(&did).and_then(|p| p.as_ty()).cloned() { return new_ty; @@ -1295,7 +1330,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { resolve_type(cx, path) } } - hir::QPath::Resolved(Some(ref qself), p) => { + hir::QPath::Resolved(Some(qself), p) => { // Try to normalize `::T` to a type let ty = hir_ty_to_ty(cx.tcx, hir_ty); if let Some(normalized_value) = normalize(cx, ty) { @@ -1309,14 +1344,17 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { segments: trait_segments.iter().map(|x| x.clean(cx)).collect(), }; register_res(cx, trait_.res); + let self_def_id = DefId::local(qself.hir_id.owner.local_def_index); + let self_type = qself.clean(cx); + let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type); Type::QPath { assoc: Box::new(p.segments.last().expect("segments were empty").clean(cx)), - self_def_id: Some(DefId::local(qself.hir_id.owner.local_def_index)), - self_type: box qself.clean(cx), + should_show_cast, + self_type: box self_type, trait_, } } - hir::QPath::TypeRelative(ref qself, segment) => { + hir::QPath::TypeRelative(qself, segment) => { let ty = hir_ty_to_ty(cx.tcx, hir_ty); let res = match ty.kind() { ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id), @@ -1326,10 +1364,13 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { }; let trait_ = hir::Path { span, res, segments: &[] }.clean(cx); register_res(cx, trait_.res); + let self_def_id = res.opt_def_id(); + let self_type = qself.clean(cx); + let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); Type::QPath { assoc: Box::new(segment.clean(cx)), - self_def_id: res.opt_def_id(), - self_type: box qself.clean(cx), + should_show_cast, + self_type: box self_type, trait_, } } @@ -1337,7 +1378,10 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { } } -fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_>) -> Option { +fn maybe_expand_private_type_alias<'tcx>( + cx: &mut DocContext<'tcx>, + path: &hir::Path<'tcx>, +) -> Option { let Res::Def(DefKind::TyAlias, def_id) = path.res else { return None }; // Substitute private type aliases let def_id = def_id.as_local()?; @@ -1420,8 +1464,8 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_> Some(cx.enter_alias(substs, |cx| ty.clean(cx))) } -impl Clean for hir::Ty<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Type { +impl<'tcx> Clean<'tcx, Type> for hir::Ty<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { use rustc_hir::*; match self.kind { @@ -1436,12 +1480,12 @@ impl Clean for hir::Ty<'_> { // Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though; // there's no case where it could cause the function to fail to compile. let elided = - l.is_elided() || matches!(l.name, LifetimeName::Param(ParamName::Fresh(_))); + l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh)); let lifetime = if elided { None } else { Some(l.clean(cx)) }; BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) } } - TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), - TyKind::Array(ref ty, ref length) => { + TyKind::Slice(ty) => Slice(box ty.clean(cx)), + TyKind::Array(ty, ref length) => { let length = match length { hir::ArrayLen::Infer(_, _) => "_".to_string(), hir::ArrayLen::Body(anon_const) => { @@ -1476,7 +1520,7 @@ impl Clean for hir::Ty<'_> { let lifetime = if !lifetime.is_elided() { Some(lifetime.clean(cx)) } else { None }; DynTrait(bounds, lifetime) } - TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)), + TyKind::BareFn(barefn) => BareFunction(box barefn.clean(cx)), // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s. TyKind::Infer | TyKind::Err => Infer, TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.kind), @@ -1515,201 +1559,199 @@ fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option> { } } -impl<'tcx> Clean for Ty<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> Type { - trace!("cleaning type: {:?}", self); - let ty = normalize(cx, *self).unwrap_or(*self); - match *ty.kind() { - ty::Never => Primitive(PrimitiveType::Never), - ty::Bool => Primitive(PrimitiveType::Bool), - ty::Char => Primitive(PrimitiveType::Char), - ty::Int(int_ty) => Primitive(int_ty.into()), - ty::Uint(uint_ty) => Primitive(uint_ty.into()), - ty::Float(float_ty) => Primitive(float_ty.into()), - ty::Str => Primitive(PrimitiveType::Str), - ty::Slice(ty) => Slice(box ty.clean(cx)), - ty::Array(ty, n) => { - let mut n = cx.tcx.lift(n).expect("array lift failed"); - n = n.eval(cx.tcx, ty::ParamEnv::reveal_all()); - let n = print_const(cx, n); - Array(box ty.clean(cx), n) - } - ty::RawPtr(mt) => RawPointer(mt.mutbl, box mt.ty.clean(cx)), - ty::Ref(r, ty, mutbl) => { - BorrowedRef { lifetime: r.clean(cx), mutability: mutbl, type_: box ty.clean(cx) } - } - ty::FnDef(..) | ty::FnPtr(_) => { - let ty = cx.tcx.lift(*self).expect("FnPtr lift failed"); - let sig = ty.fn_sig(cx.tcx); - let decl = clean_fn_decl_from_did_and_sig(cx, None, sig); - BareFunction(box BareFunctionDecl { - unsafety: sig.unsafety(), - generic_params: Vec::new(), - decl, - abi: sig.abi(), - }) - } - ty::Adt(def, substs) => { - let did = def.did(); - let kind = match def.adt_kind() { - AdtKind::Struct => ItemType::Struct, - AdtKind::Union => ItemType::Union, - AdtKind::Enum => ItemType::Enum, - }; - inline::record_extern_fqn(cx, did, kind); - let path = external_path(cx, did, false, vec![], substs); - Type::Path { path } - } - ty::Foreign(did) => { - inline::record_extern_fqn(cx, did, ItemType::ForeignType); - let path = external_path(cx, did, false, vec![], InternalSubsts::empty()); - Type::Path { path } - } - ty::Dynamic(obj, ref reg) => { - // HACK: pick the first `did` as the `did` of the trait object. Someone - // might want to implement "native" support for marker-trait-only - // trait objects. - let mut dids = obj.principal_def_id().into_iter().chain(obj.auto_traits()); - let did = dids - .next() - .unwrap_or_else(|| panic!("found trait object `{:?}` with no traits?", self)); - let substs = match obj.principal() { - Some(principal) => principal.skip_binder().substs, - // marker traits have no substs. - _ => cx.tcx.intern_substs(&[]), - }; +fn clean_ty<'tcx>(this: Ty<'tcx>, cx: &mut DocContext<'tcx>, def_id: Option) -> Type { + trace!("cleaning type: {:?}", this); + let ty = normalize(cx, this).unwrap_or(this); + match *ty.kind() { + ty::Never => Primitive(PrimitiveType::Never), + ty::Bool => Primitive(PrimitiveType::Bool), + ty::Char => Primitive(PrimitiveType::Char), + ty::Int(int_ty) => Primitive(int_ty.into()), + ty::Uint(uint_ty) => Primitive(uint_ty.into()), + ty::Float(float_ty) => Primitive(float_ty.into()), + ty::Str => Primitive(PrimitiveType::Str), + ty::Slice(ty) => Slice(box ty.clean(cx)), + ty::Array(ty, n) => { + let mut n = cx.tcx.lift(n).expect("array lift failed"); + n = n.eval(cx.tcx, ty::ParamEnv::reveal_all()); + let n = print_const(cx, n); + Array(box ty.clean(cx), n) + } + ty::RawPtr(mt) => RawPointer(mt.mutbl, box mt.ty.clean(cx)), + ty::Ref(r, ty, mutbl) => { + BorrowedRef { lifetime: r.clean(cx), mutability: mutbl, type_: box ty.clean(cx) } + } + ty::FnDef(..) | ty::FnPtr(_) => { + let ty = cx.tcx.lift(this).expect("FnPtr lift failed"); + let sig = ty.fn_sig(cx.tcx); + let decl = clean_fn_decl_from_did_and_sig(cx, None, sig); + BareFunction(box BareFunctionDecl { + unsafety: sig.unsafety(), + generic_params: Vec::new(), + decl, + abi: sig.abi(), + }) + } + ty::Adt(def, substs) => { + let did = def.did(); + let kind = match def.adt_kind() { + AdtKind::Struct => ItemType::Struct, + AdtKind::Union => ItemType::Union, + AdtKind::Enum => ItemType::Enum, + }; + inline::record_extern_fqn(cx, did, kind); + let path = external_path(cx, did, false, vec![], substs); + Type::Path { path } + } + ty::Foreign(did) => { + inline::record_extern_fqn(cx, did, ItemType::ForeignType); + let path = external_path(cx, did, false, vec![], InternalSubsts::empty()); + Type::Path { path } + } + ty::Dynamic(obj, ref reg) => { + // HACK: pick the first `did` as the `did` of the trait object. Someone + // might want to implement "native" support for marker-trait-only + // trait objects. + let mut dids = obj.principal_def_id().into_iter().chain(obj.auto_traits()); + let did = dids + .next() + .unwrap_or_else(|| panic!("found trait object `{:?}` with no traits?", this)); + let substs = match obj.principal() { + Some(principal) => principal.skip_binder().substs, + // marker traits have no substs. + _ => cx.tcx.intern_substs(&[]), + }; - inline::record_extern_fqn(cx, did, ItemType::Trait); + inline::record_extern_fqn(cx, did, ItemType::Trait); - let lifetime = reg.clean(cx); - let mut bounds = vec![]; + let lifetime = reg.clean(cx); + let mut bounds = vec![]; - for did in dids { - let empty = cx.tcx.intern_substs(&[]); - let path = external_path(cx, did, false, vec![], empty); - inline::record_extern_fqn(cx, did, ItemType::Trait); - let bound = PolyTrait { trait_: path, generic_params: Vec::new() }; - bounds.push(bound); - } + for did in dids { + let empty = cx.tcx.intern_substs(&[]); + let path = external_path(cx, did, false, vec![], empty); + inline::record_extern_fqn(cx, did, ItemType::Trait); + let bound = PolyTrait { trait_: path, generic_params: Vec::new() }; + bounds.push(bound); + } - let mut bindings = vec![]; - for pb in obj.projection_bounds() { - bindings.push(TypeBinding { - assoc: projection_to_path_segment( - pb.skip_binder() - .lift_to_tcx(cx.tcx) - .unwrap() - // HACK(compiler-errors): Doesn't actually matter what self - // type we put here, because we're only using the GAT's substs. - .with_self_ty(cx.tcx, cx.tcx.types.self_param) - .projection_ty, - cx, - ), - kind: TypeBindingKind::Equality { term: pb.skip_binder().term.clean(cx) }, - }); - } + let mut bindings = vec![]; + for pb in obj.projection_bounds() { + bindings.push(TypeBinding { + assoc: projection_to_path_segment( + pb.skip_binder() + .lift_to_tcx(cx.tcx) + .unwrap() + // HACK(compiler-errors): Doesn't actually matter what self + // type we put here, because we're only using the GAT's substs. + .with_self_ty(cx.tcx, cx.tcx.types.self_param) + .projection_ty, + cx, + ), + kind: TypeBindingKind::Equality { term: pb.skip_binder().term.clean(cx) }, + }); + } - let path = external_path(cx, did, false, bindings, substs); - bounds.insert(0, PolyTrait { trait_: path, generic_params: Vec::new() }); + let path = external_path(cx, did, false, bindings, substs); + bounds.insert(0, PolyTrait { trait_: path, generic_params: Vec::new() }); - DynTrait(bounds, lifetime) - } - ty::Tuple(t) => Tuple(t.iter().map(|t| t.clean(cx)).collect()), + DynTrait(bounds, lifetime) + } + ty::Tuple(t) => Tuple(t.iter().map(|t| t.clean(cx)).collect()), - ty::Projection(ref data) => data.clean(cx), + ty::Projection(ref data) => clean_projection(*data, cx, def_id), - ty::Param(ref p) => { - if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) { - ImplTrait(bounds) - } else { - Generic(p.name) - } + ty::Param(ref p) => { + if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) { + ImplTrait(bounds) + } else { + Generic(p.name) } + } - ty::Opaque(def_id, substs) => { - // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, - // by looking up the bounds associated with the def_id. - let substs = cx.tcx.lift(substs).expect("Opaque lift failed"); - let bounds = cx - .tcx - .explicit_item_bounds(def_id) - .iter() - .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, substs)) - .collect::>(); - let mut regions = vec![]; - let mut has_sized = false; - let mut bounds = bounds - .iter() - .filter_map(|bound| { - let bound_predicate = bound.kind(); - let trait_ref = match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref), - ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => { - if let Some(r) = reg.clean(cx) { - regions.push(GenericBound::Outlives(r)); - } - return None; + ty::Opaque(def_id, substs) => { + // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, + // by looking up the bounds associated with the def_id. + let substs = cx.tcx.lift(substs).expect("Opaque lift failed"); + let bounds = cx + .tcx + .explicit_item_bounds(def_id) + .iter() + .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, substs)) + .collect::>(); + let mut regions = vec![]; + let mut has_sized = false; + let mut bounds = bounds + .iter() + .filter_map(|bound| { + let bound_predicate = bound.kind(); + let trait_ref = match bound_predicate.skip_binder() { + ty::PredicateKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref), + ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => { + if let Some(r) = reg.clean(cx) { + regions.push(GenericBound::Outlives(r)); } - _ => return None, - }; + return None; + } + _ => return None, + }; - if let Some(sized) = cx.tcx.lang_items().sized_trait() { - if trait_ref.def_id() == sized { - has_sized = true; - return None; - } + if let Some(sized) = cx.tcx.lang_items().sized_trait() { + if trait_ref.def_id() == sized { + has_sized = true; + return None; } + } - let bindings: Vec<_> = bounds - .iter() - .filter_map(|bound| { - if let ty::PredicateKind::Projection(proj) = - bound.kind().skip_binder() - { - if proj.projection_ty.trait_ref(cx.tcx) - == trait_ref.skip_binder() - { - Some(TypeBinding { - assoc: projection_to_path_segment( - proj.projection_ty, - cx, - ), - kind: TypeBindingKind::Equality { - term: proj.term.clean(cx), - }, - }) - } else { - None - } + let bindings: Vec<_> = bounds + .iter() + .filter_map(|bound| { + if let ty::PredicateKind::Projection(proj) = bound.kind().skip_binder() + { + if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() { + Some(TypeBinding { + assoc: projection_to_path_segment(proj.projection_ty, cx), + kind: TypeBindingKind::Equality { + term: proj.term.clean(cx), + }, + }) } else { None } - }) - .collect(); + } else { + None + } + }) + .collect(); - Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, &bindings)) - }) - .collect::>(); - bounds.extend(regions); - if !has_sized && !bounds.is_empty() { - bounds.insert(0, GenericBound::maybe_sized(cx)); - } - ImplTrait(bounds) + Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, &bindings)) + }) + .collect::>(); + bounds.extend(regions); + if !has_sized && !bounds.is_empty() { + bounds.insert(0, GenericBound::maybe_sized(cx)); } + ImplTrait(bounds) + } - ty::Closure(..) | ty::Generator(..) => Tuple(vec![]), // FIXME(pcwalton) + ty::Closure(..) | ty::Generator(..) => Tuple(vec![]), // FIXME(pcwalton) - ty::Bound(..) => panic!("Bound"), - ty::Placeholder(..) => panic!("Placeholder"), - ty::GeneratorWitness(..) => panic!("GeneratorWitness"), - ty::Infer(..) => panic!("Infer"), - ty::Error(_) => panic!("Error"), - } + ty::Bound(..) => panic!("Bound"), + ty::Placeholder(..) => panic!("Placeholder"), + ty::GeneratorWitness(..) => panic!("GeneratorWitness"), + ty::Infer(..) => panic!("Infer"), + ty::Error(_) => panic!("Error"), } } -impl<'tcx> Clean for ty::Const<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> Constant { +impl<'tcx> Clean<'tcx, Type> for Ty<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { + clean_ty(*self, cx, None) + } +} + +impl<'tcx> Clean<'tcx, Constant> for ty::Const<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Constant { // FIXME: instead of storing the stringified expression, store `self` directly instead. Constant { type_: self.ty().clean(cx), @@ -1718,15 +1760,15 @@ impl<'tcx> Clean for ty::Const<'tcx> { } } -impl Clean for hir::FieldDef<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for hir::FieldDef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let def_id = cx.tcx.hir().local_def_id(self.hir_id).to_def_id(); clean_field(def_id, self.ident.name, self.ty.clean(cx), cx) } } -impl Clean for ty::FieldDef { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for ty::FieldDef { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { clean_field(self.did, self.name, cx.tcx.type_of(self.did).clean(cx), cx) } } @@ -1752,7 +1794,7 @@ fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } } -impl Clean for ty::Visibility { +impl<'tcx> Clean<'tcx, Visibility> for ty::Visibility { fn clean(&self, _cx: &mut DocContext<'_>) -> Visibility { match *self { ty::Visibility::Public => Visibility::Public, @@ -1766,24 +1808,23 @@ impl Clean for ty::Visibility { } } -impl Clean for rustc_hir::VariantData<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> VariantStruct { +impl<'tcx> Clean<'tcx, VariantStruct> for rustc_hir::VariantData<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> VariantStruct { VariantStruct { struct_type: CtorKind::from_hir(self), fields: self.fields().iter().map(|x| x.clean(cx)).collect(), - fields_stripped: false, } } } -impl Clean> for hir::VariantData<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Vec { +impl<'tcx> Clean<'tcx, Vec> for hir::VariantData<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Vec { self.fields().iter().map(|x| x.clean(cx)).collect() } } -impl Clean for ty::VariantDef { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for ty::VariantDef { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let kind = match self.ctor_kind { CtorKind::Const => Variant::CLike, CtorKind::Fn => { @@ -1791,7 +1832,6 @@ impl Clean for ty::VariantDef { } CtorKind::Fictive => Variant::Struct(VariantStruct { struct_type: CtorKind::Fictive, - fields_stripped: false, fields: self.fields.iter().map(|field| field.clean(cx)).collect(), }), }; @@ -1802,8 +1842,8 @@ impl Clean for ty::VariantDef { } } -impl Clean for hir::VariantData<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Variant { +impl<'tcx> Clean<'tcx, Variant> for hir::VariantData<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Variant { match self { hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)), hir::VariantData::Tuple(..) => Variant::Tuple(self.clean(cx)), @@ -1812,19 +1852,19 @@ impl Clean for hir::VariantData<'_> { } } -impl Clean for hir::Path<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Path { +impl<'tcx> Clean<'tcx, Path> for hir::Path<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Path { Path { res: self.res, segments: self.segments.iter().map(|x| x.clean(cx)).collect() } } } -impl Clean for hir::GenericArgs<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericArgs { +impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericArgs { if self.parenthesized { let output = self.bindings[0].ty().clean(cx); let output = if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None }; - let inputs = self.inputs().iter().map(|x| x.clean(cx)).collect(); + let inputs = self.inputs().iter().map(|x| x.clean(cx)).collect::>().into(); GenericArgs::Parenthesized { inputs, output } } else { let args = self @@ -1839,25 +1879,30 @@ impl Clean for hir::GenericArgs<'_> { hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(ct.clean(cx))), hir::GenericArg::Infer(_inf) => GenericArg::Infer, }) - .collect(); - let bindings = self.bindings.iter().map(|x| x.clean(cx)).collect(); + .collect::>() + .into(); + let bindings = self.bindings.iter().map(|x| x.clean(cx)).collect::>().into(); GenericArgs::AngleBracketed { args, bindings } } } } -impl Clean for hir::PathSegment<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> PathSegment { +impl<'tcx> Clean<'tcx, PathSegment> for hir::PathSegment<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> PathSegment { PathSegment { name: self.ident.name, args: self.args().clean(cx) } } } -impl Clean for hir::BareFnTy<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> BareFunctionDecl { +impl<'tcx> Clean<'tcx, BareFunctionDecl> for hir::BareFnTy<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> BareFunctionDecl { let (generic_params, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args - let generic_params = - self.generic_params.iter().map(|x| clean_generic_param(cx, None, x)).collect(); + let generic_params = self + .generic_params + .iter() + .filter(|p| !is_elided_lifetime(p)) + .map(|x| clean_generic_param(cx, None, x)) + .collect(); let args = clean_args_from_types_and_names(cx, self.decl.inputs, self.param_names); let decl = clean_fn_decl_with_args(cx, self.decl, args); (generic_params, decl) @@ -1866,9 +1911,9 @@ impl Clean for hir::BareFnTy<'_> { } } -fn clean_maybe_renamed_item( - cx: &mut DocContext<'_>, - item: &hir::Item<'_>, +fn clean_maybe_renamed_item<'tcx>( + cx: &mut DocContext<'tcx>, + item: &hir::Item<'tcx>, renamed: Option, ) -> Vec { use hir::ItemKind; @@ -1888,7 +1933,7 @@ fn clean_maybe_renamed_item( bounds: ty.bounds.iter().filter_map(|x| x.clean(cx)).collect(), generics: ty.generics.clean(cx), }), - ItemKind::TyAlias(hir_ty, ref generics) => { + ItemKind::TyAlias(hir_ty, generics) => { let rustdoc_ty = hir_ty.clean(cx); let ty = hir_ty_to_ty(cx.tcx, hir_ty).clean(cx); TypedefItem(Typedef { @@ -1897,29 +1942,26 @@ fn clean_maybe_renamed_item( item_type: Some(ty), }) } - ItemKind::Enum(ref def, ref generics) => EnumItem(Enum { + ItemKind::Enum(ref def, generics) => EnumItem(Enum { variants: def.variants.iter().map(|v| v.clean(cx)).collect(), generics: generics.clean(cx), - variants_stripped: false, }), - ItemKind::TraitAlias(ref generics, bounds) => TraitAliasItem(TraitAlias { + ItemKind::TraitAlias(generics, bounds) => TraitAliasItem(TraitAlias { generics: generics.clean(cx), bounds: bounds.iter().filter_map(|x| x.clean(cx)).collect(), }), - ItemKind::Union(ref variant_data, ref generics) => UnionItem(Union { + ItemKind::Union(ref variant_data, generics) => UnionItem(Union { generics: generics.clean(cx), fields: variant_data.fields().iter().map(|x| x.clean(cx)).collect(), - fields_stripped: false, }), - ItemKind::Struct(ref variant_data, ref generics) => StructItem(Struct { + ItemKind::Struct(ref variant_data, generics) => StructItem(Struct { struct_type: CtorKind::from_hir(variant_data), generics: generics.clean(cx), fields: variant_data.fields().iter().map(|x| x.clean(cx)).collect(), - fields_stripped: false, }), - ItemKind::Impl(ref impl_) => return clean_impl(impl_, item.hir_id(), cx), + ItemKind::Impl(impl_) => return clean_impl(impl_, item.hir_id(), cx), // proc macros can have a name set by attributes - ItemKind::Fn(ref sig, ref generics, body_id) => { + ItemKind::Fn(ref sig, generics, body_id) => { clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) } ItemKind::Macro(ref macro_def, _) => { @@ -1928,7 +1970,7 @@ fn clean_maybe_renamed_item( source: display_macro_source(cx, name, macro_def, def_id, ty_vis), }) } - ItemKind::Trait(is_auto, unsafety, ref generics, bounds, item_ids) => { + ItemKind::Trait(is_auto, unsafety, generics, bounds, item_ids) => { let items = item_ids.iter().map(|ti| cx.tcx.hir().trait_item(ti.id).clean(cx)).collect(); TraitItem(Trait { @@ -1943,7 +1985,7 @@ fn clean_maybe_renamed_item( return clean_extern_crate(item, name, orig_name, cx); } ItemKind::Use(path, kind) => { - return clean_use_statement(item, name, path, kind, cx); + return clean_use_statement(item, name, path, kind, cx, &mut FxHashSet::default()); } _ => unreachable!("not yet converted"), }; @@ -1952,8 +1994,8 @@ fn clean_maybe_renamed_item( }) } -impl Clean for hir::Variant<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for hir::Variant<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let kind = VariantItem(self.data.clean(cx)); let what_rustc_thinks = Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx); @@ -1962,7 +2004,11 @@ impl Clean for hir::Variant<'_> { } } -fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>) -> Vec { +fn clean_impl<'tcx>( + impl_: &hir::Impl<'tcx>, + hir_id: hir::HirId, + cx: &mut DocContext<'tcx>, +) -> Vec { let tcx = cx.tcx; let mut ret = Vec::new(); let trait_ = impl_.of_trait.as_ref().map(|t| t.clean(cx)); @@ -1989,7 +2035,11 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_> for_, items, polarity: tcx.impl_polarity(def_id), - kind: ImplKind::Normal, + kind: if utils::has_doc_flag(tcx, def_id.to_def_id(), sym::tuple_variadic) { + ImplKind::TupleVaradic + } else { + ImplKind::Normal + }, }); Item::from_hir_id_and_parts(hir_id, None, kind, cx) }; @@ -2000,11 +2050,11 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_> ret } -fn clean_extern_crate( - krate: &hir::Item<'_>, +fn clean_extern_crate<'tcx>( + krate: &hir::Item<'tcx>, name: Symbol, orig_name: Option, - cx: &mut DocContext<'_>, + cx: &mut DocContext<'tcx>, ) -> Vec { // this is the ID of the `extern crate` statement let cnum = cx.tcx.extern_mod_stmt_cnum(krate.def_id).unwrap_or(LOCAL_CRATE); @@ -2050,12 +2100,13 @@ fn clean_extern_crate( }] } -fn clean_use_statement( - import: &hir::Item<'_>, +fn clean_use_statement<'tcx>( + import: &hir::Item<'tcx>, name: Symbol, - path: &hir::Path<'_>, + path: &hir::Path<'tcx>, kind: hir::UseKind, - cx: &mut DocContext<'_>, + cx: &mut DocContext<'tcx>, + inlined_names: &mut FxHashSet<(ItemType, Symbol)>, ) -> Vec { // We need this comparison because some imports (for std types for example) // are "inserted" as well but directly by the compiler and they should not be @@ -2120,7 +2171,8 @@ fn clean_use_statement( let inner = if kind == hir::UseKind::Glob { if !denied { let mut visited = FxHashSet::default(); - if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) { + if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited, inlined_names) + { return items; } } @@ -2163,15 +2215,15 @@ fn clean_use_statement( vec![Item::from_def_id_and_parts(import.def_id.to_def_id(), None, ImportItem(inner), cx)] } -fn clean_maybe_renamed_foreign_item( - cx: &mut DocContext<'_>, - item: &hir::ForeignItem<'_>, +fn clean_maybe_renamed_foreign_item<'tcx>( + cx: &mut DocContext<'tcx>, + item: &hir::ForeignItem<'tcx>, renamed: Option, ) -> Item { let def_id = item.def_id.to_def_id(); cx.with_param_env(def_id, |cx| { let kind = match item.kind { - hir::ForeignItemKind::Fn(decl, names, ref generics) => { + hir::ForeignItemKind::Fn(decl, names, generics) => { let (generics, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args let generics = generics.clean(cx); @@ -2181,7 +2233,7 @@ fn clean_maybe_renamed_foreign_item( }); ForeignFunctionItem(Function { decl, generics }) } - hir::ForeignItemKind::Static(ref ty, mutability) => { + hir::ForeignItemKind::Static(ty, mutability) => { ForeignStaticItem(Static { type_: ty.clean(cx), mutability, expr: None }) } hir::ForeignItemKind::Type => ForeignTypeItem, @@ -2196,8 +2248,8 @@ fn clean_maybe_renamed_foreign_item( }) } -impl Clean for hir::TypeBinding<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> TypeBinding { +impl<'tcx> Clean<'tcx, TypeBinding> for hir::TypeBinding<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBinding { TypeBinding { assoc: PathSegment { name: self.ident.name, args: self.gen_args.clean(cx) }, kind: self.kind.clean(cx), @@ -2205,13 +2257,13 @@ impl Clean for hir::TypeBinding<'_> { } } -impl Clean for hir::TypeBindingKind<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind { +impl<'tcx> Clean<'tcx, TypeBindingKind> for hir::TypeBindingKind<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBindingKind { match *self { hir::TypeBindingKind::Equality { ref term } => { TypeBindingKind::Equality { term: term.clean(cx) } } - hir::TypeBindingKind::Constraint { ref bounds } => TypeBindingKind::Constraint { + hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint { bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(), }, } diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index a9c0fe6f07..f7700c4335 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -171,7 +171,7 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) { if state != Start && needs_space { printer.space(); } - print_tt(printer, &tt); + print_tt(printer, tt); state = next_state; } } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 194c25a795..af7813a774 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -21,7 +21,7 @@ use crate::clean::GenericArgs as PP; use crate::clean::WherePredicate as WP; use crate::core::DocContext; -crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> Vec { +pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> Vec { // First, partition the where clause into its separate components. // // We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to @@ -79,7 +79,7 @@ crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> Vec { clauses } -crate fn merge_bounds( +pub(crate) fn merge_bounds( cx: &clean::DocContext<'_>, bounds: &mut Vec, trait_did: DefId, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 456d860f12..2762d5e850 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1,10 +1,10 @@ use std::cell::RefCell; use std::default::Default; use std::hash::Hash; -use std::lazy::SyncOnceCell as OnceCell; use std::path::PathBuf; use std::rc::Rc; use std::sync::Arc; +use std::sync::OnceLock as OnceCell; use std::{cmp, fmt, iter}; use arrayvec::ArrayVec; @@ -44,22 +44,22 @@ use crate::formats::item_type::ItemType; use crate::html::render::Context; use crate::passes::collect_intra_doc_links::UrlFragment; -crate use self::FnRetTy::*; -crate use self::ItemKind::*; -crate use self::SelfTy::*; -crate use self::Type::{ +pub(crate) use self::FnRetTy::*; +pub(crate) use self::ItemKind::*; +pub(crate) use self::SelfTy::*; +pub(crate) use self::Type::{ Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath, RawPointer, Slice, Tuple, }; -crate use self::Visibility::{Inherited, Public}; +pub(crate) use self::Visibility::{Inherited, Public}; #[cfg(test)] mod tests; -crate type ItemIdSet = FxHashSet; +pub(crate) type ItemIdSet = FxHashSet; #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)] -crate enum ItemId { +pub(crate) enum ItemId { /// A "normal" item that uses a [`DefId`] for identification. DefId(DefId), /// Identifier that is used for auto traits. @@ -72,7 +72,7 @@ crate enum ItemId { impl ItemId { #[inline] - crate fn is_local(self) -> bool { + pub(crate) fn is_local(self) -> bool { match self { ItemId::Auto { for_: id, .. } | ItemId::Blanket { for_: id, .. } @@ -83,13 +83,13 @@ impl ItemId { #[inline] #[track_caller] - crate fn expect_def_id(self) -> DefId { + pub(crate) fn expect_def_id(self) -> DefId { self.as_def_id() .unwrap_or_else(|| panic!("ItemId::expect_def_id: `{:?}` isn't a DefId", self)) } #[inline] - crate fn as_def_id(self) -> Option { + pub(crate) fn as_def_id(self) -> Option { match self { ItemId::DefId(id) => Some(id), _ => None, @@ -97,7 +97,7 @@ impl ItemId { } #[inline] - crate fn krate(self) -> CrateNum { + pub(crate) fn krate(self) -> CrateNum { match self { ItemId::Auto { for_: id, .. } | ItemId::Blanket { for_: id, .. } @@ -115,11 +115,11 @@ impl From for ItemId { /// The crate currently being documented. #[derive(Clone, Debug)] -crate struct Crate { - crate module: Item, - crate primitives: ThinVec<(DefId, PrimitiveType)>, +pub(crate) struct Crate { + pub(crate) module: Item, + pub(crate) primitives: ThinVec<(DefId, PrimitiveType)>, /// Only here so that they can be filtered through the rustdoc passes. - crate external_traits: Rc>>, + pub(crate) external_traits: Rc>>, } // `Crate` is frequently moved by-value. Make sure it doesn't unintentionally get bigger. @@ -127,45 +127,45 @@ crate struct Crate { rustc_data_structures::static_assert_size!(Crate, 72); impl Crate { - crate fn name(&self, tcx: TyCtxt<'_>) -> Symbol { + pub(crate) fn name(&self, tcx: TyCtxt<'_>) -> Symbol { ExternalCrate::LOCAL.name(tcx) } - crate fn src(&self, tcx: TyCtxt<'_>) -> FileName { + pub(crate) fn src(&self, tcx: TyCtxt<'_>) -> FileName { ExternalCrate::LOCAL.src(tcx) } } /// This struct is used to wrap additional information added by rustdoc on a `trait` item. #[derive(Clone, Debug)] -crate struct TraitWithExtraInfo { - crate trait_: Trait, - crate is_notable: bool, +pub(crate) struct TraitWithExtraInfo { + pub(crate) trait_: Trait, + pub(crate) is_notable: bool, } #[derive(Copy, Clone, Debug)] -crate struct ExternalCrate { - crate crate_num: CrateNum, +pub(crate) struct ExternalCrate { + pub(crate) crate_num: CrateNum, } impl ExternalCrate { const LOCAL: Self = Self { crate_num: LOCAL_CRATE }; #[inline] - crate fn def_id(&self) -> DefId { + pub(crate) fn def_id(&self) -> DefId { self.crate_num.as_def_id() } - crate fn src(&self, tcx: TyCtxt<'_>) -> FileName { + pub(crate) fn src(&self, tcx: TyCtxt<'_>) -> FileName { let krate_span = tcx.def_span(self.def_id()); tcx.sess.source_map().span_to_filename(krate_span) } - crate fn name(&self, tcx: TyCtxt<'_>) -> Symbol { + pub(crate) fn name(&self, tcx: TyCtxt<'_>) -> Symbol { tcx.crate_name(self.crate_num) } - crate fn src_root(&self, tcx: TyCtxt<'_>) -> PathBuf { + pub(crate) fn src_root(&self, tcx: TyCtxt<'_>) -> PathBuf { match self.src(tcx) { FileName::Real(ref p) => match p.local_path_if_available().parent() { Some(p) => p.to_path_buf(), @@ -177,7 +177,7 @@ impl ExternalCrate { /// Attempts to find where an external crate is located, given that we're /// rendering in to the specified source destination. - crate fn location( + pub(crate) fn location( &self, extern_url: Option<&str>, extern_url_takes_precedence: bool, @@ -221,7 +221,7 @@ impl ExternalCrate { .unwrap_or(Unknown) // Well, at least we tried. } - crate fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> { + pub(crate) fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> { let root = self.def_id(); let as_keyword = |res: Res| { @@ -268,7 +268,7 @@ impl ExternalCrate { } } - crate fn primitives(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, PrimitiveType)> { + pub(crate) fn primitives(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, PrimitiveType)> { let root = self.def_id(); // Collect all inner modules which are tagged as implementations of @@ -341,7 +341,7 @@ impl ExternalCrate { /// Indicates where an external crate can be found. #[derive(Debug)] -crate enum ExternalLocation { +pub(crate) enum ExternalLocation { /// Remote URL root of the external crate Remote(String), /// This external crate can be found in the local doc/ folder @@ -354,18 +354,18 @@ crate enum ExternalLocation { /// name. That is, anything that can be documented. This doesn't correspond /// directly to the AST's concept of an item; it's a strict superset. #[derive(Clone)] -crate struct Item { +pub(crate) struct Item { /// The name of this item. /// Optional because not every item has a name, e.g. impls. - crate name: Option, - crate attrs: Box, - crate visibility: Visibility, + pub(crate) name: Option, + pub(crate) attrs: Box, + pub(crate) visibility: Visibility, /// Information about this item that is specific to what kind of item it is. /// E.g., struct vs enum vs function. - crate kind: Box, - crate item_id: ItemId, + pub(crate) kind: Box, + pub(crate) item_id: ItemId, - crate cfg: Option>, + pub(crate) cfg: Option>, } /// NOTE: this does NOT unconditionally print every item, to avoid thousands of lines of logs. @@ -393,7 +393,7 @@ impl fmt::Debug for Item { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] rustc_data_structures::static_assert_size!(Item, 56); -crate fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span { +pub(crate) fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span { Span::new(def_id.as_local().map_or_else( || tcx.def_span(def_id), |local| { @@ -404,26 +404,26 @@ crate fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span { } impl Item { - crate fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { + pub(crate) fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { self.item_id.as_def_id().and_then(|did| tcx.lookup_stability(did)) } - crate fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { + pub(crate) fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { self.item_id.as_def_id().and_then(|did| tcx.lookup_const_stability(did)) } - crate fn deprecation(&self, tcx: TyCtxt<'_>) -> Option { + pub(crate) fn deprecation(&self, tcx: TyCtxt<'_>) -> Option { self.item_id.as_def_id().and_then(|did| tcx.lookup_deprecation(did)) } - crate fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool { + pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool { self.item_id .as_def_id() .map(|did| tcx.get_attrs_unchecked(did).inner_docs()) .unwrap_or(false) } - crate fn span(&self, tcx: TyCtxt<'_>) -> Span { + pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Span { let kind = match &*self.kind { ItemKind::StrippedItem(k) => k, _ => &*self.kind, @@ -444,19 +444,19 @@ impl Item { } } - crate fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span { + pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span { crate::passes::span_of_attrs(&self.attrs).unwrap_or_else(|| self.span(tcx).inner()) } /// Finds the `doc` attribute as a NameValue and returns the corresponding /// value found. - crate fn doc_value(&self) -> Option { + pub(crate) fn doc_value(&self) -> Option { self.attrs.doc_value() } /// Convenience wrapper around [`Self::from_def_id_and_parts`] which converts /// `hir_id` to a [`DefId`] - crate fn from_hir_id_and_parts( + pub(crate) fn from_hir_id_and_parts( hir_id: hir::HirId, name: Option, kind: ItemKind, @@ -465,7 +465,7 @@ impl Item { Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx) } - crate fn from_def_id_and_parts( + pub(crate) fn from_def_id_and_parts( def_id: DefId, name: Option, kind: ItemKind, @@ -483,7 +483,7 @@ impl Item { ) } - crate fn from_def_id_and_attrs_and_parts( + pub(crate) fn from_def_id_and_attrs_and_parts( def_id: DefId, name: Option, kind: ItemKind, @@ -508,11 +508,11 @@ impl Item { /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined /// with newlines. - crate fn collapsed_doc_value(&self) -> Option { + pub(crate) fn collapsed_doc_value(&self) -> Option { self.attrs.collapsed_doc_value() } - crate fn links(&self, cx: &Context<'_>) -> Vec { + pub(crate) fn links(&self, cx: &Context<'_>) -> Vec { use crate::html::format::href; cx.cache() @@ -525,7 +525,7 @@ impl Item { if let Ok((mut href, ..)) = href(*did, cx) { debug!(?href); if let Some(ref fragment) = *fragment { - fragment.render(&mut href, cx.tcx()).unwrap() + fragment.render(&mut href, cx.tcx()) } Some(RenderedLink { original_text: s.clone(), @@ -544,7 +544,7 @@ impl Item { /// This is used for generating summary text, which does not include /// the link text, but does need to know which `[]`-bracketed names /// are actually links. - crate fn link_names(&self, cache: &Cache) -> Vec { + pub(crate) fn link_names(&self, cache: &Cache) -> Vec { cache .intra_doc_links .get(&self.item_id) @@ -558,81 +558,82 @@ impl Item { .collect() } - crate fn is_crate(&self) -> bool { + pub(crate) fn is_crate(&self) -> bool { self.is_mod() && self.item_id.as_def_id().map_or(false, |did| did.is_crate_root()) } - crate fn is_mod(&self) -> bool { + pub(crate) fn is_mod(&self) -> bool { self.type_() == ItemType::Module } - crate fn is_trait(&self) -> bool { + pub(crate) fn is_trait(&self) -> bool { self.type_() == ItemType::Trait } - crate fn is_struct(&self) -> bool { + pub(crate) fn is_struct(&self) -> bool { self.type_() == ItemType::Struct } - crate fn is_enum(&self) -> bool { + pub(crate) fn is_enum(&self) -> bool { self.type_() == ItemType::Enum } - crate fn is_variant(&self) -> bool { + pub(crate) fn is_variant(&self) -> bool { self.type_() == ItemType::Variant } - crate fn is_associated_type(&self) -> bool { + pub(crate) fn is_associated_type(&self) -> bool { matches!(&*self.kind, AssocTypeItem(..) | StrippedItem(box AssocTypeItem(..))) } - crate fn is_ty_associated_type(&self) -> bool { + pub(crate) fn is_ty_associated_type(&self) -> bool { matches!(&*self.kind, TyAssocTypeItem(..) | StrippedItem(box TyAssocTypeItem(..))) } - crate fn is_associated_const(&self) -> bool { + pub(crate) fn is_associated_const(&self) -> bool { matches!(&*self.kind, AssocConstItem(..) | StrippedItem(box AssocConstItem(..))) } - crate fn is_ty_associated_const(&self) -> bool { + pub(crate) fn is_ty_associated_const(&self) -> bool { matches!(&*self.kind, TyAssocConstItem(..) | StrippedItem(box TyAssocConstItem(..))) } - crate fn is_method(&self) -> bool { + pub(crate) fn is_method(&self) -> bool { self.type_() == ItemType::Method } - crate fn is_ty_method(&self) -> bool { + pub(crate) fn is_ty_method(&self) -> bool { self.type_() == ItemType::TyMethod } - crate fn is_typedef(&self) -> bool { + pub(crate) fn is_typedef(&self) -> bool { self.type_() == ItemType::Typedef } - crate fn is_primitive(&self) -> bool { + pub(crate) fn is_primitive(&self) -> bool { self.type_() == ItemType::Primitive } - crate fn is_union(&self) -> bool { + pub(crate) fn is_union(&self) -> bool { self.type_() == ItemType::Union } - crate fn is_import(&self) -> bool { + pub(crate) fn is_import(&self) -> bool { self.type_() == ItemType::Import } - crate fn is_extern_crate(&self) -> bool { + pub(crate) fn is_extern_crate(&self) -> bool { self.type_() == ItemType::ExternCrate } - crate fn is_keyword(&self) -> bool { + pub(crate) fn is_keyword(&self) -> bool { self.type_() == ItemType::Keyword } - crate fn is_stripped(&self) -> bool { + pub(crate) fn is_stripped(&self) -> bool { match *self.kind { StrippedItem(..) => true, ImportItem(ref i) => !i.should_be_displayed, _ => false, } } - crate fn has_stripped_fields(&self) -> Option { + pub(crate) fn has_stripped_entries(&self) -> Option { match *self.kind { - StructItem(ref _struct) => Some(_struct.fields_stripped), - UnionItem(ref union) => Some(union.fields_stripped), - VariantItem(Variant::Struct(ref vstruct)) => Some(vstruct.fields_stripped), + StructItem(ref struct_) => Some(struct_.has_stripped_entries()), + UnionItem(ref union_) => Some(union_.has_stripped_entries()), + EnumItem(ref enum_) => Some(enum_.has_stripped_entries()), + VariantItem(ref v) => v.has_stripped_entries(), _ => None, } } - crate fn stability_class(&self, tcx: TyCtxt<'_>) -> Option { + pub(crate) fn stability_class(&self, tcx: TyCtxt<'_>) -> Option { self.stability(tcx).as_ref().and_then(|s| { let mut classes = Vec::with_capacity(2); - if s.level.is_unstable() { + if s.is_unstable() { classes.push("unstable"); } @@ -645,30 +646,30 @@ impl Item { }) } - crate fn stable_since(&self, tcx: TyCtxt<'_>) -> Option { + pub(crate) fn stable_since(&self, tcx: TyCtxt<'_>) -> Option { match self.stability(tcx)?.level { StabilityLevel::Stable { since, .. } => Some(since), StabilityLevel::Unstable { .. } => None, } } - crate fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option { + pub(crate) fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option { match self.const_stability(tcx)?.level { StabilityLevel::Stable { since, .. } => Some(since), StabilityLevel::Unstable { .. } => None, } } - crate fn is_non_exhaustive(&self) -> bool { + pub(crate) fn is_non_exhaustive(&self) -> bool { self.attrs.other_attrs.iter().any(|a| a.has_name(sym::non_exhaustive)) } /// Returns a documentation-level item type from the item. - crate fn type_(&self) -> ItemType { + pub(crate) fn type_(&self) -> ItemType { ItemType::from(self) } - crate fn is_default(&self) -> bool { + pub(crate) fn is_default(&self) -> bool { match *self.kind { ItemKind::MethodItem(_, Some(defaultness)) => { defaultness.has_value() && !defaultness.is_final() @@ -678,7 +679,7 @@ impl Item { } /// Returns a `FnHeader` if `self` is a function item, otherwise returns `None`. - crate fn fn_header(&self, tcx: TyCtxt<'_>) -> Option { + pub(crate) fn fn_header(&self, tcx: TyCtxt<'_>) -> Option { fn build_fn_header( def_id: DefId, tcx: TyCtxt<'_>, @@ -721,7 +722,7 @@ impl Item { } #[derive(Clone, Debug)] -crate enum ItemKind { +pub(crate) enum ItemKind { ExternCrateItem { /// The crate's name, *not* the name it's imported as. src: Option, @@ -774,7 +775,7 @@ crate enum ItemKind { impl ItemKind { /// Some items contain others such as structs (for their fields) and Enums /// (for their variants). This method returns those contained items. - crate fn inner_items(&self) -> impl Iterator { + pub(crate) fn inner_items(&self) -> impl Iterator { match self { StructItem(s) => s.fields.iter(), UnionItem(u) => u.fields.iter(), @@ -813,12 +814,12 @@ impl ItemKind { } #[derive(Clone, Debug)] -crate struct Module { - crate items: Vec, - crate span: Span, +pub(crate) struct Module { + pub(crate) items: Vec, + pub(crate) span: Span, } -crate trait AttributesExt { +pub(crate) trait AttributesExt { type AttributeIterator<'a>: Iterator where Self: 'a; @@ -879,7 +880,7 @@ impl AttributesExt for [ast::Attribute] { let mut doc_cfg = self .iter() .filter(|attr| attr.has_name(sym::doc)) - .flat_map(|attr| attr.meta_item_list().unwrap_or_else(Vec::new)) + .flat_map(|attr| attr.meta_item_list().unwrap_or_default()) .filter(|attr| attr.has_name(sym::cfg)) .peekable(); if doc_cfg.peek().is_some() && doc_cfg_active { @@ -949,7 +950,7 @@ impl AttributesExt for [ast::Attribute] { } } -crate trait NestedAttributesExt { +pub(crate) trait NestedAttributesExt { /// Returns `true` if the attribute list contains a specific `word` fn has_word(self, word: Symbol) -> bool where @@ -978,24 +979,24 @@ impl> NestedAttributesExt for I { /// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are /// kept separate because of issue #42760. #[derive(Clone, PartialEq, Eq, Debug)] -crate struct DocFragment { - crate span: rustc_span::Span, +pub(crate) struct DocFragment { + pub(crate) span: rustc_span::Span, /// The module this doc-comment came from. /// /// This allows distinguishing between the original documentation and a pub re-export. /// If it is `None`, the item was not re-exported. - crate parent_module: Option, - crate doc: Symbol, - crate kind: DocFragmentKind, - crate indent: usize, + pub(crate) parent_module: Option, + pub(crate) doc: Symbol, + pub(crate) kind: DocFragmentKind, + pub(crate) indent: usize, } // `DocFragment` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] rustc_data_structures::static_assert_size!(DocFragment, 32); -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] -crate enum DocFragmentKind { +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub(crate) enum DocFragmentKind { /// A doc fragment created from a `///` or `//!` doc comment. SugaredDoc, /// A doc fragment created from a "raw" `#[doc=""]` attribute. @@ -1010,7 +1011,7 @@ crate enum DocFragmentKind { fn add_doc_fragment(out: &mut String, frag: &DocFragment) { let s = frag.doc.as_str(); let mut iter = s.lines(); - if s == "" { + if s.is_empty() { out.push('\n'); return; } @@ -1027,7 +1028,7 @@ fn add_doc_fragment(out: &mut String, frag: &DocFragment) { /// Collapse a collection of [`DocFragment`]s into one string, /// handling indentation and newlines as needed. -crate fn collapse_doc_fragments(doc_strings: &[DocFragment]) -> String { +pub(crate) fn collapse_doc_fragments(doc_strings: &[DocFragment]) -> String { let mut acc = String::new(); for frag in doc_strings { add_doc_fragment(&mut acc, frag); @@ -1120,44 +1121,44 @@ fn unindent_doc_fragments(docs: &mut Vec) { /// /// This link will be turned into a rendered link by [`Item::links`]. #[derive(Clone, Debug, PartialEq, Eq)] -crate struct ItemLink { +pub(crate) struct ItemLink { /// The original link written in the markdown - crate link: String, + pub(crate) link: String, /// The link text displayed in the HTML. /// /// This may not be the same as `link` if there was a disambiguator /// in an intra-doc link (e.g. \[`fn@f`\]) - crate link_text: String, - crate did: DefId, + pub(crate) link_text: String, + pub(crate) did: DefId, /// The url fragment to append to the link - crate fragment: Option, + pub(crate) fragment: Option, } pub struct RenderedLink { /// The text the link was original written as. /// /// This could potentially include disambiguators and backticks. - crate original_text: String, + pub(crate) original_text: String, /// The text to display in the HTML - crate new_text: String, + pub(crate) new_text: String, /// The URL to put in the `href` - crate href: String, + pub(crate) href: String, } /// The attributes on an [`Item`], including attributes like `#[derive(...)]` and `#[inline]`, /// as well as doc comments. #[derive(Clone, Debug, Default)] -crate struct Attributes { - crate doc_strings: Vec, - crate other_attrs: Vec, +pub(crate) struct Attributes { + pub(crate) doc_strings: Vec, + pub(crate) other_attrs: Vec, } impl Attributes { - crate fn lists(&self, name: Symbol) -> impl Iterator + '_ { + pub(crate) fn lists(&self, name: Symbol) -> impl Iterator + '_ { self.other_attrs.lists(name) } - crate fn has_doc_flag(&self, flag: Symbol) -> bool { + pub(crate) fn has_doc_flag(&self, flag: Symbol) -> bool { for attr in &self.other_attrs { if !attr.has_name(sym::doc) { continue; @@ -1173,7 +1174,7 @@ impl Attributes { false } - crate fn from_ast( + pub(crate) fn from_ast( attrs: &[ast::Attribute], additional_attrs: Option<(&[ast::Attribute], DefId)>, ) -> Attributes { @@ -1185,7 +1186,7 @@ impl Attributes { Attributes::from_ast_iter(attrs1.chain(attrs2), false) } - crate fn from_ast_iter<'a>( + pub(crate) fn from_ast_iter<'a>( attrs: impl Iterator)>, doc_only: bool, ) -> Attributes { @@ -1214,7 +1215,7 @@ impl Attributes { /// Finds the `doc` attribute as a NameValue and returns the corresponding /// value found. - crate fn doc_value(&self) -> Option { + pub(crate) fn doc_value(&self) -> Option { let mut iter = self.doc_strings.iter(); let ori = iter.next()?; @@ -1232,7 +1233,7 @@ impl Attributes { /// /// The last newline is not trimmed so the produced strings are reusable between /// early and late doc link resolution regardless of their position. - crate fn prepare_to_doc_link_resolution(&self) -> FxHashMap, String> { + pub(crate) fn prepare_to_doc_link_resolution(&self) -> FxHashMap, String> { let mut res = FxHashMap::default(); for fragment in &self.doc_strings { let out_str = res.entry(fragment.parent_module).or_default(); @@ -1243,7 +1244,7 @@ impl Attributes { /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined /// with newlines. - crate fn collapsed_doc_value(&self) -> Option { + pub(crate) fn collapsed_doc_value(&self) -> Option { if self.doc_strings.is_empty() { None } else { @@ -1251,7 +1252,7 @@ impl Attributes { } } - crate fn get_doc_aliases(&self) -> Box<[Symbol]> { + pub(crate) fn get_doc_aliases(&self) -> Box<[Symbol]> { let mut aliases = FxHashSet::default(); for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) { @@ -1286,13 +1287,13 @@ impl PartialEq for Attributes { impl Eq for Attributes {} #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate enum GenericBound { +pub(crate) enum GenericBound { TraitBound(PolyTrait, hir::TraitBoundModifier), Outlives(Lifetime), } impl GenericBound { - crate fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound { + pub(crate) fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound { let did = cx.tcx.require_lang_item(LangItem::Sized, None); let empty = cx.tcx.intern_substs(&[]); let path = external_path(cx, did, false, vec![], empty); @@ -1303,7 +1304,7 @@ impl GenericBound { ) } - crate fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool { + pub(crate) fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool { use rustc_hir::TraitBoundModifier as TBM; if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self { if Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() { @@ -1313,14 +1314,14 @@ impl GenericBound { false } - crate fn get_poly_trait(&self) -> Option { + pub(crate) fn get_poly_trait(&self) -> Option { if let GenericBound::TraitBound(ref p, _) = *self { return Some(p.clone()); } None } - crate fn get_trait_path(&self) -> Option { + pub(crate) fn get_trait_path(&self) -> Option { if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self { Some(trait_.clone()) } else { @@ -1330,27 +1331,27 @@ impl GenericBound { } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct Lifetime(pub Symbol); +pub(crate) struct Lifetime(pub Symbol); impl Lifetime { - crate fn statik() -> Lifetime { + pub(crate) fn statik() -> Lifetime { Lifetime(kw::StaticLifetime) } - crate fn elided() -> Lifetime { + pub(crate) fn elided() -> Lifetime { Lifetime(kw::UnderscoreLifetime) } } #[derive(Clone, Debug)] -crate enum WherePredicate { +pub(crate) enum WherePredicate { BoundPredicate { ty: Type, bounds: Vec, bound_params: Vec }, RegionPredicate { lifetime: Lifetime, bounds: Vec }, EqPredicate { lhs: Type, rhs: Term }, } impl WherePredicate { - crate fn get_bounds(&self) -> Option<&[GenericBound]> { + pub(crate) fn get_bounds(&self) -> Option<&[GenericBound]> { match *self { WherePredicate::BoundPredicate { ref bounds, .. } => Some(bounds), WherePredicate::RegionPredicate { ref bounds, .. } => Some(bounds), @@ -1360,22 +1361,22 @@ impl WherePredicate { } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate enum GenericParamDefKind { +pub(crate) enum GenericParamDefKind { Lifetime { outlives: Vec }, Type { did: DefId, bounds: Vec, default: Option>, synthetic: bool }, Const { did: DefId, ty: Box, default: Option> }, } impl GenericParamDefKind { - crate fn is_type(&self) -> bool { + pub(crate) fn is_type(&self) -> bool { matches!(self, GenericParamDefKind::Type { .. }) } } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct GenericParamDef { - crate name: Symbol, - crate kind: GenericParamDefKind, +pub(crate) struct GenericParamDef { + pub(crate) name: Symbol, + pub(crate) kind: GenericParamDefKind, } // `GenericParamDef` is used in many places. Make sure it doesn't unintentionally get bigger. @@ -1383,18 +1384,18 @@ crate struct GenericParamDef { rustc_data_structures::static_assert_size!(GenericParamDef, 56); impl GenericParamDef { - crate fn is_synthetic_type_param(&self) -> bool { + pub(crate) fn is_synthetic_type_param(&self) -> bool { match self.kind { GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false, GenericParamDefKind::Type { synthetic, .. } => synthetic, } } - crate fn is_type(&self) -> bool { + pub(crate) fn is_type(&self) -> bool { self.kind.is_type() } - crate fn get_bounds(&self) -> Option<&[GenericBound]> { + pub(crate) fn get_bounds(&self) -> Option<&[GenericBound]> { match self.kind { GenericParamDefKind::Type { ref bounds, .. } => Some(bounds), _ => None, @@ -1404,26 +1405,32 @@ impl GenericParamDef { // maybe use a Generic enum and use Vec? #[derive(Clone, Debug, Default)] -crate struct Generics { - crate params: Vec, - crate where_predicates: Vec, +pub(crate) struct Generics { + pub(crate) params: Vec, + pub(crate) where_predicates: Vec, +} + +impl Generics { + pub(crate) fn is_empty(&self) -> bool { + self.params.is_empty() && self.where_predicates.is_empty() + } } #[derive(Clone, Debug)] -crate struct Function { - crate decl: FnDecl, - crate generics: Generics, +pub(crate) struct Function { + pub(crate) decl: FnDecl, + pub(crate) generics: Generics, } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct FnDecl { - crate inputs: Arguments, - crate output: FnRetTy, - crate c_variadic: bool, +pub(crate) struct FnDecl { + pub(crate) inputs: Arguments, + pub(crate) output: FnRetTy, + pub(crate) c_variadic: bool, } impl FnDecl { - crate fn self_type(&self) -> Option { + pub(crate) fn self_type(&self) -> Option { self.inputs.values.get(0).and_then(|v| v.to_self()) } @@ -1436,7 +1443,7 @@ impl FnDecl { /// /// This function will panic if the return type does not match the expected sugaring for async /// functions. - crate fn sugared_async_return_type(&self) -> FnRetTy { + pub(crate) fn sugared_async_return_type(&self) -> FnRetTy { match &self.output { FnRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] { GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => { @@ -1453,28 +1460,28 @@ impl FnDecl { } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct Arguments { - crate values: Vec, +pub(crate) struct Arguments { + pub(crate) values: Vec, } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct Argument { - crate type_: Type, - crate name: Symbol, +pub(crate) struct Argument { + pub(crate) type_: Type, + pub(crate) name: Symbol, /// This field is used to represent "const" arguments from the `rustc_legacy_const_generics` /// feature. More information in . - crate is_const: bool, + pub(crate) is_const: bool, } #[derive(Clone, PartialEq, Debug)] -crate enum SelfTy { +pub(crate) enum SelfTy { SelfValue, SelfBorrowed(Option, Mutability), SelfExplicit(Type), } impl Argument { - crate fn to_self(&self) -> Option { + pub(crate) fn to_self(&self) -> Option { if self.name != kw::SelfLower { return None; } @@ -1491,13 +1498,13 @@ impl Argument { } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate enum FnRetTy { +pub(crate) enum FnRetTy { Return(Type), DefaultReturn, } impl FnRetTy { - crate fn as_return(&self) -> Option<&Type> { + pub(crate) fn as_return(&self) -> Option<&Type> { match self { Return(ret) => Some(ret), DefaultReturn => None, @@ -1506,30 +1513,30 @@ impl FnRetTy { } #[derive(Clone, Debug)] -crate struct Trait { - crate unsafety: hir::Unsafety, - crate items: Vec, - crate generics: Generics, - crate bounds: Vec, - crate is_auto: bool, +pub(crate) struct Trait { + pub(crate) unsafety: hir::Unsafety, + pub(crate) items: Vec, + pub(crate) generics: Generics, + pub(crate) bounds: Vec, + pub(crate) is_auto: bool, } #[derive(Clone, Debug)] -crate struct TraitAlias { - crate generics: Generics, - crate bounds: Vec, +pub(crate) struct TraitAlias { + pub(crate) generics: Generics, + pub(crate) bounds: Vec, } /// A trait reference, which may have higher ranked lifetimes. #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct PolyTrait { - crate trait_: Path, - crate generic_params: Vec, +pub(crate) struct PolyTrait { + pub(crate) trait_: Path, + pub(crate) generic_params: Vec, } /// Rustdoc's representation of types, mostly based on the [`hir::Ty`]. #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate enum Type { +pub(crate) enum Type { /// A named type, which could be a trait. /// /// This is mostly Rustdoc's version of [`hir::Path`]. @@ -1560,10 +1567,8 @@ crate enum Type { QPath { assoc: Box, self_type: Box, - /// FIXME: This is a hack that should be removed; see [this discussion][1]. - /// - /// [1]: https://github.com/rust-lang/rust/pull/85479#discussion_r635729093 - self_def_id: Option, + /// FIXME: compute this field on demand. + should_show_cast: bool, trait_: Path, }, @@ -1576,11 +1581,11 @@ crate enum Type { // `Type` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Type, 80); +rustc_data_structures::static_assert_size!(Type, 72); impl Type { /// When comparing types for equality, it can help to ignore `&` wrapping. - crate fn without_borrowed_ref(&self) -> &Type { + pub(crate) fn without_borrowed_ref(&self) -> &Type { let mut result = self; while let Type::BorrowedRef { type_, .. } = result { result = &*type_; @@ -1591,21 +1596,21 @@ impl Type { /// Check if two types are "potentially the same". /// This is different from `Eq`, because it knows that things like /// `Placeholder` are possible matches for everything. - crate fn is_same(&self, other: &Self, cache: &Cache) -> bool { + pub(crate) fn is_same(&self, other: &Self, cache: &Cache) -> bool { match (self, other) { // Recursive cases. (Type::Tuple(a), Type::Tuple(b)) => { - a.len() == b.len() && a.iter().zip(b).all(|(a, b)| a.is_same(&b, cache)) + a.len() == b.len() && a.iter().zip(b).all(|(a, b)| a.is_same(b, cache)) } - (Type::Slice(a), Type::Slice(b)) => a.is_same(&b, cache), - (Type::Array(a, al), Type::Array(b, bl)) => al == bl && a.is_same(&b, cache), + (Type::Slice(a), Type::Slice(b)) => a.is_same(b, cache), + (Type::Array(a, al), Type::Array(b, bl)) => al == bl && a.is_same(b, cache), (Type::RawPointer(mutability, type_), Type::RawPointer(b_mutability, b_type_)) => { - mutability == b_mutability && type_.is_same(&b_type_, cache) + mutability == b_mutability && type_.is_same(b_type_, cache) } ( Type::BorrowedRef { mutability, type_, .. }, Type::BorrowedRef { mutability: b_mutability, type_: b_type_, .. }, - ) => mutability == b_mutability && type_.is_same(&b_type_, cache), + ) => mutability == b_mutability && type_.is_same(b_type_, cache), // Placeholders and generics are equal to all other types. (Type::Infer, _) | (_, Type::Infer) => true, (Type::Generic(_), _) | (_, Type::Generic(_)) => true, @@ -1618,7 +1623,7 @@ impl Type { } } - crate fn primitive_type(&self) -> Option { + pub(crate) fn primitive_type(&self) -> Option { match *self { Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p), Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice), @@ -1637,38 +1642,42 @@ impl Type { } /// Checks if this is a `T::Name` path for an associated type. - crate fn is_assoc_ty(&self) -> bool { + pub(crate) fn is_assoc_ty(&self) -> bool { match self { Type::Path { path, .. } => path.is_assoc_ty(), _ => false, } } - crate fn is_self_type(&self) -> bool { + pub(crate) fn is_self_type(&self) -> bool { match *self { Generic(name) => name == kw::SelfUpper, _ => false, } } - crate fn generics(&self) -> Option> { + pub(crate) fn generics(&self) -> Option> { match self { Type::Path { path, .. } => path.generics(), _ => None, } } - crate fn is_full_generic(&self) -> bool { + pub(crate) fn is_full_generic(&self) -> bool { matches!(self, Type::Generic(_)) } - crate fn is_primitive(&self) -> bool { + pub(crate) fn is_impl_trait(&self) -> bool { + matches!(self, Type::ImplTrait(_)) + } + + pub(crate) fn is_primitive(&self) -> bool { self.primitive_type().is_some() } - crate fn projection(&self) -> Option<(&Type, DefId, PathSegment)> { + pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> { if let QPath { self_type, trait_, assoc, .. } = self { - Some((&self_type, trait_.def_id(), *assoc.clone())) + Some((self_type, trait_.def_id(), *assoc.clone())) } else { None } @@ -1701,7 +1710,7 @@ impl Type { /// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s. /// /// [clean]: crate::clean - crate fn def_id(&self, cache: &Cache) -> Option { + pub(crate) fn def_id(&self, cache: &Cache) -> Option { self.inner_def_id(Some(cache)) } } @@ -1713,7 +1722,7 @@ impl Type { /// N.B. This has to be different from [`hir::PrimTy`] because it also includes types that aren't /// paths, like [`Self::Unit`]. #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)] -crate enum PrimitiveType { +pub(crate) enum PrimitiveType { Isize, I8, I16, @@ -1741,9 +1750,9 @@ crate enum PrimitiveType { Never, } -type SimplifiedTypes = FxHashMap>; +type SimplifiedTypes = FxHashMap>; impl PrimitiveType { - crate fn from_hir(prim: hir::PrimTy) -> PrimitiveType { + pub(crate) fn from_hir(prim: hir::PrimTy) -> PrimitiveType { use ast::{FloatTy, IntTy, UintTy}; match prim { hir::PrimTy::Int(IntTy::Isize) => PrimitiveType::Isize, @@ -1766,7 +1775,7 @@ impl PrimitiveType { } } - crate fn from_symbol(s: Symbol) -> Option { + pub(crate) fn from_symbol(s: Symbol) -> Option { match s { sym::isize => Some(PrimitiveType::Isize), sym::i8 => Some(PrimitiveType::I8), @@ -1797,7 +1806,7 @@ impl PrimitiveType { } } - crate fn simplified_types() -> &'static SimplifiedTypes { + pub(crate) fn simplified_types() -> &'static SimplifiedTypes { use ty::fast_reject::SimplifiedTypeGen::*; use ty::{FloatTy, IntTy, UintTy}; use PrimitiveType::*; @@ -1830,10 +1839,10 @@ impl PrimitiveType { // // Either manually update this arrayvec at this point // or start with a more complex refactoring. - Tuple => [TupleSimplifiedType(2), TupleSimplifiedType(3)].into(), + Tuple => [TupleSimplifiedType(1), TupleSimplifiedType(2), TupleSimplifiedType(3)].into(), Unit => single(TupleSimplifiedType(0)), - RawPointer => [PtrSimplifiedType(Mutability::Not), PtrSimplifiedType(Mutability::Mut)].into(), - Reference => [RefSimplifiedType(Mutability::Not), RefSimplifiedType(Mutability::Mut)].into(), + RawPointer => [PtrSimplifiedType(Mutability::Not), PtrSimplifiedType(Mutability::Mut)].into_iter().collect(), + Reference => [RefSimplifiedType(Mutability::Not), RefSimplifiedType(Mutability::Mut)].into_iter().collect(), // FIXME: This will be wrong if we ever add inherent impls // for function pointers. Fn => ArrayVec::new(), @@ -1842,7 +1851,7 @@ impl PrimitiveType { }) } - crate fn impls<'tcx>(&self, tcx: TyCtxt<'tcx>) -> impl Iterator + 'tcx { + pub(crate) fn impls<'tcx>(&self, tcx: TyCtxt<'tcx>) -> impl Iterator + 'tcx { Self::simplified_types() .get(self) .into_iter() @@ -1851,7 +1860,7 @@ impl PrimitiveType { .copied() } - crate fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator + '_ { + pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator + '_ { Self::simplified_types() .values() .flatten() @@ -1859,7 +1868,7 @@ impl PrimitiveType { .copied() } - crate fn as_sym(&self) -> Symbol { + pub(crate) fn as_sym(&self) -> Symbol { use PrimitiveType::*; match self { Isize => sym::isize, @@ -1897,7 +1906,7 @@ impl PrimitiveType { /// but otherwise, if multiple crates define the same primitive, there is no guarantee of which will be picked. /// In particular, if a crate depends on both `std` and another crate that also defines `doc(primitive)`, then /// it's entirely random whether `std` or the other crate is picked. (no_std crates are usually fine unless multiple dependencies define a primitive.) - crate fn primitive_locations(tcx: TyCtxt<'_>) -> &FxHashMap { + pub(crate) fn primitive_locations(tcx: TyCtxt<'_>) -> &FxHashMap { static PRIMITIVE_LOCATIONS: OnceCell> = OnceCell::new(); PRIMITIVE_LOCATIONS.get_or_init(|| { let mut primitive_locations = FxHashMap::default(); @@ -2008,7 +2017,7 @@ impl From for PrimitiveType { } #[derive(Copy, Clone, Debug)] -crate enum Visibility { +pub(crate) enum Visibility { /// `pub` Public, /// Visibility inherited from parent. @@ -2020,110 +2029,143 @@ crate enum Visibility { } impl Visibility { - crate fn is_public(&self) -> bool { + pub(crate) fn is_public(&self) -> bool { matches!(self, Visibility::Public) } } #[derive(Clone, Debug)] -crate struct Struct { - crate struct_type: CtorKind, - crate generics: Generics, - crate fields: Vec, - crate fields_stripped: bool, +pub(crate) struct Struct { + pub(crate) struct_type: CtorKind, + pub(crate) generics: Generics, + pub(crate) fields: Vec, +} + +impl Struct { + pub(crate) fn has_stripped_entries(&self) -> bool { + self.fields.iter().any(|f| f.is_stripped()) + } } #[derive(Clone, Debug)] -crate struct Union { - crate generics: Generics, - crate fields: Vec, - crate fields_stripped: bool, +pub(crate) struct Union { + pub(crate) generics: Generics, + pub(crate) fields: Vec, +} + +impl Union { + pub(crate) fn has_stripped_entries(&self) -> bool { + self.fields.iter().any(|f| f.is_stripped()) + } } /// This is a more limited form of the standard Struct, different in that /// it lacks the things most items have (name, id, parameterization). Found /// only as a variant in an enum. #[derive(Clone, Debug)] -crate struct VariantStruct { - crate struct_type: CtorKind, - crate fields: Vec, - crate fields_stripped: bool, +pub(crate) struct VariantStruct { + pub(crate) struct_type: CtorKind, + pub(crate) fields: Vec, +} + +impl VariantStruct { + pub(crate) fn has_stripped_entries(&self) -> bool { + self.fields.iter().any(|f| f.is_stripped()) + } } #[derive(Clone, Debug)] -crate struct Enum { - crate variants: IndexVec, - crate generics: Generics, - crate variants_stripped: bool, +pub(crate) struct Enum { + pub(crate) variants: IndexVec, + pub(crate) generics: Generics, +} + +impl Enum { + pub(crate) fn has_stripped_entries(&self) -> bool { + self.variants.iter().any(|f| f.is_stripped()) + } + + pub(crate) fn variants(&self) -> impl Iterator { + self.variants.iter().filter(|v| !v.is_stripped()) + } } #[derive(Clone, Debug)] -crate enum Variant { +pub(crate) enum Variant { CLike, Tuple(Vec), Struct(VariantStruct), } +impl Variant { + pub(crate) fn has_stripped_entries(&self) -> Option { + match *self { + Self::Struct(ref struct_) => Some(struct_.has_stripped_entries()), + Self::CLike | Self::Tuple(_) => None, + } + } +} + /// Small wrapper around [`rustc_span::Span`] that adds helper methods /// and enforces calling [`rustc_span::Span::source_callsite()`]. #[derive(Copy, Clone, Debug)] -crate struct Span(rustc_span::Span); +pub(crate) struct Span(rustc_span::Span); impl Span { /// Wraps a [`rustc_span::Span`]. In case this span is the result of a macro expansion, the /// span will be updated to point to the macro invocation instead of the macro definition. /// /// (See rust-lang/rust#39726) - crate fn new(sp: rustc_span::Span) -> Self { + pub(crate) fn new(sp: rustc_span::Span) -> Self { Self(sp.source_callsite()) } - crate fn inner(&self) -> rustc_span::Span { + pub(crate) fn inner(&self) -> rustc_span::Span { self.0 } - crate fn dummy() -> Self { + pub(crate) fn dummy() -> Self { Self(rustc_span::DUMMY_SP) } - crate fn is_dummy(&self) -> bool { + pub(crate) fn is_dummy(&self) -> bool { self.0.is_dummy() } - crate fn filename(&self, sess: &Session) -> FileName { + pub(crate) fn filename(&self, sess: &Session) -> FileName { sess.source_map().span_to_filename(self.0) } - crate fn lo(&self, sess: &Session) -> Loc { + pub(crate) fn lo(&self, sess: &Session) -> Loc { sess.source_map().lookup_char_pos(self.0.lo()) } - crate fn hi(&self, sess: &Session) -> Loc { + pub(crate) fn hi(&self, sess: &Session) -> Loc { sess.source_map().lookup_char_pos(self.0.hi()) } - crate fn cnum(&self, sess: &Session) -> CrateNum { + pub(crate) fn cnum(&self, sess: &Session) -> CrateNum { // FIXME: is there a time when the lo and hi crate would be different? self.lo(sess).file.cnum } } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct Path { - crate res: Res, - crate segments: Vec, +pub(crate) struct Path { + pub(crate) res: Res, + pub(crate) segments: Vec, } impl Path { - crate fn def_id(&self) -> DefId { + pub(crate) fn def_id(&self) -> DefId { self.res.def_id() } - crate fn last(&self) -> Symbol { + pub(crate) fn last(&self) -> Symbol { self.segments.last().expect("segments were empty").name } - crate fn whole_name(&self) -> String { + pub(crate) fn whole_name(&self) -> String { self.segments .iter() .map(|s| if s.name == kw::PathRoot { String::new() } else { s.name.to_string() }) @@ -2132,7 +2174,7 @@ impl Path { } /// Checks if this is a `T::Name` path for an associated type. - crate fn is_assoc_ty(&self) -> bool { + pub(crate) fn is_assoc_ty(&self) -> bool { match self.res { Res::SelfTy { .. } if self.segments.len() != 1 => true, Res::Def(DefKind::TyParam, _) if self.segments.len() != 1 => true, @@ -2141,7 +2183,7 @@ impl Path { } } - crate fn generics(&self) -> Option> { + pub(crate) fn generics(&self) -> Option> { self.segments.last().and_then(|seg| { if let GenericArgs::AngleBracketed { ref args, .. } = seg.args { Some( @@ -2158,7 +2200,7 @@ impl Path { }) } - crate fn bindings(&self) -> Option<&[TypeBinding]> { + pub(crate) fn bindings(&self) -> Option<&[TypeBinding]> { self.segments.last().and_then(|seg| { if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args { Some(&**bindings) @@ -2170,7 +2212,7 @@ impl Path { } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate enum GenericArg { +pub(crate) enum GenericArg { Lifetime(Lifetime), Type(Type), Const(Box), @@ -2180,78 +2222,78 @@ crate enum GenericArg { // `GenericArg` can occur many times in a single `Path`, so make sure it // doesn't increase in size unexpectedly. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(GenericArg, 88); +rustc_data_structures::static_assert_size!(GenericArg, 80); #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate enum GenericArgs { - AngleBracketed { args: Vec, bindings: ThinVec }, - Parenthesized { inputs: Vec, output: Option> }, +pub(crate) enum GenericArgs { + AngleBracketed { args: Box<[GenericArg]>, bindings: ThinVec }, + Parenthesized { inputs: Box<[Type]>, output: Option> }, } // `GenericArgs` is in every `PathSegment`, so its size can significantly // affect rustdoc's memory usage. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(GenericArgs, 40); +rustc_data_structures::static_assert_size!(GenericArgs, 32); #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct PathSegment { - crate name: Symbol, - crate args: GenericArgs, +pub(crate) struct PathSegment { + pub(crate) name: Symbol, + pub(crate) args: GenericArgs, } // `PathSegment` usually occurs multiple times in every `Path`, so its size can // significantly affect rustdoc's memory usage. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(PathSegment, 48); +rustc_data_structures::static_assert_size!(PathSegment, 40); #[derive(Clone, Debug)] -crate struct Typedef { - crate type_: Type, - crate generics: Generics, +pub(crate) struct Typedef { + pub(crate) type_: Type, + pub(crate) generics: Generics, /// `type_` can come from either the HIR or from metadata. If it comes from HIR, it may be a type /// alias instead of the final type. This will always have the final type, regardless of whether /// `type_` came from HIR or from metadata. /// /// If `item_type.is_none()`, `type_` is guaranteed to come from metadata (and therefore hold the /// final type). - crate item_type: Option, + pub(crate) item_type: Option, } #[derive(Clone, Debug)] -crate struct OpaqueTy { - crate bounds: Vec, - crate generics: Generics, +pub(crate) struct OpaqueTy { + pub(crate) bounds: Vec, + pub(crate) generics: Generics, } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct BareFunctionDecl { - crate unsafety: hir::Unsafety, - crate generic_params: Vec, - crate decl: FnDecl, - crate abi: Abi, +pub(crate) struct BareFunctionDecl { + pub(crate) unsafety: hir::Unsafety, + pub(crate) generic_params: Vec, + pub(crate) decl: FnDecl, + pub(crate) abi: Abi, } #[derive(Clone, Debug)] -crate struct Static { - crate type_: Type, - crate mutability: Mutability, - crate expr: Option, +pub(crate) struct Static { + pub(crate) type_: Type, + pub(crate) mutability: Mutability, + pub(crate) expr: Option, } #[derive(Clone, PartialEq, Eq, Hash, Debug)] -crate struct Constant { - crate type_: Type, - crate kind: ConstantKind, +pub(crate) struct Constant { + pub(crate) type_: Type, + pub(crate) kind: ConstantKind, } #[derive(Clone, PartialEq, Eq, Hash, Debug)] -crate enum Term { +pub(crate) enum Term { Type(Type), Constant(Constant), } impl Term { - crate fn ty(&self) -> Option<&Type> { + pub(crate) fn ty(&self) -> Option<&Type> { if let Term::Type(ty) = self { Some(ty) } else { None } } } @@ -2263,7 +2305,7 @@ impl From for Term { } #[derive(Clone, PartialEq, Eq, Hash, Debug)] -crate enum ConstantKind { +pub(crate) enum ConstantKind { /// This is the wrapper around `ty::Const` for a non-local constant. Because it doesn't have a /// `BodyId`, we need to handle it on its own. /// @@ -2281,21 +2323,21 @@ crate enum ConstantKind { } impl Constant { - crate fn expr(&self, tcx: TyCtxt<'_>) -> String { + pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> String { self.kind.expr(tcx) } - crate fn value(&self, tcx: TyCtxt<'_>) -> Option { + pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> Option { self.kind.value(tcx) } - crate fn is_literal(&self, tcx: TyCtxt<'_>) -> bool { + pub(crate) fn is_literal(&self, tcx: TyCtxt<'_>) -> bool { self.kind.is_literal(tcx) } } impl ConstantKind { - crate fn expr(&self, tcx: TyCtxt<'_>) -> String { + pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> String { match *self { ConstantKind::TyConst { ref expr } => expr.clone(), ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id), @@ -2305,7 +2347,7 @@ impl ConstantKind { } } - crate fn value(&self, tcx: TyCtxt<'_>) -> Option { + pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> Option { match *self { ConstantKind::TyConst { .. } | ConstantKind::Anonymous { .. } => None, ConstantKind::Extern { def_id } | ConstantKind::Local { def_id, .. } => { @@ -2314,7 +2356,7 @@ impl ConstantKind { } } - crate fn is_literal(&self, tcx: TyCtxt<'_>) -> bool { + pub(crate) fn is_literal(&self, tcx: TyCtxt<'_>) -> bool { match *self { ConstantKind::TyConst { .. } => false, ConstantKind::Extern { def_id } => def_id.as_local().map_or(false, |def_id| { @@ -2328,18 +2370,18 @@ impl ConstantKind { } #[derive(Clone, Debug)] -crate struct Impl { - crate unsafety: hir::Unsafety, - crate generics: Generics, - crate trait_: Option, - crate for_: Type, - crate items: Vec, - crate polarity: ty::ImplPolarity, - crate kind: ImplKind, +pub(crate) struct Impl { + pub(crate) unsafety: hir::Unsafety, + pub(crate) generics: Generics, + pub(crate) trait_: Option, + pub(crate) for_: Type, + pub(crate) items: Vec, + pub(crate) polarity: ty::ImplPolarity, + pub(crate) kind: ImplKind, } impl Impl { - crate fn provided_trait_methods(&self, tcx: TyCtxt<'_>) -> FxHashSet { + pub(crate) fn provided_trait_methods(&self, tcx: TyCtxt<'_>) -> FxHashSet { self.trait_ .as_ref() .map(|t| t.def_id()) @@ -2349,22 +2391,27 @@ impl Impl { } #[derive(Clone, Debug)] -crate enum ImplKind { +pub(crate) enum ImplKind { Normal, Auto, + TupleVaradic, Blanket(Box), } impl ImplKind { - crate fn is_auto(&self) -> bool { + pub(crate) fn is_auto(&self) -> bool { matches!(self, ImplKind::Auto) } - crate fn is_blanket(&self) -> bool { + pub(crate) fn is_blanket(&self) -> bool { matches!(self, ImplKind::Blanket(_)) } - crate fn as_blanket_ty(&self) -> Option<&Type> { + pub(crate) fn is_tuple_variadic(&self) -> bool { + matches!(self, ImplKind::TupleVaradic) + } + + pub(crate) fn as_blanket_ty(&self) -> Option<&Type> { match self { ImplKind::Blanket(ty) => Some(ty), _ => None, @@ -2373,24 +2420,28 @@ impl ImplKind { } #[derive(Clone, Debug)] -crate struct Import { - crate kind: ImportKind, - crate source: ImportSource, - crate should_be_displayed: bool, +pub(crate) struct Import { + pub(crate) kind: ImportKind, + pub(crate) source: ImportSource, + pub(crate) should_be_displayed: bool, } impl Import { - crate fn new_simple(name: Symbol, source: ImportSource, should_be_displayed: bool) -> Self { + pub(crate) fn new_simple( + name: Symbol, + source: ImportSource, + should_be_displayed: bool, + ) -> Self { Self { kind: ImportKind::Simple(name), source, should_be_displayed } } - crate fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self { + pub(crate) fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self { Self { kind: ImportKind::Glob, source, should_be_displayed } } } #[derive(Clone, Debug)] -crate enum ImportKind { +pub(crate) enum ImportKind { // use source as str; Simple(Symbol), // use source::*; @@ -2398,38 +2449,38 @@ crate enum ImportKind { } #[derive(Clone, Debug)] -crate struct ImportSource { - crate path: Path, - crate did: Option, +pub(crate) struct ImportSource { + pub(crate) path: Path, + pub(crate) did: Option, } #[derive(Clone, Debug)] -crate struct Macro { - crate source: String, +pub(crate) struct Macro { + pub(crate) source: String, } #[derive(Clone, Debug)] -crate struct ProcMacro { - crate kind: MacroKind, - crate helpers: Vec, +pub(crate) struct ProcMacro { + pub(crate) kind: MacroKind, + pub(crate) helpers: Vec, } /// An type binding on an associated type (e.g., `A = Bar` in `Foo` or /// `A: Send + Sync` in `Foo`). #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate struct TypeBinding { - crate assoc: PathSegment, - crate kind: TypeBindingKind, +pub(crate) struct TypeBinding { + pub(crate) assoc: PathSegment, + pub(crate) kind: TypeBindingKind, } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -crate enum TypeBindingKind { +pub(crate) enum TypeBindingKind { Equality { term: Term }, Constraint { bounds: Vec }, } impl TypeBinding { - crate fn term(&self) -> &Term { + pub(crate) fn term(&self) -> &Term { match self.kind { TypeBindingKind::Equality { ref term } => term, _ => panic!("expected equality type binding for parenthesized generic args"), @@ -2450,18 +2501,18 @@ impl TypeBinding { /// /// `public_fn`'s docs will show it as returning `Vec`, since `PrivAlias` is private. /// [`SubstParam`] is used to record that `T` should be mapped to `i32`. -crate enum SubstParam { +pub(crate) enum SubstParam { Type(Type), Lifetime(Lifetime), Constant(Constant), } impl SubstParam { - crate fn as_ty(&self) -> Option<&Type> { + pub(crate) fn as_ty(&self) -> Option<&Type> { if let Self::Type(ty) = self { Some(ty) } else { None } } - crate fn as_lt(&self) -> Option<&Lifetime> { + pub(crate) fn as_lt(&self) -> Option<&Lifetime> { if let Self::Lifetime(lt) = self { Some(lt) } else { None } } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index c67b92df64..16574f94c0 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -15,6 +15,7 @@ use rustc_data_structures::thin_vec::ThinVec; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_middle::mir; use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; @@ -25,7 +26,7 @@ use std::mem; #[cfg(test)] mod tests; -crate fn krate(cx: &mut DocContext<'_>) -> Crate { +pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { let module = crate::visit_ast::RustdocVisitor::new(cx).visit(); for &cnum in cx.tcx.crates(()) { @@ -75,45 +76,42 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { Crate { module, primitives, external_traits: cx.external_traits.clone() } } -crate fn substs_to_args( - cx: &mut DocContext<'_>, - substs: &[ty::subst::GenericArg<'_>], +pub(crate) fn substs_to_args<'tcx>( + cx: &mut DocContext<'tcx>, + substs: &[ty::subst::GenericArg<'tcx>], mut skip_first: bool, ) -> Vec { - substs - .iter() - .filter_map(|kind| match kind.unpack() { - GenericArgKind::Lifetime(lt) => match *lt { - ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrAnon(_), .. }) => { - Some(GenericArg::Lifetime(Lifetime::elided())) - } - _ => lt.clean(cx).map(GenericArg::Lifetime), - }, - GenericArgKind::Type(_) if skip_first => { - skip_first = false; - None - } - GenericArgKind::Type(ty) => Some(GenericArg::Type(ty.clean(cx))), - GenericArgKind::Const(ct) => Some(GenericArg::Const(Box::new(ct.clean(cx)))), - }) - .collect() + let mut ret_val = + Vec::with_capacity(substs.len().saturating_sub(if skip_first { 1 } else { 0 })); + ret_val.extend(substs.iter().filter_map(|kind| match kind.unpack() { + GenericArgKind::Lifetime(lt) => { + Some(GenericArg::Lifetime(lt.clean(cx).unwrap_or(Lifetime::elided()))) + } + GenericArgKind::Type(_) if skip_first => { + skip_first = false; + None + } + GenericArgKind::Type(ty) => Some(GenericArg::Type(ty.clean(cx))), + GenericArgKind::Const(ct) => Some(GenericArg::Const(Box::new(ct.clean(cx)))), + })); + ret_val } -fn external_generic_args( - cx: &mut DocContext<'_>, +fn external_generic_args<'tcx>( + cx: &mut DocContext<'tcx>, did: DefId, has_self: bool, bindings: Vec, - substs: SubstsRef<'_>, + substs: SubstsRef<'tcx>, ) -> GenericArgs { - let args = substs_to_args(cx, &substs, has_self); + let args = substs_to_args(cx, substs, has_self); if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() { let inputs = // The trait's first substitution is the one after self, if there is one. match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() { - ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(), - _ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() }, + ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect::>().into(), + _ => return GenericArgs::AngleBracketed { args: args.into(), bindings: bindings.into() }, }; let output = None; // FIXME(#20299) return type comes from a projection now @@ -123,16 +121,16 @@ fn external_generic_args( // }; GenericArgs::Parenthesized { inputs, output } } else { - GenericArgs::AngleBracketed { args, bindings: bindings.into() } + GenericArgs::AngleBracketed { args: args.into(), bindings: bindings.into() } } } -pub(super) fn external_path( - cx: &mut DocContext<'_>, +pub(super) fn external_path<'tcx>( + cx: &mut DocContext<'tcx>, did: DefId, has_self: bool, bindings: Vec, - substs: SubstsRef<'_>, + substs: SubstsRef<'tcx>, ) -> Path { let def_kind = cx.tcx.def_kind(did); let name = cx.tcx.item_name(did); @@ -146,15 +144,15 @@ pub(super) fn external_path( } /// Remove the generic arguments from a path. -crate fn strip_path_generics(mut path: Path) -> Path { +pub(crate) fn strip_path_generics(mut path: Path) -> Path { for ps in path.segments.iter_mut() { - ps.args = GenericArgs::AngleBracketed { args: vec![], bindings: ThinVec::new() } + ps.args = GenericArgs::AngleBracketed { args: Default::default(), bindings: ThinVec::new() } } path } -crate fn qpath_to_string(p: &hir::QPath<'_>) -> String { +pub(crate) fn qpath_to_string(p: &hir::QPath<'_>) -> String { let segments = match *p { hir::QPath::Resolved(_, path) => &path.segments, hir::QPath::TypeRelative(_, segment) => return segment.ident.to_string(), @@ -173,7 +171,11 @@ crate fn qpath_to_string(p: &hir::QPath<'_>) -> String { s } -crate fn build_deref_target_impls(cx: &mut DocContext<'_>, items: &[Item], ret: &mut Vec) { +pub(crate) fn build_deref_target_impls( + cx: &mut DocContext<'_>, + items: &[Item], + ret: &mut Vec, +) { let tcx = cx.tcx; for item in items { @@ -196,7 +198,7 @@ crate fn build_deref_target_impls(cx: &mut DocContext<'_>, items: &[Item], ret: } } -crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { +pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { use rustc_hir::*; debug!("trying to get a name from pattern: {:?}", p); @@ -229,8 +231,8 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { }) } -crate fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { - match n.val() { +pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { + match n.kind() { ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => { let mut s = if let Some(def) = def.as_local() { let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did); @@ -259,14 +261,14 @@ crate fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { } } -crate fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option { +pub(crate) fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option { tcx.const_eval_poly(def_id).ok().and_then(|val| { let ty = tcx.type_of(def_id); match (val, ty.kind()) { (_, &ty::Ref(..)) => None, (ConstValue::Scalar(_), &ty::Adt(_, _)) => None, (ConstValue::Scalar(_), _) => { - let const_ = ty::Const::from_value(tcx, val, ty); + let const_ = mir::ConstantKind::from_value(val, ty); Some(print_const_with_custom_print_scalar(tcx, const_)) } _ => None, @@ -300,19 +302,18 @@ fn format_integer_with_underscore_sep(num: &str) -> String { .collect() } -fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: ty::Const<'_>) -> String { +fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: mir::ConstantKind<'_>) -> String { // Use a slightly different format for integer types which always shows the actual value. // For all other types, fallback to the original `pretty_print_const`. - match (ct.val(), ct.ty().kind()) { - (ty::ConstKind::Value(ConstValue::Scalar(int)), ty::Uint(ui)) => { + match (ct, ct.ty().kind()) { + (mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Uint(ui)) => { format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str()) } - (ty::ConstKind::Value(ConstValue::Scalar(int)), ty::Int(i)) => { + (mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Int(i)) => { let ty = tcx.lift(ct.ty()).unwrap(); let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size; let data = int.assert_bits(size); let sign_extended_data = size.sign_extend(data) as i128; - format!( "{}{}", format_integer_with_underscore_sep(&sign_extended_data.to_string()), @@ -323,7 +324,7 @@ fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: ty::Const<'_>) -> S } } -crate fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { +pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { if let hir::Node::Expr(expr) = tcx.hir().get(hir_id) { if let hir::ExprKind::Lit(_) = &expr.kind { return true; @@ -339,7 +340,7 @@ crate fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { false } -crate fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String { +pub(crate) fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String { let hir = tcx.hir(); let value = &hir.body(body).value; @@ -353,7 +354,7 @@ crate fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String { } /// Given a type Path, resolve it to a Type using the TyCtxt -crate fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type { +pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type { debug!("resolve_type({:?})", path); match path.res { @@ -367,7 +368,7 @@ crate fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type { } } -crate fn get_auto_trait_and_blanket_impls( +pub(crate) fn get_auto_trait_and_blanket_impls( cx: &mut DocContext<'_>, item_def_id: DefId, ) -> impl Iterator { @@ -389,7 +390,7 @@ crate fn get_auto_trait_and_blanket_impls( /// This is later used by [`href()`] to determine the HTML link for the item. /// /// [`href()`]: crate::html::format::href -crate fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId { +pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId { use DefKind::*; debug!("register_res({:?})", res); @@ -428,16 +429,16 @@ crate fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId { did } -crate fn resolve_use_source(cx: &mut DocContext<'_>, path: Path) -> ImportSource { +pub(crate) fn resolve_use_source(cx: &mut DocContext<'_>, path: Path) -> ImportSource { ImportSource { did: if path.res.opt_def_id().is_none() { None } else { Some(register_res(cx, path.res)) }, path, } } -crate fn enter_impl_trait(cx: &mut DocContext<'_>, f: F) -> R +pub(crate) fn enter_impl_trait<'tcx, F, R>(cx: &mut DocContext<'tcx>, f: F) -> R where - F: FnOnce(&mut DocContext<'_>) -> R, + F: FnOnce(&mut DocContext<'tcx>) -> R, { let old_bounds = mem::take(&mut cx.impl_trait_bounds); let r = f(cx); @@ -447,7 +448,7 @@ where } /// Find the nearest parent module of a [`DefId`]. -crate fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option { +pub(crate) fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option { if def_id.is_top_level_module() { // The crate root has no parent. Use it as the root instead. Some(def_id) @@ -474,7 +475,7 @@ crate fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option, did: DefId, flag: Symbol) -> bool { +pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool { tcx.get_attrs(did, sym::doc).any(|attr| { attr.meta_item_list().map_or(false, |l| rustc_attr::list_contains_name(&l, flag)) }) @@ -484,7 +485,7 @@ crate fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool { /// so that the channel is consistent. /// /// Set by `bootstrap::Builder::doc_rust_lang_org_channel` in order to keep tests passing on beta/stable. -crate const DOC_RUST_LANG_ORG_CHANNEL: &str = env!("DOC_RUST_LANG_ORG_CHANNEL"); +pub(crate) const DOC_RUST_LANG_ORG_CHANNEL: &str = env!("DOC_RUST_LANG_ORG_CHANNEL"); /// Render a sequence of macro arms in a format suitable for displaying to the user /// as part of an item declaration. diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 1ff2c8191e..e59324331a 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -31,7 +31,7 @@ use crate::scrape_examples::{AllCallLocations, ScrapeExamplesOptions}; use crate::theme; #[derive(Clone, Copy, PartialEq, Eq, Debug)] -crate enum OutputFormat { +pub(crate) enum OutputFormat { Json, Html, } @@ -43,7 +43,7 @@ impl Default for OutputFormat { } impl OutputFormat { - crate fn is_json(&self) -> bool { + pub(crate) fn is_json(&self) -> bool { matches!(self, OutputFormat::Json) } } @@ -62,100 +62,100 @@ impl TryFrom<&str> for OutputFormat { /// Configuration options for rustdoc. #[derive(Clone)] -crate struct Options { +pub(crate) struct Options { // Basic options / Options passed directly to rustc /// The crate root or Markdown file to load. - crate input: PathBuf, + pub(crate) input: PathBuf, /// The name of the crate being documented. - crate crate_name: Option, + pub(crate) crate_name: Option, /// Whether or not this is a proc-macro crate - crate proc_macro_crate: bool, + pub(crate) proc_macro_crate: bool, /// How to format errors and warnings. - crate error_format: ErrorOutputType, + pub(crate) error_format: ErrorOutputType, /// Library search paths to hand to the compiler. - crate libs: Vec, + pub(crate) libs: Vec, /// Library search paths strings to hand to the compiler. - crate lib_strs: Vec, + pub(crate) lib_strs: Vec, /// The list of external crates to link against. - crate externs: Externs, + pub(crate) externs: Externs, /// The list of external crates strings to link against. - crate extern_strs: Vec, + pub(crate) extern_strs: Vec, /// List of `cfg` flags to hand to the compiler. Always includes `rustdoc`. - crate cfgs: Vec, + pub(crate) cfgs: Vec, /// List of check cfg flags to hand to the compiler. - crate check_cfgs: Vec, + pub(crate) check_cfgs: Vec, /// Codegen options to hand to the compiler. - crate codegen_options: CodegenOptions, + pub(crate) codegen_options: CodegenOptions, /// Codegen options strings to hand to the compiler. - crate codegen_options_strs: Vec, + pub(crate) codegen_options_strs: Vec, /// Debugging (`-Z`) options to pass to the compiler. - crate debugging_opts: DebuggingOptions, + pub(crate) debugging_opts: DebuggingOptions, /// Debugging (`-Z`) options strings to pass to the compiler. - crate debugging_opts_strs: Vec, + pub(crate) debugging_opts_strs: Vec, /// The target used to compile the crate against. - crate target: TargetTriple, + pub(crate) target: TargetTriple, /// Edition used when reading the crate. Defaults to "2015". Also used by default when /// compiling doctests from the crate. - crate edition: Edition, + pub(crate) edition: Edition, /// The path to the sysroot. Used during the compilation process. - crate maybe_sysroot: Option, + pub(crate) maybe_sysroot: Option, /// Lint information passed over the command-line. - crate lint_opts: Vec<(String, Level)>, + pub(crate) lint_opts: Vec<(String, Level)>, /// Whether to ask rustc to describe the lints it knows. - crate describe_lints: bool, + pub(crate) describe_lints: bool, /// What level to cap lints at. - crate lint_cap: Option, + pub(crate) lint_cap: Option, // Options specific to running doctests /// Whether we should run doctests instead of generating docs. - crate should_test: bool, + pub(crate) should_test: bool, /// List of arguments to pass to the test harness, if running tests. - crate test_args: Vec, + pub(crate) test_args: Vec, /// The working directory in which to run tests. - crate test_run_directory: Option, + pub(crate) test_run_directory: Option, /// Optional path to persist the doctest executables to, defaults to a /// temporary directory if not set. - crate persist_doctests: Option, + pub(crate) persist_doctests: Option, /// Runtool to run doctests with - crate runtool: Option, + pub(crate) runtool: Option, /// Arguments to pass to the runtool - crate runtool_args: Vec, + pub(crate) runtool_args: Vec, /// Whether to allow ignoring doctests on a per-target basis /// For example, using ignore-foo to ignore running the doctest on any target that /// contains "foo" as a substring - crate enable_per_target_ignores: bool, + pub(crate) enable_per_target_ignores: bool, /// Do not run doctests, compile them if should_test is active. - crate no_run: bool, + pub(crate) no_run: bool, /// The path to a rustc-like binary to build tests with. If not set, we /// default to loading from `$sysroot/bin/rustc`. - crate test_builder: Option, + pub(crate) test_builder: Option, // Options that affect the documentation process /// Whether to run the `calculate-doc-coverage` pass, which counts the number of public items /// with and without documentation. - crate show_coverage: bool, + pub(crate) show_coverage: bool, // Options that alter generated documentation pages /// Crate version to note on the sidebar of generated docs. - crate crate_version: Option, + pub(crate) crate_version: Option, /// Collected options specific to outputting final pages. - crate render_options: RenderOptions, + pub(crate) render_options: RenderOptions, /// The format that we output when rendering. /// /// Currently used only for the `--show-coverage` option. - crate output_format: OutputFormat, + pub(crate) output_format: OutputFormat, /// If this option is set to `true`, rustdoc will only run checks and not generate /// documentation. - crate run_check: bool, + pub(crate) run_check: bool, /// Whether doctests should emit unused externs - crate json_unused_externs: JsonUnusedExterns, + pub(crate) json_unused_externs: JsonUnusedExterns, /// Whether to skip capturing stdout and stderr of tests. - crate nocapture: bool, + pub(crate) nocapture: bool, /// Configuration for scraping examples from the current crate. If this option is Some(..) then /// the compiler will scrape examples and not generate documentation. - crate scrape_examples_options: Option, + pub(crate) scrape_examples_options: Option, } impl fmt::Debug for Options { @@ -205,83 +205,83 @@ impl fmt::Debug for Options { /// Configuration options for the HTML page-creation process. #[derive(Clone, Debug)] -crate struct RenderOptions { +pub(crate) struct RenderOptions { /// Output directory to generate docs into. Defaults to `doc`. - crate output: PathBuf, + pub(crate) output: PathBuf, /// External files to insert into generated pages. - crate external_html: ExternalHtml, + pub(crate) external_html: ExternalHtml, /// A pre-populated `IdMap` with the default headings and any headings added by Markdown files /// processed by `external_html`. - crate id_map: IdMap, + pub(crate) id_map: IdMap, /// If present, playground URL to use in the "Run" button added to code samples. /// /// Be aware: This option can come both from the CLI and from crate attributes! - crate playground_url: Option, + pub(crate) playground_url: Option, /// Whether to sort modules alphabetically on a module page instead of using declaration order. /// `true` by default. // // FIXME(misdreavus): the flag name is `--sort-modules-by-appearance` but the meaning is // inverted once read. - crate sort_modules_alphabetically: bool, + pub(crate) sort_modules_alphabetically: bool, /// List of themes to extend the docs with. Original argument name is included to assist in /// displaying errors if it fails a theme check. - crate themes: Vec, + pub(crate) themes: Vec, /// If present, CSS file that contains rules to add to the default CSS. - crate extension_css: Option, + pub(crate) extension_css: Option, /// A map of crate names to the URL to use instead of querying the crate's `html_root_url`. - crate extern_html_root_urls: BTreeMap, + pub(crate) extern_html_root_urls: BTreeMap, /// Whether to give precedence to `html_root_url` or `--exten-html-root-url`. - crate extern_html_root_takes_precedence: bool, + pub(crate) extern_html_root_takes_precedence: bool, /// A map of the default settings (values are as for DOM storage API). Keys should lack the /// `rustdoc-` prefix. - crate default_settings: FxHashMap, + pub(crate) default_settings: FxHashMap, /// If present, suffix added to CSS/JavaScript files when referencing them in generated pages. - crate resource_suffix: String, + pub(crate) resource_suffix: String, /// Whether to run the static CSS/JavaScript through a minifier when outputting them. `true` by /// default. // // FIXME(misdreavus): the flag name is `--disable-minification` but the meaning is inverted // once read. - crate enable_minification: bool, + pub(crate) enable_minification: bool, /// Whether to create an index page in the root of the output directory. If this is true but /// `enable_index_page` is None, generate a static listing of crates instead. - crate enable_index_page: bool, + pub(crate) enable_index_page: bool, /// A file to use as the index page at the root of the output directory. Overrides /// `enable_index_page` to be true if set. - crate index_page: Option, + pub(crate) index_page: Option, /// An optional path to use as the location of static files. If not set, uses combinations of /// `../` to reach the documentation root. - crate static_root_path: Option, + pub(crate) static_root_path: Option, // Options specific to reading standalone Markdown files /// Whether to generate a table of contents on the output file when reading a standalone /// Markdown file. - crate markdown_no_toc: bool, + pub(crate) markdown_no_toc: bool, /// Additional CSS files to link in pages generated from standalone Markdown files. - crate markdown_css: Vec, + pub(crate) markdown_css: Vec, /// If present, playground URL to use in the "Run" button added to code samples generated from /// standalone Markdown files. If not present, `playground_url` is used. - crate markdown_playground_url: Option, + pub(crate) markdown_playground_url: Option, /// Document items that have lower than `pub` visibility. - crate document_private: bool, + pub(crate) document_private: bool, /// Document items that have `doc(hidden)`. - crate document_hidden: bool, + pub(crate) document_hidden: bool, /// If `true`, generate a JSON file in the crate folder instead of HTML redirection files. - crate generate_redirect_map: bool, + pub(crate) generate_redirect_map: bool, /// Show the memory layout of types in the docs. - crate show_type_layout: bool, - crate unstable_features: rustc_feature::UnstableFeatures, - crate emit: Vec, + pub(crate) show_type_layout: bool, + pub(crate) unstable_features: rustc_feature::UnstableFeatures, + pub(crate) emit: Vec, /// If `true`, HTML source pages will generate links for items to their definition. - crate generate_link_to_definition: bool, + pub(crate) generate_link_to_definition: bool, /// Set of function-call locations to include as examples - crate call_locations: AllCallLocations, + pub(crate) call_locations: AllCallLocations, /// If `true`, Context::init will not emit shared files. - crate no_emit_shared: bool, + pub(crate) no_emit_shared: bool, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] -crate enum EmitType { +pub(crate) enum EmitType { Unversioned, Toolchain, InvocationSpecific, @@ -302,7 +302,7 @@ impl FromStr for EmitType { } impl RenderOptions { - crate fn should_emit_crate(&self) -> bool { + pub(crate) fn should_emit_crate(&self) -> bool { self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific) } } @@ -310,7 +310,7 @@ impl RenderOptions { impl Options { /// Parses the given command-line for options. If an error message or other early-return has /// been printed, returns `Err` with the exit code. - crate fn from_matches(matches: &getopts::Matches) -> Result { + pub(crate) fn from_matches(matches: &getopts::Matches) -> Result { // Check for unstable options. nightly_options::check_nightly_options(matches, &opts()); @@ -667,7 +667,7 @@ impl Options { return Err(1); } - let scrape_examples_options = ScrapeExamplesOptions::new(&matches, &diag)?; + let scrape_examples_options = ScrapeExamplesOptions::new(matches, &diag)?; let with_examples = matches.opt_strs("with-examples"); let call_locations = crate::scrape_examples::load_call_locations(with_examples, &diag)?; @@ -745,7 +745,7 @@ impl Options { } /// Returns `true` if the file given as `self.input` is a Markdown file. - crate fn markdown_input(&self) -> bool { + pub(crate) fn markdown_input(&self) -> bool { self.input.extension().map_or(false, |e| e == "md" || e == "markdown") } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 17644aeed8..51b245e36b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -21,9 +21,9 @@ use rustc_span::symbol::sym; use rustc_span::{source_map, Span, Symbol}; use std::cell::RefCell; -use std::lazy::SyncLazy; use std::mem; use std::rc::Rc; +use std::sync::LazyLock; use crate::clean::inline::build_external_trait; use crate::clean::{self, ItemId, TraitWithExtraInfo}; @@ -32,70 +32,74 @@ use crate::formats::cache::Cache; use crate::passes::collect_intra_doc_links::PreprocessedMarkdownLink; use crate::passes::{self, Condition::*}; -crate use rustc_session::config::{DebuggingOptions, Input, Options}; +pub(crate) use rustc_session::config::{DebuggingOptions, Input, Options}; -crate struct ResolverCaches { - crate markdown_links: Option>>, - crate doc_link_resolutions: FxHashMap<(Symbol, Namespace, DefId), Option>>, +pub(crate) struct ResolverCaches { + pub(crate) markdown_links: Option>>, + pub(crate) doc_link_resolutions: FxHashMap<(Symbol, Namespace, DefId), Option>>, /// Traits in scope for a given module. /// See `collect_intra_doc_links::traits_implemented_by` for more details. - crate traits_in_scope: DefIdMap>, - crate all_traits: Option>, - crate all_trait_impls: Option>, - crate all_macro_rules: FxHashMap>, + pub(crate) traits_in_scope: DefIdMap>, + pub(crate) all_traits: Option>, + pub(crate) all_trait_impls: Option>, + pub(crate) all_macro_rules: FxHashMap>, } -crate struct DocContext<'tcx> { - crate tcx: TyCtxt<'tcx>, +pub(crate) struct DocContext<'tcx> { + pub(crate) tcx: TyCtxt<'tcx>, /// Name resolver. Used for intra-doc links. /// /// The `Rc>` wrapping is needed because that is what's returned by /// [`rustc_interface::Queries::expansion()`]. // FIXME: see if we can get rid of this RefCell somehow - crate resolver: Rc>, - crate resolver_caches: ResolverCaches, + pub(crate) resolver: Rc>, + pub(crate) resolver_caches: ResolverCaches, /// Used for normalization. /// /// Most of this logic is copied from rustc_lint::late. - crate param_env: ParamEnv<'tcx>, + pub(crate) param_env: ParamEnv<'tcx>, /// Later on moved through `clean::Crate` into `cache` - crate external_traits: Rc>>, + pub(crate) external_traits: Rc>>, /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. - crate active_extern_traits: FxHashSet, + pub(crate) active_extern_traits: FxHashSet, // The current set of parameter substitutions, // for expanding type aliases at the HIR level: /// Table `DefId` of type, lifetime, or const parameter -> substituted type, lifetime, or const - crate substs: FxHashMap, + pub(crate) substs: FxHashMap, /// Table synthetic type parameter for `impl Trait` in argument position -> bounds - crate impl_trait_bounds: FxHashMap>, + pub(crate) impl_trait_bounds: FxHashMap>, /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`. // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set. - crate generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>, - crate auto_traits: Vec, + pub(crate) generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>, + pub(crate) auto_traits: Vec, /// The options given to rustdoc that could be relevant to a pass. - crate render_options: RenderOptions, + pub(crate) render_options: RenderOptions, /// This same cache is used throughout rustdoc, including in [`crate::html::render`]. - crate cache: Cache, + pub(crate) cache: Cache, /// Used by [`clean::inline`] to tell if an item has already been inlined. - crate inlined: FxHashSet, + pub(crate) inlined: FxHashSet, /// Used by `calculate_doc_coverage`. - crate output_format: OutputFormat, + pub(crate) output_format: OutputFormat, } impl<'tcx> DocContext<'tcx> { - crate fn sess(&self) -> &'tcx Session { + pub(crate) fn sess(&self) -> &'tcx Session { self.tcx.sess } - crate fn with_param_env T>(&mut self, def_id: DefId, f: F) -> T { + pub(crate) fn with_param_env T>( + &mut self, + def_id: DefId, + f: F, + ) -> T { let old_param_env = mem::replace(&mut self.param_env, self.tcx.param_env(def_id)); let ret = f(self); self.param_env = old_param_env; ret } - crate fn enter_resolver(&self, f: F) -> R + pub(crate) fn enter_resolver(&self, f: F) -> R where F: FnOnce(&mut resolve::Resolver<'_>) -> R, { @@ -104,7 +108,11 @@ impl<'tcx> DocContext<'tcx> { /// Call the closure with the given parameters set as /// the substitutions for a type alias' RHS. - crate fn enter_alias(&mut self, substs: FxHashMap, f: F) -> R + pub(crate) fn enter_alias( + &mut self, + substs: FxHashMap, + f: F, + ) -> R where F: FnOnce(&mut Self) -> R, { @@ -116,7 +124,7 @@ impl<'tcx> DocContext<'tcx> { /// Like `hir().local_def_id_to_hir_id()`, but skips calling it on fake DefIds. /// (This avoids a slice-index-out-of-bounds panic.) - crate fn as_local_hir_id(tcx: TyCtxt<'_>, item_id: ItemId) -> Option { + pub(crate) fn as_local_hir_id(tcx: TyCtxt<'_>, item_id: ItemId) -> Option { match item_id { ItemId::DefId(real_id) => { real_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)) @@ -126,13 +134,13 @@ impl<'tcx> DocContext<'tcx> { } } - crate fn with_all_traits(&mut self, f: impl FnOnce(&mut Self, &[DefId])) { + pub(crate) fn with_all_traits(&mut self, f: impl FnOnce(&mut Self, &[DefId])) { let all_traits = self.resolver_caches.all_traits.take(); f(self, all_traits.as_ref().expect("`all_traits` are already borrowed")); self.resolver_caches.all_traits = all_traits; } - crate fn with_all_trait_impls(&mut self, f: impl FnOnce(&mut Self, &[DefId])) { + pub(crate) fn with_all_trait_impls(&mut self, f: impl FnOnce(&mut Self, &[DefId])) { let all_trait_impls = self.resolver_caches.all_trait_impls.take(); f(self, all_trait_impls.as_ref().expect("`all_trait_impls` are already borrowed")); self.resolver_caches.all_trait_impls = all_trait_impls; @@ -143,7 +151,7 @@ impl<'tcx> DocContext<'tcx> { /// /// If the given `error_format` is `ErrorOutputType::Json` and no `SourceMap` is given, a new one /// will be created for the handler. -crate fn new_handler( +pub(crate) fn new_handler( error_format: ErrorOutputType, source_map: Option>, debugging_opts: &DebuggingOptions, @@ -194,7 +202,7 @@ crate fn new_handler( } /// Parse, resolve, and typecheck the given crate. -crate fn create_config( +pub(crate) fn create_config( RustdocOptions { input, crate_name, @@ -285,8 +293,8 @@ crate fn create_config( providers.typeck_item_bodies = |_, _| {}; // hack so that `used_trait_imports` won't try to call typeck providers.used_trait_imports = |_, _| { - static EMPTY_SET: SyncLazy> = - SyncLazy::new(FxHashSet::default); + static EMPTY_SET: LazyLock> = + LazyLock::new(FxHashSet::default); &EMPTY_SET }; // In case typeck does end up being called, don't ICE in case there were name resolution errors @@ -311,7 +319,7 @@ crate fn create_config( } } -crate fn run_global_ctxt( +pub(crate) fn run_global_ctxt( tcx: TyCtxt<'_>, resolver: Rc>, resolver_caches: ResolverCaches, @@ -535,7 +543,7 @@ impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> { /// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter /// for `impl Trait` in argument position. #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -crate enum ImplTraitParam { +pub(crate) enum ImplTraitParam { DefId(DefId), ParamIndex(u32), } diff --git a/src/librustdoc/docfs.rs b/src/librustdoc/docfs.rs index d59273db08..be066bdafa 100644 --- a/src/librustdoc/docfs.rs +++ b/src/librustdoc/docfs.rs @@ -15,38 +15,38 @@ use std::path::{Path, PathBuf}; use std::string::ToString; use std::sync::mpsc::Sender; -crate trait PathError { +pub(crate) trait PathError { fn new>(e: S, path: P) -> Self where S: ToString + Sized; } -crate struct DocFS { +pub(crate) struct DocFS { sync_only: bool, errors: Option>, } impl DocFS { - crate fn new(errors: Sender) -> DocFS { + pub(crate) fn new(errors: Sender) -> DocFS { DocFS { sync_only: false, errors: Some(errors) } } - crate fn set_sync_only(&mut self, sync_only: bool) { + pub(crate) fn set_sync_only(&mut self, sync_only: bool) { self.sync_only = sync_only; } - crate fn close(&mut self) { + pub(crate) fn close(&mut self) { self.errors = None; } - crate fn create_dir_all>(&self, path: P) -> io::Result<()> { + pub(crate) fn create_dir_all>(&self, path: P) -> io::Result<()> { // For now, dir creation isn't a huge time consideration, do it // synchronously, which avoids needing ordering between write() actions // and directory creation. fs::create_dir_all(path) } - crate fn write( + pub(crate) fn write( &self, path: PathBuf, contents: impl 'static + Send + AsRef<[u8]>, @@ -54,7 +54,8 @@ impl DocFS { where E: PathError, { - if !self.sync_only && cfg!(windows) { + #[cfg(windows)] + if !self.sync_only { // A possible future enhancement after more detailed profiling would // be to create the file sync so errors are reported eagerly. let sender = self.errors.clone().expect("can't write after closing"); @@ -68,6 +69,10 @@ impl DocFS { } else { fs::write(&path, contents).map_err(|e| E::new(e, path))?; } + + #[cfg(not(windows))] + fs::write(&path, contents).map_err(|e| E::new(e, path))?; + Ok(()) } } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 93ccf60a1d..ab72f4a3f5 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -40,14 +40,14 @@ use crate::passes::span_of_attrs; /// Options that apply to all doctests in a crate or Markdown file (for `rustdoc foo.md`). #[derive(Clone, Default)] -crate struct GlobalTestOptions { +pub(crate) struct GlobalTestOptions { /// Whether to disable the default `extern crate my_crate;` when creating doctests. - crate no_crate_inject: bool, + pub(crate) no_crate_inject: bool, /// Additional crate-level attributes to add to doctests. - crate attrs: Vec, + pub(crate) attrs: Vec, } -crate fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { +pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { let input = config::Input::File(options.input.clone()); let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name; @@ -207,7 +207,11 @@ crate fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { Ok(()) } -crate fn run_tests(mut test_args: Vec, nocapture: bool, tests: Vec) { +pub(crate) fn run_tests( + mut test_args: Vec, + nocapture: bool, + tests: Vec, +) { test_args.insert(0, "rustdoctest".to_string()); if nocapture { test_args.push("--nocapture".to_string()); @@ -224,7 +228,7 @@ fn scrape_test_config(attrs: &[ast::Attribute]) -> GlobalTestOptions { let test_attrs: Vec<_> = attrs .iter() .filter(|a| a.has_name(sym::doc)) - .flat_map(|a| a.meta_item_list().unwrap_or_else(Vec::new)) + .flat_map(|a| a.meta_item_list().unwrap_or_default()) .filter(|a| a.has_name(sym::test)) .collect(); let attrs = test_attrs.iter().flat_map(|a| a.meta_item_list().unwrap_or(&[])); @@ -361,8 +365,8 @@ fn run_test( } compiler.arg("--target").arg(match target { TargetTriple::TargetTriple(s) => s, - TargetTriple::TargetPath(path) => { - path.to_str().expect("target path must be valid unicode").to_string() + TargetTriple::TargetJson { path_for_rustdoc, .. } => { + path_for_rustdoc.to_str().expect("target path must be valid unicode").to_string() } }); if let ErrorOutputType::HumanReadable(kind) = rustdoc_options.error_format { @@ -488,7 +492,7 @@ fn run_test( /// Transforms a test into code that can be compiled into a Rust binary, and returns the number of /// lines before the test code begins as well as if the output stream supports colors or not. -crate fn make_test( +pub(crate) fn make_test( s: &str, crate_name: Option<&str>, dont_insert_main: bool, @@ -734,7 +738,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool { } }; // If a parsing error happened, it's very likely that the attribute is incomplete. - if !parser.parse_attribute(InnerAttrPolicy::Permitted).is_ok() { + if parser.parse_attribute(InnerAttrPolicy::Permitted).is_err() { return false; } // We now check if there is an unclosed delimiter for the attribute. To do so, we look at @@ -791,7 +795,9 @@ fn partition_source(s: &str, edition: Edition) -> (String, String, String) { // If not, then we append the new line into the pending attribute to check // if this time it's complete... mod_attr_pending.push_str(line); - if !trimline.is_empty() && check_if_attr_is_complete(line, edition) { + if !trimline.is_empty() + && check_if_attr_is_complete(&mod_attr_pending, edition) + { // If it's complete, then we can clear the pending content. mod_attr_pending.clear(); } @@ -840,7 +846,7 @@ fn partition_source(s: &str, edition: Edition) -> (String, String, String) { (before, after, crates) } -crate trait Tester { +pub(crate) trait Tester { fn add_test(&mut self, test: String, config: LangString, line: usize); fn get_line(&self) -> usize { 0 @@ -848,8 +854,8 @@ crate trait Tester { fn register_header(&mut self, _name: &str, _level: u32) {} } -crate struct Collector { - crate tests: Vec, +pub(crate) struct Collector { + pub(crate) tests: Vec, // The name of the test displayed to the user, separated by `::`. // @@ -887,7 +893,7 @@ crate struct Collector { } impl Collector { - crate fn new( + pub(crate) fn new( crate_name: Symbol, rustdoc_options: RustdocOptions, use_headers: bool, @@ -922,7 +928,7 @@ impl Collector { format!("{} - {}(line {})", filename.prefer_local(), item_path, line) } - crate fn set_position(&mut self, position: Span) { + pub(crate) fn set_position(&mut self, position: Span) { self.position = position; } diff --git a/src/librustdoc/error.rs b/src/librustdoc/error.rs index 8eadbf63f3..6ed7eab1ab 100644 --- a/src/librustdoc/error.rs +++ b/src/librustdoc/error.rs @@ -5,9 +5,9 @@ use std::path::{Path, PathBuf}; use crate::docfs::PathError; #[derive(Debug)] -crate struct Error { - crate file: PathBuf, - crate error: String, +pub(crate) struct Error { + pub(crate) file: PathBuf, + pub(crate) error: String, } impl error::Error for Error {} diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 4df48cef59..37fd909c93 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -7,20 +7,20 @@ use std::str; use serde::Serialize; #[derive(Clone, Debug, Serialize)] -crate struct ExternalHtml { +pub(crate) struct ExternalHtml { /// Content that will be included inline in the `` section of a /// rendered Markdown file or generated documentation - crate in_header: String, + pub(crate) in_header: String, /// Content that will be included inline between `` and the content of /// a rendered Markdown file or generated documentation - crate before_content: String, + pub(crate) before_content: String, /// Content that will be included inline between the content and `` of /// a rendered Markdown file or generated documentation - crate after_content: String, + pub(crate) after_content: String, } impl ExternalHtml { - crate fn load( + pub(crate) fn load( in_header: &[String], before_content: &[String], after_content: &[String], @@ -70,12 +70,12 @@ impl ExternalHtml { } } -crate enum LoadStringError { +pub(crate) enum LoadStringError { ReadFail, BadUtf8, } -crate fn load_string>( +pub(crate) fn load_string>( file_path: P, diag: &rustc_errors::Handler, ) -> Result { diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 95adc4426b..336448904d 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -1,13 +1,13 @@ use crate::clean::*; -crate fn strip_item(mut item: Item) -> Item { +pub(crate) fn strip_item(mut item: Item) -> Item { if !matches!(*item.kind, StrippedItem(..)) { item.kind = box StrippedItem(item.kind); } item } -crate trait DocFolder: Sized { +pub(crate) trait DocFolder: Sized { fn fold_item(&mut self, item: Item) -> Option { Some(self.fold_item_recur(item)) } @@ -18,30 +18,15 @@ crate trait DocFolder: Sized { StrippedItem(..) => unreachable!(), ModuleItem(i) => ModuleItem(self.fold_mod(i)), StructItem(mut i) => { - let num_fields = i.fields.len(); i.fields = i.fields.into_iter().filter_map(|x| self.fold_item(x)).collect(); - if !i.fields_stripped { - i.fields_stripped = - num_fields != i.fields.len() || i.fields.iter().any(|f| f.is_stripped()); - } StructItem(i) } UnionItem(mut i) => { - let num_fields = i.fields.len(); i.fields = i.fields.into_iter().filter_map(|x| self.fold_item(x)).collect(); - if !i.fields_stripped { - i.fields_stripped = - num_fields != i.fields.len() || i.fields.iter().any(|f| f.is_stripped()); - } UnionItem(i) } EnumItem(mut i) => { - let num_variants = i.variants.len(); i.variants = i.variants.into_iter().filter_map(|x| self.fold_item(x)).collect(); - if !i.variants_stripped { - i.variants_stripped = num_variants != i.variants.len() - || i.variants.iter().any(|f| f.is_stripped()); - } EnumItem(i) } TraitItem(mut i) => { @@ -54,12 +39,7 @@ crate trait DocFolder: Sized { } VariantItem(i) => match i { Variant::Struct(mut j) => { - let num_fields = j.fields.len(); j.fields = j.fields.into_iter().filter_map(|x| self.fold_item(x)).collect(); - if !j.fields_stripped { - j.fields_stripped = num_fields != j.fields.len() - || j.fields.iter().any(|f| f.is_stripped()); - } VariantItem(Variant::Struct(j)) } Variant::Tuple(fields) => { diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 9dc30d8a18..d7276a427c 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -3,7 +3,7 @@ use std::mem; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_middle::middle::privacy::AccessLevels; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{sym, Symbol}; use crate::clean::{self, types::ExternalLocation, ExternalCrate, ItemId, PrimitiveType}; @@ -26,25 +26,25 @@ use crate::html::render::IndexItem; /// to `Send` so it may be stored in an `Arc` instance and shared among the various /// rendering threads. #[derive(Default)] -crate struct Cache { +pub(crate) struct Cache { /// Maps a type ID to all known implementations for that type. This is only /// recognized for intra-crate [`clean::Type::Path`]s, and is used to print /// out extra documentation on the page of an enum/struct. /// /// The values of the map are a list of implementations and documentation /// found on that implementation. - crate impls: FxHashMap>, + pub(crate) impls: FxHashMap>, /// Maintains a mapping of local crate `DefId`s to the fully qualified name /// and "short type description" of that node. This is used when generating /// URLs when a type is being linked to. External paths are not located in /// this map because the `External` type itself has all the information /// necessary. - crate paths: FxHashMap, ItemType)>, + pub(crate) paths: FxHashMap, ItemType)>, /// Similar to `paths`, but only holds external paths. This is only used for /// generating explicit hyperlinks to other crates. - crate external_paths: FxHashMap, ItemType)>, + pub(crate) external_paths: FxHashMap, ItemType)>, /// Maps local `DefId`s of exported types to fully qualified paths. /// Unlike 'paths', this mapping ignores any renames that occur @@ -56,56 +56,55 @@ crate struct Cache { /// to the path used if the corresponding type is inlined. By /// doing this, we can detect duplicate impls on a trait page, and only display /// the impl for the inlined type. - crate exact_paths: FxHashMap>, + pub(crate) exact_paths: FxHashMap>, /// This map contains information about all known traits of this crate. /// Implementations of a crate should inherit the documentation of the /// parent trait if no extra documentation is specified, and default methods /// should show up in documentation about trait implementations. - crate traits: FxHashMap, + pub(crate) traits: FxHashMap, /// When rendering traits, it's often useful to be able to list all /// implementors of the trait, and this mapping is exactly, that: a mapping /// of trait ids to the list of known implementors of the trait - crate implementors: FxHashMap>, + pub(crate) implementors: FxHashMap>, /// Cache of where external crate documentation can be found. - crate extern_locations: FxHashMap, + pub(crate) extern_locations: FxHashMap, /// Cache of where documentation for primitives can be found. - crate primitive_locations: FxHashMap, + pub(crate) primitive_locations: FxHashMap, // Note that external items for which `doc(hidden)` applies to are shown as // non-reachable while local items aren't. This is because we're reusing // the access levels from the privacy check pass. - crate access_levels: AccessLevels, + pub(crate) access_levels: AccessLevels, /// The version of the crate being documented, if given from the `--crate-version` flag. - crate crate_version: Option, + pub(crate) crate_version: Option, /// Whether to document private items. /// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions. - crate document_private: bool, + pub(crate) document_private: bool, /// Crates marked with [`#[doc(masked)]`][doc_masked]. /// /// [doc_masked]: https://doc.rust-lang.org/nightly/unstable-book/language-features/doc-masked.html - crate masked_crates: FxHashSet, + pub(crate) masked_crates: FxHashSet, // Private fields only used when initially crawling a crate to build a cache stack: Vec, - parent_stack: Vec, - parent_is_trait_impl: bool, + parent_stack: Vec, stripped_mod: bool, - crate search_index: Vec, + pub(crate) search_index: Vec, // In rare case where a structure is defined in one module but implemented // in another, if the implementing module is parsed before defining module, // then the fully qualified name of the structure isn't presented in `paths` // yet when its implementation methods are being indexed. Caches such methods // and their parent id here and indexes them at the end of crate parsing. - crate orphan_impl_items: Vec<(DefId, clean::Item)>, + pub(crate) orphan_impl_items: Vec, // Similarly to `orphan_impl_items`, sometimes trait impls are picked up // even though the trait itself is not exported. This can happen if a trait @@ -119,9 +118,9 @@ crate struct Cache { /// All intra-doc links resolved so far. /// /// Links are indexed by the DefId of the item they document. - crate intra_doc_links: FxHashMap>, + pub(crate) intra_doc_links: FxHashMap>, /// Cfg that have been hidden via #![doc(cfg_hide(...))] - crate hidden_cfg: FxHashSet, + pub(crate) hidden_cfg: FxHashSet, } /// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`. @@ -133,13 +132,13 @@ struct CacheBuilder<'a, 'tcx> { } impl Cache { - crate fn new(access_levels: AccessLevels, document_private: bool) -> Self { + pub(crate) fn new(access_levels: AccessLevels, document_private: bool) -> Self { Cache { access_levels, document_private, ..Cache::default() } } /// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was /// in `krate` due to the data being moved into the `Cache`. - crate fn populate(cx: &mut DocContext<'_>, mut krate: clean::Crate) -> clean::Crate { + pub(crate) fn populate(cx: &mut DocContext<'_>, mut krate: clean::Crate) -> clean::Crate { let tcx = cx.tcx; // Crawl the crate to build various caches used for the output @@ -261,7 +260,11 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { let (parent, is_inherent_impl_item) = match *item.kind { clean::StrippedItem(..) => ((None, None), false), clean::AssocConstItem(..) | clean::AssocTypeItem(..) - if self.cache.parent_is_trait_impl => + if self + .cache + .parent_stack + .last() + .map_or(false, |parent| parent.is_trait_impl()) => { // skip associated items in trait impls ((None, None), false) @@ -272,7 +275,14 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { | clean::StructFieldItem(..) | clean::VariantItem(..) => ( ( - Some(*self.cache.parent_stack.last().expect("parent_stack is empty")), + Some( + self.cache + .parent_stack + .last() + .expect("parent_stack is empty") + .item_id() + .expect_def_id(), + ), Some(&self.cache.stack[..self.cache.stack.len() - 1]), ), false, @@ -282,8 +292,11 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { ((None, None), false) } else { let last = self.cache.parent_stack.last().expect("parent_stack is empty 2"); - let did = *last; - let path = match self.cache.paths.get(&did) { + let did = match &*last { + ParentStackItem::Impl { for_, .. } => for_.def_id(&self.cache), + ParentStackItem::Type(item_id) => item_id.as_def_id(), + }; + let path = match did.and_then(|did| self.cache.paths.get(&did)) { // The current stack not necessarily has correlation // for where the type was defined. On the other // hand, `paths` always has the right @@ -291,7 +304,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { Some(&(ref fqp, _)) => Some(&fqp[..fqp.len() - 1]), None => None, }; - ((Some(*last), path), true) + ((did, path), true) } } _ => ((None, Some(&*self.cache.stack)), false), @@ -315,7 +328,12 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { desc, parent, parent_idx: None, - search_type: get_function_type_for_search(&item, self.tcx, self.cache), + search_type: get_function_type_for_search( + &item, + self.tcx, + clean_impl_generics(self.cache.parent_stack.last()).as_ref(), + self.cache, + ), aliases: item.attrs.get_doc_aliases(), }); } @@ -323,7 +341,12 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { (Some(parent), None) if is_inherent_impl_item => { // We have a parent, but we don't know where they're // defined yet. Wait for later to index this item. - self.cache.orphan_impl_items.push((parent, item.clone())); + let impl_generics = clean_impl_generics(self.cache.parent_stack.last()); + self.cache.orphan_impl_items.push(OrphanImplItem { + parent, + item: item.clone(), + impl_generics, + }); } _ => {} } @@ -398,51 +421,23 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { } } - // Maintain the parent stack - let orig_parent_is_trait_impl = self.cache.parent_is_trait_impl; - let parent_pushed = match *item.kind { + // Maintain the parent stack. + let (item, parent_pushed) = match *item.kind { clean::TraitItem(..) | clean::EnumItem(..) | clean::ForeignTypeItem | clean::StructItem(..) | clean::UnionItem(..) - | clean::VariantItem(..) => { - self.cache.parent_stack.push(item.item_id.expect_def_id()); - self.cache.parent_is_trait_impl = false; - true - } - clean::ImplItem(ref i) => { - self.cache.parent_is_trait_impl = i.trait_.is_some(); - match i.for_ { - clean::Type::Path { ref path } => { - self.cache.parent_stack.push(path.def_id()); - true - } - clean::DynTrait(ref bounds, _) - | clean::BorrowedRef { type_: box clean::DynTrait(ref bounds, _), .. } => { - self.cache.parent_stack.push(bounds[0].trait_.def_id()); - true - } - ref t => { - let prim_did = t - .primitive_type() - .and_then(|t| self.cache.primitive_locations.get(&t).cloned()); - match prim_did { - Some(did) => { - self.cache.parent_stack.push(did); - true - } - None => false, - } - } - } + | clean::VariantItem(..) + | clean::ImplItem(..) => { + self.cache.parent_stack.push(ParentStackItem::new(&item)); + (self.fold_item_recur(item), true) } - _ => false, + _ => (self.fold_item_recur(item), false), }; // Once we've recursively found all the generics, hoard off all the // implementations elsewhere. - let item = self.fold_item_recur(item); let ret = if let clean::Item { kind: box clean::ImplItem(ref i), .. } = item { // Figure out the id of this impl. This may map to a // primitive rather than always to a struct/enum. @@ -452,6 +447,15 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { clean::Type::Path { ref path } | clean::BorrowedRef { type_: box clean::Type::Path { ref path }, .. } => { dids.insert(path.def_id()); + if let Some(generics) = path.generics() && + let ty::Adt(adt, _) = self.tcx.type_of(path.def_id()).kind() && + adt.is_fundamental() { + for ty in generics { + if let Some(did) = ty.def_id(self.cache) { + dids.insert(did); + } + } + } } clean::DynTrait(ref bounds, _) | clean::BorrowedRef { type_: box clean::DynTrait(ref bounds, _), .. } => { @@ -502,7 +506,64 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { self.cache.parent_stack.pop().expect("parent stack already empty"); } self.cache.stripped_mod = orig_stripped_mod; - self.cache.parent_is_trait_impl = orig_parent_is_trait_impl; ret } } + +pub(crate) struct OrphanImplItem { + pub(crate) parent: DefId, + pub(crate) item: clean::Item, + pub(crate) impl_generics: Option<(clean::Type, clean::Generics)>, +} + +/// Information about trait and type parents is tracked while traversing the item tree to build +/// the cache. +/// +/// We don't just store `Item` in there, because `Item` contains the list of children being +/// traversed and it would be wasteful to clone all that. We also need the item id, so just +/// storing `ItemKind` won't work, either. +enum ParentStackItem { + Impl { + for_: clean::Type, + trait_: Option, + generics: clean::Generics, + kind: clean::ImplKind, + item_id: ItemId, + }, + Type(ItemId), +} + +impl ParentStackItem { + fn new(item: &clean::Item) -> Self { + match &*item.kind { + clean::ItemKind::ImplItem(clean::Impl { for_, trait_, generics, kind, .. }) => { + ParentStackItem::Impl { + for_: for_.clone(), + trait_: trait_.clone(), + generics: generics.clone(), + kind: kind.clone(), + item_id: item.item_id, + } + } + _ => ParentStackItem::Type(item.item_id), + } + } + fn is_trait_impl(&self) -> bool { + matches!(self, ParentStackItem::Impl { trait_: Some(..), .. }) + } + fn item_id(&self) -> ItemId { + match self { + ParentStackItem::Impl { item_id, .. } => *item_id, + ParentStackItem::Type(item_id) => *item_id, + } + } +} + +fn clean_impl_generics(item: Option<&ParentStackItem>) -> Option<(clean::Type, clean::Generics)> { + if let Some(ParentStackItem::Impl { for_, generics, kind: clean::ImplKind::Normal, .. }) = item + { + Some((for_.clone(), generics.clone())) + } else { + None + } +} diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index fb4afb769a..eca5501cd3 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -21,7 +21,7 @@ use crate::clean; /// a heading, edit the listing in `html/render.rs`, function `sidebar_module`. This uses an /// ordering based on a helper function inside `item_module`, in the same file. #[derive(Copy, PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)] -crate enum ItemType { +pub(crate) enum ItemType { Module = 0, ExternCrate = 1, Import = 2, @@ -147,7 +147,7 @@ impl From for ItemType { } impl ItemType { - crate fn as_str(&self) -> &'static str { + pub(crate) fn as_str(&self) -> &'static str { match *self { ItemType::Module => "mod", ItemType::ExternCrate => "externcrate", diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs index 3e36318eb7..b236bd7be4 100644 --- a/src/librustdoc/formats/mod.rs +++ b/src/librustdoc/formats/mod.rs @@ -1,16 +1,17 @@ -crate mod cache; -crate mod item_type; -crate mod renderer; +pub(crate) mod cache; +pub(crate) mod item_type; +pub(crate) mod renderer; use rustc_hir::def_id::DefId; -crate use renderer::{run_format, FormatRenderer}; +pub(crate) use renderer::{run_format, FormatRenderer}; use crate::clean::{self, ItemId}; +use crate::html::render::Context; /// Specifies whether rendering directly implemented trait items or ones from a certain Deref /// impl. -crate enum AssocItemRender<'a> { +pub(crate) enum AssocItemRender<'a> { All, DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool }, } @@ -18,26 +19,26 @@ crate enum AssocItemRender<'a> { /// For different handling of associated items from the Deref target of a type rather than the type /// itself. #[derive(Copy, Clone, PartialEq)] -crate enum RenderMode { +pub(crate) enum RenderMode { Normal, ForDeref { mut_: bool }, } /// Metadata about implementations for a type or trait. #[derive(Clone, Debug)] -crate struct Impl { - crate impl_item: clean::Item, +pub(crate) struct Impl { + pub(crate) impl_item: clean::Item, } impl Impl { - crate fn inner_impl(&self) -> &clean::Impl { + pub(crate) fn inner_impl(&self) -> &clean::Impl { match *self.impl_item.kind { clean::ImplItem(ref impl_) => impl_, _ => panic!("non-impl item found in impl"), } } - crate fn trait_did(&self) -> Option { + pub(crate) fn trait_did(&self) -> Option { self.inner_impl().trait_.as_ref().map(|t| t.def_id()) } @@ -47,7 +48,7 @@ impl Impl { /// with blanket impls). /// /// It panics if `self` is a `ItemId::Primitive`. - crate fn def_id(&self) -> DefId { + pub(crate) fn def_id(&self) -> DefId { match self.impl_item.item_id { ItemId::Blanket { impl_id, .. } => impl_id, ItemId::Auto { trait_, .. } => trait_, @@ -60,4 +61,41 @@ impl Impl { } } } + + // Returns true if this is an implementation on a "local" type, meaning: + // the type is in the current crate, or the type and the trait are both + // re-exported by the current crate. + pub(crate) fn is_on_local_type(&self, cx: &Context<'_>) -> bool { + let cache = cx.cache(); + let for_type = &self.inner_impl().for_; + if let Some(for_type_did) = for_type.def_id(cache) { + // The "for" type is local if it's in the paths for the current crate. + if cache.paths.contains_key(&for_type_did) { + return true; + } + if let Some(trait_did) = self.trait_did() { + // The "for" type and the trait are from the same crate. That could + // be different from the current crate, for instance when both were + // re-exported from some other crate. But they are local with respect to + // each other. + if for_type_did.krate == trait_did.krate { + return true; + } + // Hack: many traits and types in std are re-exported from + // core or alloc. In general, rustdoc is capable of recognizing + // these implementations as being on local types. However, in at + // least one case (https://github.com/rust-lang/rust/issues/97610), + // rustdoc gets confused and labels an implementation as being on + // a foreign type. To make sure that confusion doesn't pass on to + // the reader, consider all implementations in std, core, and alloc + // to be on local types. + let crate_name = cx.tcx().crate_name(trait_did.krate); + if matches!(crate_name.as_str(), "std" | "core" | "alloc") { + return true; + } + } + return false; + }; + true + } } diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 2403ff4eba..62ba984acc 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -9,7 +9,7 @@ use crate::formats::cache::Cache; /// Allows for different backends to rustdoc to be used with the `run_format()` function. Each /// backend renderer has hooks for initialization, documenting an item, entering and exiting a /// module, and cleanup/finalizing output. -crate trait FormatRenderer<'tcx>: Sized { +pub(crate) trait FormatRenderer<'tcx>: Sized { /// Gives a description of the renderer. Used for performance profiling. fn descr() -> &'static str; @@ -48,7 +48,7 @@ crate trait FormatRenderer<'tcx>: Sized { } /// Main method for rendering a crate. -crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( +pub(crate) fn run_format<'tcx, T: FormatRenderer<'tcx>>( krate: clean::Crate, options: RenderOptions, cache: Cache, diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index ce44722a53..4a19d0a44c 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -7,7 +7,7 @@ use std::fmt; /// Wrapper struct which will emit the HTML-escaped version of the contained /// string when passed to a format string. -crate struct Escape<'a>(pub &'a str); +pub(crate) struct Escape<'a>(pub &'a str); impl<'a> fmt::Display for Escape<'a> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 528eb6410c..056eda089c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -5,16 +5,19 @@ //! assume that HTML output is desired, although it may be possible to redesign //! them in the future to instead emit any format desired. +use std::borrow::Cow; use std::cell::Cell; use std::fmt; -use std::iter; +use std::iter::{self, once}; +use rustc_ast as ast; use rustc_attr::{ConstStability, StabilityLevel}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; +use rustc_metadata::creader::{CStore, LoadedMacro}; use rustc_middle::ty; use rustc_middle::ty::DefIdTree; use rustc_middle::ty::TyCtxt; @@ -22,6 +25,8 @@ use rustc_span::symbol::kw; use rustc_span::{sym, Symbol}; use rustc_target::spec::abi::Abi; +use itertools::Itertools; + use crate::clean::{ self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, ItemId, PrimitiveType, @@ -33,7 +38,7 @@ use crate::html::render::Context; use super::url_parts_builder::estimate_item_path_byte_length; use super::url_parts_builder::UrlPartsBuilder; -crate trait Print { +pub(crate) trait Print { fn print(self, buffer: &mut Buffer); } @@ -59,7 +64,7 @@ impl Print for &'_ str { } #[derive(Debug, Clone)] -crate struct Buffer { +pub(crate) struct Buffer { for_html: bool, buffer: String, } @@ -82,63 +87,63 @@ impl core::fmt::Write for Buffer { } impl Buffer { - crate fn empty_from(v: &Buffer) -> Buffer { + pub(crate) fn empty_from(v: &Buffer) -> Buffer { Buffer { for_html: v.for_html, buffer: String::new() } } - crate fn html() -> Buffer { + pub(crate) fn html() -> Buffer { Buffer { for_html: true, buffer: String::new() } } - crate fn new() -> Buffer { + pub(crate) fn new() -> Buffer { Buffer { for_html: false, buffer: String::new() } } - crate fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { self.buffer.is_empty() } - crate fn into_inner(self) -> String { + pub(crate) fn into_inner(self) -> String { self.buffer } - crate fn insert_str(&mut self, idx: usize, s: &str) { + pub(crate) fn insert_str(&mut self, idx: usize, s: &str) { self.buffer.insert_str(idx, s); } - crate fn push_str(&mut self, s: &str) { + pub(crate) fn push_str(&mut self, s: &str) { self.buffer.push_str(s); } - crate fn push_buffer(&mut self, other: Buffer) { + pub(crate) fn push_buffer(&mut self, other: Buffer) { self.buffer.push_str(&other.buffer); } // Intended for consumption by write! and writeln! (std::fmt) but without // the fmt::Result return type imposed by fmt::Write (and avoiding the trait // import). - crate fn write_str(&mut self, s: &str) { + pub(crate) fn write_str(&mut self, s: &str) { self.buffer.push_str(s); } // Intended for consumption by write! and writeln! (std::fmt) but without // the fmt::Result return type imposed by fmt::Write (and avoiding the trait // import). - crate fn write_fmt(&mut self, v: fmt::Arguments<'_>) { + pub(crate) fn write_fmt(&mut self, v: fmt::Arguments<'_>) { use fmt::Write; self.buffer.write_fmt(v).unwrap(); } - crate fn to_display(mut self, t: T) -> String { + pub(crate) fn to_display(mut self, t: T) -> String { t.print(&mut self); self.into_inner() } - crate fn is_for_html(&self) -> bool { + pub(crate) fn is_for_html(&self) -> bool { self.for_html } - crate fn reserve(&mut self, additional: usize) { + pub(crate) fn reserve(&mut self, additional: usize) { self.buffer.reserve(additional) } } @@ -158,7 +163,7 @@ fn comma_sep( }) } -crate fn print_generic_bounds<'a, 'tcx: 'a>( +pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( bounds: &'a [clean::GenericBound], cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -176,7 +181,7 @@ crate fn print_generic_bounds<'a, 'tcx: 'a>( } impl clean::GenericParamDef { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -239,7 +244,7 @@ impl clean::GenericParamDef { } impl clean::Generics { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -262,7 +267,7 @@ impl clean::Generics { /// * The Generics from which to emit a where-clause. /// * The number of spaces to indent each line with. /// * Whether the where-clause needs to add a comma and newline after the last bound. -crate fn print_where_clause<'a, 'tcx: 'a>( +pub(crate) fn print_where_clause<'a, 'tcx: 'a>( gens: &'a clean::Generics, cx: &'a Context<'tcx>, indent: usize, @@ -372,13 +377,13 @@ crate fn print_where_clause<'a, 'tcx: 'a>( } impl clean::Lifetime { - crate fn print(&self) -> impl fmt::Display + '_ { + pub(crate) fn print(&self) -> impl fmt::Display + '_ { self.0.as_str() } } impl clean::Constant { - crate fn print(&self, tcx: TyCtxt<'_>) -> impl fmt::Display + '_ { + pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl fmt::Display + '_ { let expr = self.expr(tcx); display_fn( move |f| { @@ -419,7 +424,7 @@ impl clean::PolyTrait { } impl clean::GenericBound { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -457,7 +462,7 @@ impl clean::GenericArgs { f.write_str("<")?; } let mut comma = false; - for arg in args { + for arg in args.iter() { if comma { f.write_str(", ")?; } @@ -468,7 +473,7 @@ impl clean::GenericArgs { write!(f, "{}", arg.print(cx))?; } } - for binding in bindings { + for binding in bindings.iter() { if comma { f.write_str(", ")?; } @@ -489,7 +494,7 @@ impl clean::GenericArgs { clean::GenericArgs::Parenthesized { inputs, output } => { f.write_str("(")?; let mut comma = false; - for ty in inputs { + for ty in inputs.iter() { if comma { f.write_str(", ")?; } @@ -516,7 +521,8 @@ impl clean::GenericArgs { } // Possible errors when computing href link source for a `DefId` -crate enum HrefError { +#[derive(PartialEq, Eq)] +pub(crate) enum HrefError { /// This item is known to rustdoc, but from a crate that does not have documentation generated. /// /// This can only happen for non-local items. @@ -543,17 +549,90 @@ crate enum HrefError { } // Panics if `syms` is empty. -crate fn join_with_double_colon(syms: &[Symbol]) -> String { +pub(crate) fn join_with_double_colon(syms: &[Symbol]) -> String { let mut s = String::with_capacity(estimate_item_path_byte_length(syms.len())); - s.push_str(&syms[0].as_str()); + s.push_str(syms[0].as_str()); for sym in &syms[1..] { s.push_str("::"); - s.push_str(&sym.as_str()); + s.push_str(sym.as_str()); } s } -crate fn href_with_root_path( +/// This function is to get the external macro path because they are not in the cache used in +/// `href_with_root_path`. +fn generate_macro_def_id_path( + def_id: DefId, + cx: &Context<'_>, + root_path: Option<&str>, +) -> Result<(String, ItemType, Vec), HrefError> { + let tcx = cx.shared.tcx; + let crate_name = tcx.crate_name(def_id.krate).to_string(); + let cache = cx.cache(); + + let fqp: Vec = tcx + .def_path(def_id) + .data + .into_iter() + .filter_map(|elem| { + // extern blocks (and a few others things) have an empty name. + match elem.data.get_opt_name() { + Some(s) if !s.is_empty() => Some(s), + _ => None, + } + }) + .collect(); + let relative = fqp.iter().map(|elem| elem.to_string()); + let cstore = CStore::from_tcx(tcx); + // We need this to prevent a `panic` when this function is used from intra doc links... + if !cstore.has_crate_data(def_id.krate) { + debug!("No data for crate {}", crate_name); + return Err(HrefError::NotInExternalCache); + } + // Check to see if it is a macro 2.0 or built-in macro. + // More information in . + let is_macro_2 = match cstore.load_macro_untracked(def_id, tcx.sess) { + LoadedMacro::MacroDef(def, _) => { + // If `ast_def.macro_rules` is `true`, then it's not a macro 2.0. + matches!(&def.kind, ast::ItemKind::MacroDef(ast_def) if !ast_def.macro_rules) + } + _ => false, + }; + + let mut path = if is_macro_2 { + once(crate_name.clone()).chain(relative).collect() + } else { + vec![crate_name.clone(), relative.last().unwrap()] + }; + if path.len() < 2 { + // The minimum we can have is the crate name followed by the macro name. If shorter, then + // it means that that `relative` was empty, which is an error. + debug!("macro path cannot be empty!"); + return Err(HrefError::NotInExternalCache); + } + + if let Some(last) = path.last_mut() { + *last = format!("macro.{}.html", last); + } + + let url = match cache.extern_locations[&def_id.krate] { + ExternalLocation::Remote(ref s) => { + // `ExternalLocation::Remote` always end with a `/`. + format!("{}{}", s, path.join("/")) + } + ExternalLocation::Local => { + // `root_path` always end with a `/`. + format!("{}{}/{}", root_path.unwrap_or(""), crate_name, path.join("/")) + } + ExternalLocation::Unknown => { + debug!("crate {} not in cache when linkifying macros", crate_name); + return Err(HrefError::NotInExternalCache); + } + }; + Ok((url, ItemType::Macro, fqp)) +} + +pub(crate) fn href_with_root_path( did: DefId, cx: &Context<'_>, root_path: Option<&str>, @@ -608,6 +687,8 @@ crate fn href_with_root_path( ExternalLocation::Unknown => return Err(HrefError::DocumentationNotBuilt), }, ) + } else if matches!(def_kind, DefKind::Macro(_)) { + return generate_macro_def_id_path(did, cx, root_path); } else { return Err(HrefError::NotInExternalCache); } @@ -633,14 +714,17 @@ crate fn href_with_root_path( Ok((url_parts.finish(), shortty, fqp.to_vec())) } -crate fn href(did: DefId, cx: &Context<'_>) -> Result<(String, ItemType, Vec), HrefError> { +pub(crate) fn href( + did: DefId, + cx: &Context<'_>, +) -> Result<(String, ItemType, Vec), HrefError> { href_with_root_path(did, cx, None) } /// Both paths should only be modules. /// This is because modules get their own directories; that is, `std::vec` and `std::vec::Vec` will /// both need `../iter/trait.Iterator.html` to get at the iterator trait. -crate fn href_relative_parts<'fqp>( +pub(crate) fn href_relative_parts<'fqp>( fqp: &'fqp [Symbol], relative_to_fqp: &[Symbol], ) -> Box + 'fqp> { @@ -709,6 +793,16 @@ fn primitive_link( prim: clean::PrimitiveType, name: &str, cx: &Context<'_>, +) -> fmt::Result { + primitive_link_fragment(f, prim, name, "", cx) +} + +fn primitive_link_fragment( + f: &mut fmt::Formatter<'_>, + prim: clean::PrimitiveType, + name: &str, + fragment: &str, + cx: &Context<'_>, ) -> fmt::Result { let m = &cx.cache(); let mut needs_termination = false; @@ -719,7 +813,7 @@ fn primitive_link( let len = if len == 0 { 0 } else { len - 1 }; write!( f, - "", + "", "../".repeat(len), prim.as_sym() )?; @@ -750,7 +844,7 @@ fn primitive_link( }; if let Some(mut loc) = loc { loc.push_fmt(format_args!("primitive.{}.html", prim.as_sym())); - write!(f, "", loc.finish())?; + write!(f, "", loc.finish())?; needs_termination = true; } } @@ -787,7 +881,7 @@ fn tybounds<'a, 'tcx: 'a>( }) } -crate fn anchor<'a, 'cx: 'a>( +pub(crate) fn anchor<'a, 'cx: 'a>( did: DefId, text: Symbol, cx: &'cx Context<'_>, @@ -860,28 +954,55 @@ fn fmt_type<'cx>( match &typs[..] { &[] => primitive_link(f, PrimitiveType::Unit, "()", cx), &[ref one] => { - primitive_link(f, PrimitiveType::Tuple, "(", cx)?; - // Carry `f.alternate()` into this display w/o branching manually. - fmt::Display::fmt(&one.print(cx), f)?; - primitive_link(f, PrimitiveType::Tuple, ",)", cx) + if let clean::Generic(name) = one { + primitive_link(f, PrimitiveType::Tuple, &format!("({name},)"), cx) + } else { + write!(f, "(")?; + // Carry `f.alternate()` into this display w/o branching manually. + fmt::Display::fmt(&one.print(cx), f)?; + write!(f, ",)") + } } many => { - primitive_link(f, PrimitiveType::Tuple, "(", cx)?; - for (i, item) in many.iter().enumerate() { - if i != 0 { - write!(f, ", ")?; + let generic_names: Vec = many + .iter() + .filter_map(|t| match t { + clean::Generic(name) => Some(*name), + _ => None, + }) + .collect(); + let is_generic = generic_names.len() == many.len(); + if is_generic { + primitive_link( + f, + PrimitiveType::Tuple, + &format!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")), + cx, + ) + } else { + write!(f, "(")?; + for (i, item) in many.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + // Carry `f.alternate()` into this display w/o branching manually. + fmt::Display::fmt(&item.print(cx), f)?; } - fmt::Display::fmt(&item.print(cx), f)?; + write!(f, ")") } - primitive_link(f, PrimitiveType::Tuple, ")", cx) } } } - clean::Slice(ref t) => { - primitive_link(f, PrimitiveType::Slice, "[", cx)?; - fmt::Display::fmt(&t.print(cx), f)?; - primitive_link(f, PrimitiveType::Slice, "]", cx) - } + clean::Slice(ref t) => match **t { + clean::Generic(name) => { + primitive_link(f, PrimitiveType::Slice, &format!("[{name}]"), cx) + } + _ => { + write!(f, "[")?; + fmt::Display::fmt(&t.print(cx), f)?; + write!(f, "]") + } + }, clean::Array(ref t, ref n) => { primitive_link(f, PrimitiveType::Array, "[", cx)?; fmt::Display::fmt(&t.print(cx), f)?; @@ -917,42 +1038,6 @@ fn fmt_type<'cx>( let m = mutability.print_with_space(); let amp = if f.alternate() { "&".to_string() } else { "&".to_string() }; match **ty { - clean::Slice(ref bt) => { - // `BorrowedRef{ ... Slice(T) }` is `&[T]` - match **bt { - clean::Generic(_) => { - if f.alternate() { - primitive_link( - f, - PrimitiveType::Slice, - &format!("{}{}{}[{:#}]", amp, lt, m, bt.print(cx)), - cx, - ) - } else { - primitive_link( - f, - PrimitiveType::Slice, - &format!("{}{}{}[{}]", amp, lt, m, bt.print(cx)), - cx, - ) - } - } - _ => { - primitive_link( - f, - PrimitiveType::Slice, - &format!("{}{}{}[", amp, lt, m), - cx, - )?; - if f.alternate() { - write!(f, "{:#}", bt.print(cx))?; - } else { - write!(f, "{}", bt.print(cx))?; - } - primitive_link(f, PrimitiveType::Slice, "]", cx) - } - } - } clean::DynTrait(ref bounds, ref trait_lt) if bounds.len() > 1 || trait_lt.is_some() => { @@ -982,11 +1067,7 @@ fn fmt_type<'cx>( write!(f, "impl {}", print_generic_bounds(bounds, cx)) } } - clean::QPath { ref assoc, ref self_type, ref trait_, ref self_def_id } => { - let should_show_cast = !trait_.segments.is_empty() - && self_def_id - .zip(Some(trait_.def_id())) - .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_); + clean::QPath { ref assoc, ref self_type, ref trait_, should_show_cast } => { if f.alternate() { if should_show_cast { write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))? @@ -1031,7 +1112,7 @@ fn fmt_type<'cx>( } impl clean::Type { - crate fn print<'b, 'a: 'b, 'tcx: 'a>( + pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'b + Captures<'tcx> { @@ -1040,7 +1121,7 @@ impl clean::Type { } impl clean::Path { - crate fn print<'b, 'a: 'b, 'tcx: 'a>( + pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'b + Captures<'tcx> { @@ -1049,7 +1130,7 @@ impl clean::Path { } impl clean::Impl { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, use_absolute: bool, cx: &'a Context<'tcx>, @@ -1070,7 +1151,13 @@ impl clean::Impl { write!(f, " for ")?; } - if let Some(ref ty) = self.kind.as_blanket_ty() { + if let clean::Type::Tuple(types) = &self.for_ && + let [clean::Type::Generic(name)] = &types[..] && + (self.kind.is_tuple_variadic() || self.kind.is_auto()) { + // Hardcoded anchor library/core/src/primitive_docs.rs + // Link should match `# Trait implementations` + primitive_link_fragment(f, PrimitiveType::Tuple, &format!("({name}₁, {name}₂, …, {name}ₙ)"), "#trait-implementations-1", cx)?; + } else if let Some(ty) = self.kind.as_blanket_ty() { fmt_type(ty, f, use_absolute, cx)?; } else { fmt_type(&self.for_, f, use_absolute, cx)?; @@ -1083,7 +1170,7 @@ impl clean::Impl { } impl clean::Arguments { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -1107,7 +1194,7 @@ impl clean::Arguments { } impl clean::FnRetTy { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -1142,7 +1229,7 @@ impl clean::BareFunctionDecl { } impl clean::FnDecl { - crate fn print<'b, 'a: 'b, 'tcx: 'a>( + pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'b + Captures<'tcx> { @@ -1174,7 +1261,7 @@ impl clean::FnDecl { /// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is /// necessary. /// * `asyncness`: Whether the function is async or not. - crate fn full_print<'a, 'tcx: 'a>( + pub(crate) fn full_print<'a, 'tcx: 'a>( &'a self, header_len: usize, indent: usize, @@ -1291,14 +1378,16 @@ impl clean::FnDecl { } impl clean::Visibility { - crate fn print_with_space<'a, 'tcx: 'a>( + pub(crate) fn print_with_space<'a, 'tcx: 'a>( self, item_did: ItemId, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { - let to_print = match self { - clean::Public => "pub ".to_owned(), - clean::Inherited => String::new(), + use std::fmt::Write as _; + + let to_print: Cow<'static, str> = match self { + clean::Public => "pub ".into(), + clean::Inherited => "".into(), clean::Visibility::Restricted(vis_did) => { // FIXME(camelid): This may not work correctly if `item_did` is a module. // However, rustdoc currently never displays a module's @@ -1306,17 +1395,16 @@ impl clean::Visibility { let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id()); if vis_did.is_crate_root() { - "pub(crate) ".to_owned() + "pub(crate) ".into() } else if parent_module == Some(vis_did) { // `pub(in foo)` where `foo` is the parent module // is the same as no visibility modifier - String::new() + "".into() } else if parent_module - .map(|parent| find_nearest_parent_module(cx.tcx(), parent)) - .flatten() + .and_then(|parent| find_nearest_parent_module(cx.tcx(), parent)) == Some(vis_did) { - "pub(super) ".to_owned() + "pub(super) ".into() } else { let path = cx.tcx().def_path(vis_did); debug!("path={:?}", path); @@ -1326,20 +1414,20 @@ impl clean::Visibility { let mut s = "pub(in ".to_owned(); for seg in &path.data[..path.data.len() - 1] { - s.push_str(&format!("{}::", seg.data.get_opt_name().unwrap())); + let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap()); } - s.push_str(&format!("{}) ", anchor)); - s + let _ = write!(s, "{}) ", anchor); + s.into() } } }; - display_fn(move |f| f.write_str(&to_print)) + display_fn(move |f| write!(f, "{}", to_print)) } /// This function is the same as print_with_space, except that it renders no links. /// It's used for macros' rendered source view, which is syntax highlighted and cannot have /// any HTML in it. - crate fn to_src_with_space<'a, 'tcx: 'a>( + pub(crate) fn to_src_with_space<'a, 'tcx: 'a>( self, tcx: TyCtxt<'tcx>, item_did: DefId, @@ -1359,9 +1447,7 @@ impl clean::Visibility { // `pub(in foo)` where `foo` is the parent module // is the same as no visibility modifier String::new() - } else if parent_module - .map(|parent| find_nearest_parent_module(tcx, parent)) - .flatten() + } else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent)) == Some(vis_did) { "pub(super) ".to_owned() @@ -1374,7 +1460,7 @@ impl clean::Visibility { } } -crate trait PrintWithSpace { +pub(crate) trait PrintWithSpace { fn print_with_space(&self) -> &str; } @@ -1405,7 +1491,10 @@ impl PrintWithSpace for hir::Mutability { } } -crate fn print_constness_with_space(c: &hir::Constness, s: Option) -> &'static str { +pub(crate) fn print_constness_with_space( + c: &hir::Constness, + s: Option, +) -> &'static str { match (c, s) { // const stable or when feature(staged_api) is not set ( @@ -1419,7 +1508,7 @@ crate fn print_constness_with_space(c: &hir::Constness, s: Option( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -1443,7 +1532,7 @@ impl clean::Import { } impl clean::ImportSource { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -1466,7 +1555,7 @@ impl clean::ImportSource { } impl clean::TypeBinding { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -1500,7 +1589,7 @@ impl clean::TypeBinding { } } -crate fn print_abi_with_space(abi: Abi) -> impl fmt::Display { +pub(crate) fn print_abi_with_space(abi: Abi) -> impl fmt::Display { display_fn(move |f| { let quot = if f.alternate() { "\"" } else { """ }; match abi { @@ -1510,12 +1599,12 @@ crate fn print_abi_with_space(abi: Abi) -> impl fmt::Display { }) } -crate fn print_default_space<'a>(v: bool) -> &'a str { +pub(crate) fn print_default_space<'a>(v: bool) -> &'a str { if v { "default " } else { "" } } impl clean::GenericArg { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -1529,7 +1618,7 @@ impl clean::GenericArg { } impl clean::types::Term { - crate fn print<'a, 'tcx: 'a>( + pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { @@ -1540,7 +1629,9 @@ impl clean::types::Term { } } -crate fn display_fn(f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Display { +pub(crate) fn display_fn( + f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, +) -> impl fmt::Display { struct WithFormatter(Cell>); impl fmt::Display for WithFormatter diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index a0187bd77f..d2ef89078b 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -22,21 +22,21 @@ use super::format::{self, Buffer}; use super::render::LinkFromSrc; /// This type is needed in case we want to render links on items to allow to go to their definition. -crate struct ContextInfo<'a, 'b, 'c> { - crate context: &'a Context<'b>, +pub(crate) struct HrefContext<'a, 'b, 'c> { + pub(crate) context: &'a Context<'b>, /// This span contains the current file we're going through. - crate file_span: Span, + pub(crate) file_span: Span, /// This field is used to know "how far" from the top of the directory we are to link to either /// documentation pages or other source pages. - crate root_path: &'c str, + pub(crate) root_path: &'c str, } /// Decorations are represented as a map from CSS class to vector of character ranges. /// Each range will be wrapped in a span with that class. -crate struct DecorationInfo(crate FxHashMap<&'static str, Vec<(u32, u32)>>); +pub(crate) struct DecorationInfo(pub(crate) FxHashMap<&'static str, Vec<(u32, u32)>>); /// Highlights `src`, returning the HTML output. -crate fn render_with_highlighting( +pub(crate) fn render_with_highlighting( src: &str, out: &mut Buffer, class: Option<&str>, @@ -44,7 +44,7 @@ crate fn render_with_highlighting( tooltip: Option<(Option, &str)>, edition: Edition, extra_content: Option, - context_info: Option>, + href_context: Option>, decoration_info: Option, ) { debug!("highlighting: ================\n{}\n==============", src); @@ -62,7 +62,7 @@ crate fn render_with_highlighting( } write_header(out, class, extra_content); - write_code(out, src, edition, context_info, decoration_info); + write_code(out, src, edition, href_context, decoration_info); write_footer(out, playground_button); } @@ -85,8 +85,8 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option>, + href_context: Option>, decoration_info: Option, ) { // This replace allows to fix how the code source with DOS backline characters is displayed. let src = src.replace("\r\n", "\n"); + let mut closing_tags: Vec<&'static str> = Vec::new(); Classifier::new( &src, edition, - context_info.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP), + href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP), decoration_info, ) .highlight(&mut |highlight| { match highlight { - Highlight::Token { text, class } => string(out, Escape(text), class, &context_info), - Highlight::EnterSpan { class } => enter_span(out, class), - Highlight::ExitSpan => exit_span(out), + Highlight::Token { text, class } => string(out, Escape(text), class, &href_context), + Highlight::EnterSpan { class } => { + closing_tags.push(enter_span(out, class, &href_context)) + } + Highlight::ExitSpan => { + exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan")) + } }; }); } @@ -129,7 +134,7 @@ enum Class { RefKeyWord, Self_(Span), Op, - Macro, + Macro(Span), MacroNonTerminal, String, Number, @@ -153,7 +158,7 @@ impl Class { Class::RefKeyWord => "kw-2", Class::Self_(_) => "self", Class::Op => "op", - Class::Macro => "macro", + Class::Macro(_) => "macro", Class::MacroNonTerminal => "macro-nonterminal", Class::String => "string", Class::Number => "number", @@ -171,8 +176,22 @@ impl Class { /// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`). fn get_span(self) -> Option { match self { - Self::Ident(sp) | Self::Self_(sp) => Some(sp), - _ => None, + Self::Ident(sp) | Self::Self_(sp) | Self::Macro(sp) => Some(sp), + Self::Comment + | Self::DocComment + | Self::Attribute + | Self::KeyWord + | Self::RefKeyWord + | Self::Op + | Self::MacroNonTerminal + | Self::String + | Self::Number + | Self::Bool + | Self::Lifetime + | Self::PreludeTy + | Self::PreludeVal + | Self::QuestionMark + | Self::Decoration(_) => None, } } } @@ -611,7 +630,7 @@ impl<'a> Classifier<'a> { }, TokenKind::Ident | TokenKind::RawIdent if lookahead == Some(TokenKind::Bang) => { self.in_macro = true; - sink(Highlight::EnterSpan { class: Class::Macro }); + sink(Highlight::EnterSpan { class: Class::Macro(self.new_span(before, text)) }); sink(Highlight::Token { text, class: None }); return; } @@ -658,13 +677,20 @@ impl<'a> Classifier<'a> { /// Called when we start processing a span of text that should be highlighted. /// The `Class` argument specifies how it should be highlighted. -fn enter_span(out: &mut Buffer, klass: Class) { - write!(out, "", klass.as_html()); +fn enter_span( + out: &mut Buffer, + klass: Class, + href_context: &Option>, +) -> &'static str { + string_without_closing_tag(out, "", Some(klass), href_context).expect( + "internal error: enter_span was called with Some(klass) but did not return a \ + closing HTML tag", + ) } /// Called at the end of a span of highlighted text. -fn exit_span(out: &mut Buffer) { - out.write_str(""); +fn exit_span(out: &mut Buffer, closing_tag: &str) { + out.write_str(closing_tag); } /// Called for a span of text. If the text should be highlighted differently @@ -687,15 +713,39 @@ fn string( out: &mut Buffer, text: T, klass: Option, - context_info: &Option>, + href_context: &Option>, ) { + if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context) { + out.write_str(closing_tag); + } +} + +/// This function writes `text` into `out` with some modifications depending on `klass`: +/// +/// * If `klass` is `None`, `text` is written into `out` with no modification. +/// * If `klass` is `Some` but `klass.get_span()` is `None`, it writes the text wrapped in a +/// `` with the provided `klass`. +/// * If `klass` is `Some` and has a [`rustc_span::Span`], it then tries to generate a link (`` +/// element) by retrieving the link information from the `span_correspondance_map` that was filled +/// in `span_map.rs::collect_spans_and_sources`. If it cannot retrieve the information, then it's +/// the same as the second point (`klass` is `Some` but doesn't have a [`rustc_span::Span`]). +fn string_without_closing_tag( + out: &mut Buffer, + text: T, + klass: Option, + href_context: &Option>, +) -> Option<&'static str> { let Some(klass) = klass - else { return write!(out, "{}", text) }; + else { + write!(out, "{}", text); + return None; + }; let Some(def_span) = klass.get_span() else { - write!(out, "{}", klass.as_html(), text); - return; + write!(out, "{}", klass.as_html(), text); + return Some(""); }; + let mut text_s = text.to_string(); if text_s.contains("::") { text_s = text_s.split("::").intersperse("::").fold(String::new(), |mut path, t| { @@ -715,10 +765,10 @@ fn string( path }); } - if let Some(context_info) = context_info { + if let Some(href_context) = href_context { if let Some(href) = - context_info.context.shared.span_correspondance_map.get(&def_span).and_then(|href| { - let context = context_info.context; + href_context.context.shared.span_correspondance_map.get(&def_span).and_then(|href| { + let context = href_context.context; // FIXME: later on, it'd be nice to provide two links (if possible) for all items: // one to the documentation page and one to the source definition. // FIXME: currently, external items only generate a link to their documentation, @@ -727,27 +777,28 @@ fn string( match href { LinkFromSrc::Local(span) => context .href_from_span(*span, true) - .map(|s| format!("{}{}", context_info.root_path, s)), + .map(|s| format!("{}{}", href_context.root_path, s)), LinkFromSrc::External(def_id) => { - format::href_with_root_path(*def_id, context, Some(context_info.root_path)) + format::href_with_root_path(*def_id, context, Some(href_context.root_path)) .ok() .map(|(url, _, _)| url) } LinkFromSrc::Primitive(prim) => format::href_with_root_path( PrimitiveType::primitive_locations(context.tcx())[prim], context, - Some(context_info.root_path), + Some(href_context.root_path), ) .ok() .map(|(url, _, _)| url), } }) { - write!(out, "{}", klass.as_html(), href, text_s); - return; + write!(out, "{}", klass.as_html(), href, text_s); + return Some(""); } } - write!(out, "{}", klass.as_html(), text_s); + write!(out, "{}", klass.as_html(), text_s); + Some("") } #[cfg(test)] diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 4ca71ea868..7d6d4b71e2 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -10,33 +10,31 @@ use crate::html::render::{ensure_trailing_slash, StylePath}; use askama::Template; #[derive(Clone)] -crate struct Layout { - crate logo: String, - crate favicon: String, - crate external_html: ExternalHtml, - crate default_settings: FxHashMap, - crate krate: String, +pub(crate) struct Layout { + pub(crate) logo: String, + pub(crate) favicon: String, + pub(crate) external_html: ExternalHtml, + pub(crate) default_settings: FxHashMap, + pub(crate) krate: String, /// The given user css file which allow to customize the generated /// documentation theme. - crate css_file_extension: Option, + pub(crate) css_file_extension: Option, /// If true, then scrape-examples.js will be included in the output HTML file - crate scrape_examples_extension: bool, + pub(crate) scrape_examples_extension: bool, } -crate struct Page<'a> { - crate title: &'a str, - crate css_class: &'a str, - crate root_path: &'a str, - crate static_root_path: Option<&'a str>, - crate description: &'a str, - crate keywords: &'a str, - crate resource_suffix: &'a str, - crate extra_scripts: &'a [&'a str], - crate static_extra_scripts: &'a [&'a str], +pub(crate) struct Page<'a> { + pub(crate) title: &'a str, + pub(crate) css_class: &'a str, + pub(crate) root_path: &'a str, + pub(crate) static_root_path: Option<&'a str>, + pub(crate) description: &'a str, + pub(crate) keywords: &'a str, + pub(crate) resource_suffix: &'a str, } impl<'a> Page<'a> { - crate fn get_static_root_path(&self) -> &str { + pub(crate) fn get_static_root_path(&self) -> &str { self.static_root_path.unwrap_or(self.root_path) } } @@ -51,10 +49,10 @@ struct PageLayout<'a> { sidebar: String, content: String, krate_with_trailing_slash: String, - crate rustdoc_version: &'a str, + pub(crate) rustdoc_version: &'a str, } -crate fn render( +pub(crate) fn render( layout: &Layout, page: &Page<'_>, sidebar: S, @@ -86,7 +84,7 @@ crate fn render( .unwrap() } -crate fn redirect(url: &str) -> String { +pub(crate) fn redirect(url: &str) -> String { // ", + "
\ +

\ + Rustdoc settings\ +

\ + \ + \ + Back\ + \ + \ +
\ + \ + \ + ", root_path = page.static_root_path.unwrap_or(""), suffix = page.resource_suffix, ) }, - &self.shared.style_files, + &shared.style_files, ); - self.shared.fs.write(settings_file, v)?; + shared.fs.write(settings_file, v)?; - if self.shared.layout.scrape_examples_extension { + if shared.layout.scrape_examples_extension { page.title = "About scraped examples"; page.description = "How the scraped examples feature works in Rustdoc"; let v = layout::render( - &self.shared.layout, + &shared.layout, &page, "", - scrape_examples_help(&*self.shared), - &self.shared.style_files, + scrape_examples_help(&*shared), + &shared.style_files, ); - self.shared.fs.write(scrape_examples_help_file, v)?; + shared.fs.write(scrape_examples_help_file, v)?; } - if let Some(ref redirections) = self.shared.redirections { + if let Some(ref redirections) = shared.redirections { if !redirections.borrow().is_empty() { let redirect_map_path = self.dst.join(crate_name.as_str()).join("redirect-map.json"); let paths = serde_json::to_string(&*redirections.borrow()).unwrap(); - self.shared.ensure_dir(&self.dst.join(crate_name.as_str()))?; - self.shared.fs.write(redirect_map_path, paths)?; + shared.ensure_dir(&self.dst.join(crate_name.as_str()))?; + shared.fs.write(redirect_map_path, paths)?; } } + // No need for it anymore. + drop(shared); + // Flush pending errors. Rc::get_mut(&mut self.shared).unwrap().fs.close(); let nb_errors = @@ -652,7 +669,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { if !self.render_redirect_pages { self.render_redirect_pages = item.is_stripped(); } - let scx = &self.shared; let item_name = item.name.unwrap(); self.dst.push(&*item_name.as_str()); self.current.push(item_name); @@ -664,7 +680,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { if !buf.is_empty() { self.shared.ensure_dir(&self.dst)?; let joint_dst = self.dst.join("index.html"); - scx.fs.write(joint_dst, buf)?; + self.shared.fs.write(joint_dst, buf)?; } // Render sidebar-items.js used throughout this module. @@ -673,8 +689,8 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { else { unreachable!() }; let items = self.build_sidebar_items(module); let js_dst = self.dst.join(&format!("sidebar-items{}.js", self.shared.resource_suffix)); - let v = format!("initSidebarItems({});", serde_json::to_string(&items).unwrap()); - scx.fs.write(js_dst, v)?; + let v = format!("window.SIDEBAR_ITEMS = {};", serde_json::to_string(&items).unwrap()); + self.shared.fs.write(js_dst, v)?; } Ok(()) } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index c13ae1e431..3f426ee93e 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -23,7 +23,7 @@ //! These threads are not parallelized (they haven't been a bottleneck yet), and //! both occur before the crate is rendered. -crate mod search_index; +pub(crate) mod search_index; #[cfg(test)] mod tests; @@ -33,8 +33,8 @@ mod print_item; mod span_map; mod write_shared; -crate use self::context::*; -crate use self::span_map::{collect_spans_and_sources, LinkFromSrc}; +pub(crate) use self::context::*; +pub(crate) use self::span_map::{collect_spans_and_sources, LinkFromSrc}; use std::collections::VecDeque; use std::default::Default; @@ -42,6 +42,7 @@ use std::fmt; use std::fs; use std::iter::Peekable; use std::path::PathBuf; +use std::rc::Rc; use std::str; use std::string::ToString; @@ -55,7 +56,7 @@ use rustc_middle::middle::stability; use rustc_middle::ty; use rustc_middle::ty::TyCtxt; use rustc_span::{ - symbol::{kw, sym, Symbol}, + symbol::{sym, Symbol}, BytePos, FileName, RealFileName, }; use serde::ser::SerializeSeq; @@ -81,9 +82,9 @@ use crate::try_none; use crate::DOC_RUST_LANG_ORG_CHANNEL; /// A pair of name and its optional document. -crate type NameDoc = (String, Option); +pub(crate) type NameDoc = (String, Option); -crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { +pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { crate::html::format::display_fn(move |f| { if !v.ends_with('/') && !v.is_empty() { write!(f, "{}/", v) } else { f.write_str(v) } }) @@ -95,27 +96,27 @@ crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { /// Struct representing one entry in the JS search index. These are all emitted /// by hand to a large JS file at the end of cache-creation. #[derive(Debug)] -crate struct IndexItem { - crate ty: ItemType, - crate name: String, - crate path: String, - crate desc: String, - crate parent: Option, - crate parent_idx: Option, - crate search_type: Option, - crate aliases: Box<[Symbol]>, +pub(crate) struct IndexItem { + pub(crate) ty: ItemType, + pub(crate) name: String, + pub(crate) path: String, + pub(crate) desc: String, + pub(crate) parent: Option, + pub(crate) parent_idx: Option, + pub(crate) search_type: Option, + pub(crate) aliases: Box<[Symbol]>, } /// A type used for the search index. #[derive(Debug)] -crate struct RenderType { +pub(crate) struct RenderType { name: Option, generics: Option>, } /// Full type of functions/methods in the search index. #[derive(Debug)] -crate struct IndexItemFunctionType { +pub(crate) struct IndexItemFunctionType { inputs: Vec, output: Vec, } @@ -143,7 +144,7 @@ impl Serialize for IndexItemFunctionType { } #[derive(Debug)] -crate struct TypeWithKind { +pub(crate) struct TypeWithKind { ty: RenderType, kind: ItemType, } @@ -170,13 +171,13 @@ impl Serialize for TypeWithKind { } #[derive(Debug, Clone)] -crate struct StylePath { +pub(crate) struct StylePath { /// The path to the theme - crate path: PathBuf, + pub(crate) path: PathBuf, } impl StylePath { - crate fn basename(&self) -> Result { + pub(crate) fn basename(&self) -> Result { Ok(try_none!(try_none!(self.path.file_stem(), &self.path).to_str(), &self.path).to_string()) } } @@ -203,7 +204,7 @@ impl ItemEntry { } impl ItemEntry { - crate fn print(&self) -> impl fmt::Display + '_ { + pub(crate) fn print(&self) -> impl fmt::Display + '_ { crate::html::format::display_fn(move |f| { write!(f, "{}", self.url, Escape(&self.name)) }) @@ -364,7 +365,7 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String { fn document( w: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, item: &clean::Item, parent: Option<&clean::Item>, heading_offset: HeadingOffset, @@ -383,19 +384,18 @@ fn document( /// Render md_text as markdown. fn render_markdown( w: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, md_text: &str, links: Vec, heading_offset: HeadingOffset, ) { - let mut ids = cx.id_map.borrow_mut(); write!( w, "
{}
", Markdown { content: md_text, links: &links, - ids: &mut ids, + ids: &mut cx.id_map, error_codes: cx.shared.codes, edition: cx.shared.edition(), playground: &cx.shared.playground, @@ -410,7 +410,7 @@ fn render_markdown( fn document_short( w: &mut Buffer, item: &clean::Item, - cx: &Context<'_>, + cx: &mut Context<'_>, link: AssocItemLink<'_>, parent: &clean::Item, show_def_docs: bool, @@ -439,7 +439,7 @@ fn document_short( fn document_full_collapsible( w: &mut Buffer, item: &clean::Item, - cx: &Context<'_>, + cx: &mut Context<'_>, heading_offset: HeadingOffset, ) { document_full_inner(w, item, cx, true, heading_offset); @@ -448,7 +448,7 @@ fn document_full_collapsible( fn document_full( w: &mut Buffer, item: &clean::Item, - cx: &Context<'_>, + cx: &mut Context<'_>, heading_offset: HeadingOffset, ) { document_full_inner(w, item, cx, false, heading_offset); @@ -457,7 +457,7 @@ fn document_full( fn document_full_inner( w: &mut Buffer, item: &clean::Item, - cx: &Context<'_>, + cx: &mut Context<'_>, is_collapsible: bool, heading_offset: HeadingOffset, ) { @@ -493,7 +493,7 @@ fn document_full_inner( /// * Required features (through the `doc_cfg` feature) fn document_item_info( w: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, item: &clean::Item, parent: Option<&clean::Item>, ) { @@ -522,7 +522,7 @@ fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option, + cx: &mut Context<'_>, parent: Option<&clean::Item>, ) -> Vec { let mut extra_info = vec![]; @@ -550,10 +550,9 @@ fn short_item_info( if let Some(note) = note { let note = note.as_str(); - let mut ids = cx.id_map.borrow_mut(); let html = MarkdownHtml( note, - &mut ids, + &mut cx.id_map, error_codes, cx.shared.edition(), &cx.shared.playground, @@ -601,7 +600,7 @@ fn short_item_info( // Render the list of items inside one of the sections "Trait Implementations", // "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages). fn render_impls( - cx: &Context<'_>, + cx: &mut Context<'_>, w: &mut Buffer, impls: &[&&Impl], containing_item: &clean::Item, @@ -840,7 +839,7 @@ fn render_stability_since_raw( let mut stability = String::new(); if let Some(ver) = stable_version { - stability.push_str(&ver.as_str()); + stability.push_str(ver.as_str()); title.push_str(&format!("Stable since Rust version {}", ver)); } @@ -994,7 +993,7 @@ impl<'a> AssocItemLink<'a> { fn render_assoc_items( w: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, containing_item: &clean::Item, it: DefId, what: AssocItemRender<'_>, @@ -1006,14 +1005,15 @@ fn render_assoc_items( fn render_assoc_items_inner( w: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, containing_item: &clean::Item, it: DefId, what: AssocItemRender<'_>, derefs: &mut FxHashSet, ) { info!("Documenting associated items of {:?}", containing_item.name); - let cache = cx.cache(); + let shared = Rc::clone(&cx.shared); + let cache = &shared.cache; let Some(v) = cache.impls.get(&it) else { return }; let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); if !non_trait.is_empty() { @@ -1032,7 +1032,7 @@ fn render_assoc_items_inner( let id = cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx)))); if let Some(def_id) = type_.def_id(cx.cache()) { - cx.deref_id_map.borrow_mut().insert(def_id, id.clone()); + cx.deref_id_map.insert(def_id, id.clone()); } write!( tmp_buf, @@ -1138,7 +1138,7 @@ fn render_assoc_items_inner( fn render_deref_methods( w: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, impl_: &Impl, container_item: &clean::Item, deref_mut: bool, @@ -1285,7 +1285,7 @@ struct ImplRenderingParameters { fn render_impl( w: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, i: &Impl, parent: &clean::Item, link: AssocItemLink<'_>, @@ -1294,7 +1294,8 @@ fn render_impl( aliases: &[String], rendering_params: ImplRenderingParameters, ) { - let cache = cx.cache(); + let shared = Rc::clone(&cx.shared); + let cache = &shared.cache; let traits = &cache.traits; let trait_ = i.trait_did().map(|did| &traits[&did]); let mut close_tags = String::new(); @@ -1307,7 +1308,7 @@ fn render_impl( fn doc_impl_item( boring: &mut Buffer, interesting: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, item: &clean::Item, parent: &clean::Item, containing_item: &clean::Item, @@ -1520,7 +1521,7 @@ fn render_impl( fn render_default_items( boring: &mut Buffer, interesting: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, t: &clean::Trait, i: &clean::Impl, parent: &clean::Item, @@ -1599,14 +1600,20 @@ fn render_impl( } if let Some(ref dox) = i.impl_item.collapsed_doc_value() { - let mut ids = cx.id_map.borrow_mut(); + if trait_.is_none() && i.inner_impl().items.is_empty() { + w.write_str( + "
\ +
This impl block contains no items.
+
", + ); + } write!( w, "
{}
", Markdown { content: &*dox, links: &i.impl_item.links(cx), - ids: &mut ids, + ids: &mut cx.id_map, error_codes: cx.shared.codes, edition: cx.shared.edition(), playground: &cx.shared.playground, @@ -1664,7 +1671,7 @@ fn render_rightside( pub(crate) fn render_impl_summary( w: &mut Buffer, - cx: &Context<'_>, + cx: &mut Context<'_>, i: &Impl, parent: &clean::Item, containing_item: &clean::Item, @@ -1731,8 +1738,6 @@ pub(crate) fn render_impl_summary( } fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) { - let parentlen = cx.current.len() - if it.is_mod() { 1 } else { 0 }; - if it.is_struct() || it.is_trait() || it.is_primitive() @@ -1764,7 +1769,7 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) { write!(buffer, "
  • Version {}
  • ", Escape(version)); } write!(buffer, "
  • All Items
  • "); - buffer.write_str(""); + buffer.write_str(""); } match *it.kind { @@ -1793,21 +1798,6 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) { write!(buffer, "

    In {}

    ", path); } - // Sidebar refers to the enclosing module, not this module. - let relpath = if it.is_mod() && parentlen != 0 { "./" } else { "" }; - write!( - buffer, - "
    \ -
    ", - name = it.name.unwrap_or(kw::Empty), - ty = it.type_(), - path = relpath - ); - write!( - buffer, - "", - relpath, cx.shared.resource_suffix - ); // Closes sidebar-elems div. buffer.write_str(""); } @@ -2092,10 +2082,8 @@ fn sidebar_deref_methods( }) .collect::>(); if !ret.is_empty() { - let map; let id = if let Some(target_def_id) = real_target.def_id(c) { - map = cx.deref_id_map.borrow(); - map.get(&target_def_id).expect("Deref section without derived id") + cx.deref_id_map.get(&target_def_id).expect("Deref section without derived id") } else { "deref-methods" }; @@ -2283,13 +2271,10 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean |sym| format!("{0}", sym, ItemType::Method), ); - let cache = cx.cache(); - if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) { + if let Some(implementors) = cx.cache().implementors.get(&it.item_id.expect_def_id()) { let mut res = implementors .iter() - .filter(|i| { - i.inner_impl().for_.def_id(cache).map_or(false, |d| !cache.paths.contains_key(&d)) - }) + .filter(|i| !i.is_on_local_type(cx)) .filter_map(|i| extract_for_impl_name(&i.impl_item, cx)) .collect::>(); @@ -2299,7 +2284,7 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean buf, "foreign-impls", "Implementations on Foreign Types", - res.iter().map(|(name, id)| format!("{}", id, Escape(&name))), + res.iter().map(|(name, id)| format!("{}", id, Escape(name))), ); } } @@ -2363,8 +2348,7 @@ fn sidebar_enum(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, e: &clean: let mut sidebar = Buffer::new(); let mut variants = e - .variants - .iter() + .variants() .filter_map(|v| { v.name .as_ref() @@ -2538,6 +2522,8 @@ fn item_ty_to_section(ty: ItemType) -> ItemSection { } fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) { + use std::fmt::Write as _; + let mut sidebar = String::new(); let item_sections_in_use: FxHashSet<_> = items @@ -2555,7 +2541,7 @@ fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) { .map(|it| item_ty_to_section(it.type_())) .collect(); for &sec in ItemSection::ALL.iter().filter(|sec| item_sections_in_use.contains(sec)) { - sidebar.push_str(&format!("
  • {}
  • ", sec.id(), sec.name())); + let _ = write!(sidebar, "
  • {}
  • ", sec.id(), sec.name()); } if !sidebar.is_empty() { @@ -2580,7 +2566,7 @@ fn sidebar_foreign_type(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item) { } } -crate const BASIC_KEYWORDS: &str = "rust, rustlang, rust-lang"; +pub(crate) const BASIC_KEYWORDS: &str = "rust, rustlang, rust-lang"; /// Returns a list of all paths used in the type. /// This is used to help deduplicate imported impls @@ -2640,14 +2626,14 @@ const MAX_FULL_EXAMPLES: usize = 5; const NUM_VISIBLE_LINES: usize = 10; /// Generates the HTML for example call locations generated via the --scrape-examples flag. -fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) { +fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item) { let tcx = cx.tcx(); let def_id = item.item_id.expect_def_id(); let key = tcx.def_path_hash(def_id); let Some(call_locations) = cx.shared.call_locations.get(&key) else { return }; // Generate a unique ID so users can link to this section for a given method - let id = cx.id_map.borrow_mut().derive("scraped-examples"); + let id = cx.id_map.derive("scraped-examples"); write!( w, "
    \ @@ -2799,7 +2785,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) { hi - lo }; - let mut locs = call_locations.into_iter().collect::>(); + let mut locs = call_locations.iter().collect::>(); locs.sort_by_key(sort_criterion); locs }; @@ -2843,7 +2829,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) { if it.peek().is_some() { write!(w, r#"`; if (results.query.error !== null) { output += `

    Query parser error: "${results.query.error}".

    `; output += "
    " + @@ -1766,7 +1779,7 @@ window.initSearch = rawSearchIndex => { let i = 0; for (const elem of elems) { const j = i; - elem.onclick = () => { printTab(j); }; + elem.onclick = () => printTab(j); searchState.focusedByTab.push(null); i += 1; } @@ -1818,7 +1831,7 @@ window.initSearch = rawSearchIndex => { } showResults( - execQuery(query, searchWords, filterCrates), + execQuery(query, searchWords, filterCrates, window.currentCrate), params.go_to_first, filterCrates); } @@ -1998,6 +2011,16 @@ window.initSearch = rawSearchIndex => { } function registerSearchEvents() { + const params = searchState.getQueryStringParams(); + + // Populate search bar with query string search term when provided, + // but only if the input bar is empty. This avoid the obnoxious issue + // where you start trying to do a search, and the index loads, and + // suddenly your search is gone! + if (searchState.input.value === "") { + searchState.input.value = params.search || ""; + } + const searchAfter500ms = () => { searchState.clearInputTimeout(); if (searchState.input.value.length === 0) { @@ -2150,20 +2173,32 @@ window.initSearch = rawSearchIndex => { * @type {Array} */ const searchWords = buildIndex(rawSearchIndex); - registerSearchEvents(); - - function runSearchIfNeeded() { + if (typeof window !== "undefined") { + registerSearchEvents(); // If there's a search term in the URL, execute the search now. - if (searchState.getQueryStringParams().search) { + if (window.searchState.getQueryStringParams().search) { search(); } } - runSearchIfNeeded(); -}; + if (typeof exports !== "undefined") { + exports.initSearch = initSearch; + exports.execQuery = execQuery; + exports.parseQuery = parseQuery; + } + return searchWords; +} -if (window.searchIndex !== undefined) { - initSearch(window.searchIndex); +if (typeof window !== "undefined") { + window.initSearch = initSearch; + if (window.searchIndex !== undefined) { + initSearch(window.searchIndex); + } +} else { + // Running in Node, not a browser. Run initSearch just to produce the + // exports. + initSearch({}); } + })(); diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index ad32a19389..41bf0ec895 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -1,11 +1,11 @@ // Local js definitions: /* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme */ -/* global addClass, removeClass, onEach, onEachLazy, NOT_DISPLAYED_ID */ -/* global MAIN_ID, getVar, getSettingsButton, switchDisplayedElement, getNotDisplayedElem */ +/* global addClass, removeClass, onEach, onEachLazy */ +/* global MAIN_ID, getVar, getSettingsButton */ "use strict"; -(function () { +(function() { const isSettingsPage = window.location.pathname.endsWith("/settings.html"); function changeSetting(settingName, value) { @@ -123,19 +123,18 @@ output += ``; }); output += "
    "; } else { // This is a toggle. const checked = setting["default"] === true ? " checked" : ""; - output += ` - -
    ${setting_name}
    `; + output += ``; } output += ""; } @@ -206,38 +205,46 @@ ]; // Then we build the DOM. - const el = document.createElement("section"); + const elementKind = isSettingsPage ? "section" : "div"; + const innerHTML = `
    ${buildSettingsPageSections(settings)}
    `; + const el = document.createElement(elementKind); el.id = "settings"; - let innerHTML = ` -
    -

    - Rustdoc settings -

    - `; - - if (isSettingsPage) { - innerHTML += - "Back"; - } else { - innerHTML += "Back"; - } - innerHTML += ` -
    -
    ${buildSettingsPageSections(settings)}
    `; - el.innerHTML = innerHTML; if (isSettingsPage) { document.getElementById(MAIN_ID).appendChild(el); } else { - getNotDisplayedElem().appendChild(el); + el.setAttribute("tabindex", "-1"); + getSettingsButton().appendChild(el); } return el; } const settingsMenu = buildSettingsPage(); + function displaySettings() { + settingsMenu.style.display = ""; + } + + function elemIsInParent(elem, parent) { + while (elem && elem !== document.body) { + if (elem === parent) { + return true; + } + elem = elem.parentElement; + } + return false; + } + + function blurHandler(event) { + const settingsButton = getSettingsButton(); + if (!elemIsInParent(document.activeElement, settingsButton) && + !elemIsInParent(event.relatedTarget, settingsButton) + ) { + window.hideSettings(); + } + } + if (isSettingsPage) { // We replace the existing "onclick" callback to do nothing if clicked. getSettingsButton().onclick = function(event) { @@ -246,17 +253,27 @@ } else { // We replace the existing "onclick" callback. const settingsButton = getSettingsButton(); + const settingsMenu = document.getElementById("settings"); + window.hideSettings = function() { + settingsMenu.style.display = "none"; + }; settingsButton.onclick = function(event) { + if (elemIsInParent(event.target, settingsMenu)) { + return; + } event.preventDefault(); - if (settingsMenu.parentElement.id === NOT_DISPLAYED_ID) { - switchDisplayedElement(settingsMenu); - } else { + if (settingsMenu.style.display !== "none") { window.hideSettings(); + } else { + displaySettings(); } }; - window.hideSettings = function() { - switchDisplayedElement(null); - }; + settingsButton.onblur = blurHandler; + settingsButton.querySelector("a").onblur = blurHandler; + onEachLazy(settingsMenu.querySelectorAll("input"), el => { + el.onblur = blurHandler; + }); + settingsMenu.onblur = blurHandler; } // We now wait a bit for the web browser to end re-computing the DOM... @@ -264,7 +281,7 @@ setEvents(settingsMenu); // The setting menu is already displayed if we're on the settings page. if (!isSettingsPage) { - switchDisplayedElement(settingsMenu); + displaySettings(); } removeClass(getSettingsButton(), "rotate"); }, 0); diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 15e3bdf47b..290c29d314 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -9,33 +9,19 @@ (function() { -function getCurrentFilePath() { - const parts = window.location.pathname.split("/"); - const rootPathParts = window.rootPath.split("/"); +const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value; - for (const rootPathPart of rootPathParts) { - if (rootPathPart === "..") { - parts.pop(); - } - } - let file = window.location.pathname.substring(parts.join("/").length); - if (file.startsWith("/")) { - file = file.substring(1); - } - return file.substring(0, file.length - 5); -} - -function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { +function createDirEntry(elem, parent, fullPath, hasFoundFile) { const name = document.createElement("div"); name.className = "name"; fullPath += elem["name"] + "/"; - name.onclick = () => { - if (hasClass(this, "expand")) { - removeClass(this, "expand"); + name.onclick = ev => { + if (hasClass(ev.target, "expand")) { + removeClass(ev.target, "expand"); } else { - addClass(this, "expand"); + addClass(ev.target, "expand"); } }; name.innerText = elem["name"]; @@ -46,7 +32,7 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { folders.className = "folders"; if (elem.dirs) { for (const dir of elem.dirs) { - if (createDirEntry(dir, folders, fullPath, currentFile, hasFoundFile)) { + if (createDirEntry(dir, folders, fullPath, hasFoundFile)) { addClass(name, "expand"); hasFoundFile = true; } @@ -60,8 +46,9 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { for (const file_text of elem.files) { const file = document.createElement("a"); file.innerText = file_text; - file.href = window.rootPath + "src/" + fullPath + file_text + ".html"; - if (!hasFoundFile && currentFile === fullPath + file_text) { + file.href = rootPath + "src/" + fullPath + file_text + ".html"; + const w = window.location.href.split("#")[0]; + if (!hasFoundFile && w === file.href) { file.className = "selected"; addClass(name, "expand"); hasFoundFile = true; @@ -72,18 +59,17 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { children.appendChild(files); parent.appendChild(name); parent.appendChild(children); - return hasFoundFile && currentFile.startsWith(fullPath); + return hasFoundFile; } function toggleSidebar() { - const sidebar = document.querySelector("nav.sidebar"); const child = this.children[0]; if (child.innerText === ">") { - sidebar.classList.add("expanded"); + addClass(document.documentElement, "source-sidebar-expanded"); child.innerText = "<"; updateLocalStorage("source-sidebar-show", "true"); } else { - sidebar.classList.remove("expanded"); + removeClass(document.documentElement, "source-sidebar-expanded"); child.innerText = ">"; updateLocalStorage("source-sidebar-show", "false"); } @@ -109,9 +95,6 @@ function createSidebarToggle() { // This function is called from "source-files.js", generated in `html/render/mod.rs`. // eslint-disable-next-line no-unused-vars function createSourceSidebar() { - if (!window.rootPath.endsWith("/")) { - window.rootPath += "/"; - } const container = document.querySelector("nav.sidebar"); const sidebarToggle = createSidebarToggle(); @@ -119,13 +102,7 @@ function createSourceSidebar() { const sidebar = document.createElement("div"); sidebar.id = "source-sidebar"; - if (getCurrentValue("source-sidebar-show") !== "true") { - container.classList.remove("expanded"); - } else { - container.classList.add("expanded"); - } - const currentFile = getCurrentFilePath(); let hasFoundFile = false; const title = document.createElement("div"); @@ -135,7 +112,7 @@ function createSourceSidebar() { Object.keys(sourcesIndex).forEach(key => { sourcesIndex[key].name = key; hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "", - currentFile, hasFoundFile); + hasFoundFile); }); container.appendChild(sidebar); @@ -187,7 +164,7 @@ function highlightSourceLines(match) { } } -const handleSourceHighlight = (function () { +const handleSourceHighlight = (function() { let prev_line_id = 0; const set_fragment = name => { @@ -205,6 +182,10 @@ const handleSourceHighlight = (function () { return ev => { let cur_line_id = parseInt(ev.target.id, 10); + // It can happen when clicking not on a line number span. + if (isNaN(cur_line_id)) { + return; + } ev.preventDefault(); if (ev.shiftKey && prev_line_id) { diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 21de7d77d6..1c4c883448 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -1,10 +1,15 @@ +// storage.js is loaded in the `` of all rustdoc pages and doesn't +// use `async` or `defer`. That means it blocks further parsing and rendering +// of the page: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script. +// This makes it the correct place to act on settings that affect the display of +// the page, so we don't see major layout changes during the load of the page. "use strict"; const darkThemes = ["dark", "ayu"]; window.currentTheme = document.getElementById("themeStyle"); window.mainTheme = document.getElementById("mainThemeStyle"); -const settingsDataset = (function () { +const settingsDataset = (function() { const settingsElement = document.getElementById("default-settings"); if (settingsElement === null) { return null; @@ -100,15 +105,10 @@ function onEachLazy(lazyArray, func, reversed) { reversed); } -// eslint-disable-next-line no-unused-vars -function hasOwnPropertyRustdoc(obj, property) { - return Object.prototype.hasOwnProperty.call(obj, property); -} - function updateLocalStorage(name, value) { try { window.localStorage.setItem("rustdoc-" + name, value); - } catch(e) { + } catch (e) { // localStorage is not accessible, do nothing } } @@ -116,7 +116,7 @@ function updateLocalStorage(name, value) { function getCurrentValue(name) { try { return window.localStorage.getItem("rustdoc-" + name); - } catch(e) { + } catch (e) { return null; } } @@ -168,7 +168,7 @@ function useSystemTheme(value) { } } -const updateSystemTheme = (function () { +const updateSystemTheme = (function() { if (!window.matchMedia) { // fallback to the CSS computed value return () => { @@ -241,6 +241,12 @@ if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) { switchToSavedTheme(); } +if (getSettingValue("source-sidebar-show") === "true") { + // At this point in page load, `document.body` is not available yet. + // Set a class on the `` element instead. + addClass(document.documentElement, "source-sidebar-expanded"); +} + // If we navigate away (for example to a settings page), and then use the back or // forward button to get back to a page, the theme may have changed in the meantime. // But scripts may not be re-loaded in such a case due to the bfcache diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index bec5c083fe..75f2b7e357 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -8,134 +8,134 @@ //! directly written to a `Write` handle. /// The file contents of the main `rustdoc.css` file, responsible for the core layout of the page. -crate static RUSTDOC_CSS: &str = include_str!("static/css/rustdoc.css"); +pub(crate) static RUSTDOC_CSS: &str = include_str!("static/css/rustdoc.css"); /// The file contents of `settings.css`, responsible for the items on the settings page. -crate static SETTINGS_CSS: &str = include_str!("static/css/settings.css"); +pub(crate) static SETTINGS_CSS: &str = include_str!("static/css/settings.css"); /// The file contents of the `noscript.css` file, used in case JS isn't supported or is disabled. -crate static NOSCRIPT_CSS: &str = include_str!("static/css/noscript.css"); +pub(crate) static NOSCRIPT_CSS: &str = include_str!("static/css/noscript.css"); /// The file contents of `normalize.css`, included to even out standard elements between browser /// implementations. -crate static NORMALIZE_CSS: &str = include_str!("static/css/normalize.css"); +pub(crate) static NORMALIZE_CSS: &str = include_str!("static/css/normalize.css"); /// The file contents of `main.js`, which contains the core JavaScript used on documentation pages, /// including search behavior and docblock folding, among others. -crate static MAIN_JS: &str = include_str!("static/js/main.js"); +pub(crate) static MAIN_JS: &str = include_str!("static/js/main.js"); /// The file contents of `search.js`, which contains the search behavior. -crate static SEARCH_JS: &str = include_str!("static/js/search.js"); +pub(crate) static SEARCH_JS: &str = include_str!("static/js/search.js"); /// The file contents of `settings.js`, which contains the JavaScript used to handle the settings /// page. -crate static SETTINGS_JS: &str = include_str!("static/js/settings.js"); +pub(crate) static SETTINGS_JS: &str = include_str!("static/js/settings.js"); /// The file contents of `storage.js`, which contains functionality related to browser Local /// Storage, used to store documentation settings. -crate static STORAGE_JS: &str = include_str!("static/js/storage.js"); +pub(crate) static STORAGE_JS: &str = include_str!("static/js/storage.js"); /// The file contents of `scraped-examples.js`, which contains functionality related to the /// --scrape-examples flag that inserts automatically-found examples of usages of items. -crate static SCRAPE_EXAMPLES_JS: &str = include_str!("static/js/scrape-examples.js"); +pub(crate) static SCRAPE_EXAMPLES_JS: &str = include_str!("static/js/scrape-examples.js"); -crate static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/scrape-examples-help.md"); - -/// The file contents of `brush.svg`, the icon used for the theme-switch button. -crate static BRUSH_SVG: &[u8] = include_bytes!("static/images/brush.svg"); +pub(crate) static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/scrape-examples-help.md"); /// The file contents of `wheel.svg`, the icon used for the settings button. -crate static WHEEL_SVG: &[u8] = include_bytes!("static/images/wheel.svg"); +pub(crate) static WHEEL_SVG: &[u8] = include_bytes!("static/images/wheel.svg"); /// The file contents of `clipboard.svg`, the icon used for the "copy path" button. -crate static CLIPBOARD_SVG: &[u8] = include_bytes!("static/images/clipboard.svg"); +pub(crate) static CLIPBOARD_SVG: &[u8] = include_bytes!("static/images/clipboard.svg"); /// The file contents of `down-arrow.svg`, the icon used for the crate choice combobox. -crate static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/images/down-arrow.svg"); +pub(crate) static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/images/down-arrow.svg"); /// The file contents of `toggle-minus.svg`, the icon used for opened toggles. -crate static TOGGLE_MINUS_PNG: &[u8] = include_bytes!("static/images/toggle-minus.svg"); +pub(crate) static TOGGLE_MINUS_PNG: &[u8] = include_bytes!("static/images/toggle-minus.svg"); /// The file contents of `toggle-plus.svg`, the icon used for closed toggles. -crate static TOGGLE_PLUS_PNG: &[u8] = include_bytes!("static/images/toggle-plus.svg"); +pub(crate) static TOGGLE_PLUS_PNG: &[u8] = include_bytes!("static/images/toggle-plus.svg"); /// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation /// output. -crate static COPYRIGHT: &[u8] = include_bytes!("static/COPYRIGHT.txt"); +pub(crate) static COPYRIGHT: &[u8] = include_bytes!("static/COPYRIGHT.txt"); /// The contents of `LICENSE-APACHE.txt`, the text of the Apache License, version 2.0. -crate static LICENSE_APACHE: &[u8] = include_bytes!("static/LICENSE-APACHE.txt"); +pub(crate) static LICENSE_APACHE: &[u8] = include_bytes!("static/LICENSE-APACHE.txt"); /// The contents of `LICENSE-MIT.txt`, the text of the MIT License. -crate static LICENSE_MIT: &[u8] = include_bytes!("static/LICENSE-MIT.txt"); +pub(crate) static LICENSE_MIT: &[u8] = include_bytes!("static/LICENSE-MIT.txt"); /// The contents of `rust-logo.svg`, the default icon of the documentation. -crate static RUST_LOGO_SVG: &[u8] = include_bytes!("static/images/rust-logo.svg"); +pub(crate) static RUST_LOGO_SVG: &[u8] = include_bytes!("static/images/rust-logo.svg"); /// The default documentation favicons (SVG and PNG fallbacks) -crate static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/images/favicon.svg"); -crate static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-16x16.png"); -crate static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png"); +pub(crate) static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/images/favicon.svg"); +pub(crate) static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-16x16.png"); +pub(crate) static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png"); /// The built-in themes given to every documentation site. -crate mod themes { +pub(crate) mod themes { /// The "light" theme, selected by default when no setting is available. Used as the basis for /// the `--check-theme` functionality. - crate static LIGHT: &str = include_str!("static/css/themes/light.css"); + pub(crate) static LIGHT: &str = include_str!("static/css/themes/light.css"); /// The "dark" theme. - crate static DARK: &str = include_str!("static/css/themes/dark.css"); + pub(crate) static DARK: &str = include_str!("static/css/themes/dark.css"); /// The "ayu" theme. - crate static AYU: &str = include_str!("static/css/themes/ayu.css"); + pub(crate) static AYU: &str = include_str!("static/css/themes/ayu.css"); } /// Files related to the Fira Sans font. -crate mod fira_sans { +pub(crate) mod fira_sans { /// The file `FiraSans-Regular.woff2`, the Regular variant of the Fira Sans font in woff2. - crate static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2"); + pub(crate) static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2"); /// The file `FiraSans-Medium.woff2`, the Medium variant of the Fira Sans font in woff2. - crate static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2"); + pub(crate) static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2"); /// The file `FiraSans-LICENSE.txt`, the license text for the Fira Sans font. - crate static LICENSE: &[u8] = include_bytes!("static/fonts/FiraSans-LICENSE.txt"); + pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/FiraSans-LICENSE.txt"); } /// Files related to the Source Serif 4 font. -crate mod source_serif_4 { +pub(crate) mod source_serif_4 { /// The file `SourceSerif4-Regular.ttf.woff2`, the Regular variant of the Source Serif 4 font in /// woff2. - crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2"); + pub(crate) static REGULAR: &[u8] = + include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2"); /// The file `SourceSerif4-Bold.ttf.woff2`, the Bold variant of the Source Serif 4 font in /// woff2. - crate static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2"); + pub(crate) static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2"); /// The file `SourceSerif4-It.ttf.woff2`, the Italic variant of the Source Serif 4 font in /// woff2. - crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2"); + pub(crate) static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2"); /// The file `SourceSerif4-LICENSE.txt`, the license text for the Source Serif 4 font. - crate static LICENSE: &[u8] = include_bytes!("static/fonts/SourceSerif4-LICENSE.md"); + pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/SourceSerif4-LICENSE.md"); } /// Files related to the Source Code Pro font. -crate mod source_code_pro { +pub(crate) mod source_code_pro { /// The file `SourceCodePro-Regular.ttf.woff2`, the Regular variant of the Source Code Pro font /// in woff2. - crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2"); + pub(crate) static REGULAR: &[u8] = + include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2"); /// The file `SourceCodePro-Semibold.ttf.woff2`, the Semibold variant of the Source Code Pro /// font in woff2. - crate static SEMIBOLD: &[u8] = include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2"); + pub(crate) static SEMIBOLD: &[u8] = + include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2"); /// The file `SourceCodePro-It.ttf.woff2`, the Italic variant of the Source Code Pro font in /// woff2. - crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2"); + pub(crate) static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2"); /// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font. - crate static LICENSE: &[u8] = include_bytes!("static/fonts/SourceCodePro-LICENSE.txt"); + pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/SourceCodePro-LICENSE.txt"); } /// Files related to the Nanum Barun Gothic font. @@ -153,16 +153,16 @@ crate mod source_code_pro { /// --unicodes=U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \ /// --output-file=NanumBarunGothic.ttf.woff2 --flavor=woff2 /// ``` -crate mod nanum_barun_gothic { +pub(crate) mod nanum_barun_gothic { /// The file `NanumBarunGothic.ttf.woff2`, the Regular variant of the Nanum Barun Gothic font. - crate static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2"); + pub(crate) static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2"); /// The file `NanumBarunGothic-LICENSE.txt`, the license text of the Nanum Barun Gothic font. - crate static LICENSE: &[u8] = include_bytes!("static/fonts/NanumBarunGothic-LICENSE.txt"); + pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/NanumBarunGothic-LICENSE.txt"); } /// Files related to the sidebar in rustdoc sources. -crate mod sidebar { +pub(crate) mod sidebar { /// File script to handle sidebar. - crate static SOURCE_SCRIPT: &str = include_str!("static/js/source-script.js"); + pub(crate) static SOURCE_SCRIPT: &str = include_str!("static/js/source-script.js"); } diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 470cce93a5..c4999e2c74 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -34,17 +34,18 @@ {%- endfor -%} > {#- -#} {#- -#} - {#- -#} + {%- if page.css_class.contains("crate") -%} + {#- -#} + {%- else if page.css_class == "source" -%} + {#- -#} + {#- -#} + {%- else -%} + {#- -#} + {%- endif -%} {#- -#} - {%- for script in page.static_extra_scripts -%} - {#- -#} - {% endfor %} {%- if layout.scrape_examples_extension -%} {#- -#} {%- endif -%} - {%- for script in page.extra_scripts -%} - {#- -#} - {% endfor %}